{"model_name":"gemini-2.5-flash-lite-thinking","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\n// Use long long for area and large coordinates if needed.\n// For this problem, coordinates are up to 10000, area up to 10^8.\n// int is fine for coordinates. long long for area.\nusing ll = long long;\n\n// Represents an axis-aligned rectangle. Coordinates are [x1, x2) x [y1, y2).\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const { return (ll)(x2 - x1) * (y2 - y1); }\n    int width() const { return x2 - x1; }\n    int height() const { return y2 - y1; }\n};\n\n// Represents a company with its desired location and area.\nstruct Company {\n    int id;\n    int x, y; // Desired point is (x+0.5, y+0.5)\n    ll r;     // Desired area\n};\n\n// Global random number generators for reproducibility and better distribution.\n// Seeded with current time for different runs.\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> dist_01(0.0, 1.0);\n\n// Function to calculate satisfaction for a single company.\n// p_i = 1 - (1 - min(r_i, s_i) / max(r_i, s_i))^2\ndouble calculate_satisfaction(ll r_i, ll s_i) {\n    if (s_i == 0) return 0.0; // Should not happen with positive area constraint\n    double ratio = (double)min(r_i, s_i) / max(r_i, s_i);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Function to find all divisors of a number n.\n// Returns divisors in ascending order.\nvector<ll> get_divisors(ll n) {\n    vector<ll> divisors;\n    for (ll i = 1; i * i <= n; ++i) {\n        if (n % i == 0) {\n            divisors.push_back(i);\n            if (i * i != n) {\n                divisors.push_back(n / i);\n            }\n        }\n    }\n    sort(divisors.begin(), divisors.end());\n    return divisors;\n}\n\n// Structure to hold the result of one complete assignment attempt (one iteration).\nstruct AssignmentResult {\n    // Stores (a, b, c, d) for each company's assigned rectangle.\n    vector<tuple<int, int, int, int>> assignments; \n    // Total satisfaction achieved in this assignment.\n    double total_satisfaction = -1.0; // Initialize to a value lower than any possible satisfaction (0.0).\n};\n\nint N; // Number of companies\nvector<Company> companies_data; // Stores input data for each company.\nvector<Rect> initial_available_regions; // The initial bounding box for space partitioning.\n\n// Number of random trials to perform. This is a key parameter for randomized algorithms.\n// More iterations generally lead to better results but take more time.\nconst int NUM_ITERATIONS = 200; \n\n// The main solver function implementing a randomized recursive partitioning strategy.\nAssignmentResult solve() {\n    AssignmentResult overall_best_result;\n    overall_best_result.assignments.resize(N); // Pre-size for N companies.\n\n    // Indices of companies, used for shuffling and tracking.\n    vector<int> company_indices(N);\n    iota(company_indices.begin(), company_indices.end(), 0); // Fill with 0, 1, ..., N-1.\n\n    // Perform multiple independent trials to explore different random choices.\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<Rect> available_regions = initial_available_regions; // Start with the full 10000x10000 area.\n        vector<int> current_unassigned_companies = company_indices; // Companies yet to be assigned in this iteration.\n        vector<tuple<int, int, int, int>> current_assignments(N); // Stores assignments for this iteration.\n        double current_total_satisfaction = 0.0;\n        bool iteration_failed = false; // Flag to mark if this iteration produced an invalid state.\n\n        // Shuffle companies to process them in a random order for this iteration.\n        shuffle(current_unassigned_companies.begin(), current_unassigned_companies.end(), rng);\n\n        // Assign companies one by one until all are assigned.\n        while (!current_unassigned_companies.empty()) {\n            // Pick the next company to assign. It's the last one in the shuffled list.\n            int company_idx = current_unassigned_companies.back();\n            current_unassigned_companies.pop_back();\n            \n            const Company& company = companies_data[company_idx];\n            ll r_i = company.r;\n\n            // Pick an available region to place this company's ad.\n            // Heuristic: Randomly choose an available region. Other heuristics could be min area, etc.\n            if (available_regions.empty()) {\n                 // This scenario implies an issue: unassigned companies but no space left.\n                 // It suggests the partitioning logic or previous choices were flawed.\n                 iteration_failed = true; \n                 break; // Abandon this iteration.\n            }\n            \n            uniform_int_distribution<int> region_dist(0, available_regions.size() - 1);\n            int region_to_use_idx = region_dist(rng);\n            Rect region = available_regions[region_to_use_idx];\n\n            // Find all possible integer (width, height) pairs that form the desired area r_i\n            // and fit within the chosen region.\n            vector<pair<int, int>> valid_dims;\n            vector<ll> r_i_divisors = get_divisors(r_i); // Get divisors of desired area.\n\n            // Check each divisor 'w' to see if corresponding 'h' fits.\n            for (ll w_ll : r_i_divisors) {\n                int w = static_cast<int>(w_ll); // Cast is safe as w is limited by region.width() <= 10000.\n                if (w > 0 && w <= region.width()) {\n                    ll h_ll = r_i / w;\n                    if (h_ll > 0 && h_ll <= region.height()) {\n                        // If both width and height fit, this is a valid dimension pair.\n                        valid_dims.push_back({w, static_cast<int>(h_ll)}); // Cast is safe as h is limited by region.height() <= 10000.\n                    }\n                }\n            }\n\n            if (valid_dims.empty()) {\n                // If no valid (w, h) pair can form area r_i and fit in the region,\n                // this indicates that the chosen region is too small or has incompatible dimensions for r_i.\n                // Since sum of r_i equals total area, an exact fit should ideally be possible with proper partitioning.\n                // This means the current random choices led to an unresolvable state for this iteration.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose dimensions (w, h) from the list of valid options.\n            // Heuristic: Pick a random pair from valid_dims to explore different shapes.\n            uniform_int_distribution<int> dims_dist(0, valid_dims.size() - 1);\n            pair<int, int> dim = valid_dims[dims_dist(rng)];\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Determine the valid range for the top-left corner (a, b) of the rectangle.\n            // The rectangle [a, a+w) x [b, b+h) must cover the point (company.x+0.5, company.y+0.5).\n            // This means: a <= company.x < a+w AND b <= company.y < b+h.\n            // With integer coordinates, this translates to:\n            // a <= company.x AND a+w >= company.x + 1  => a >= company.x + 1 - w\n            // b <= company.y AND b+h >= company.y + 1  => b >= company.y + 1 - h\n            // Additionally, the rectangle must be within the selected region:\n            // region.x1 <= a AND a+w <= region.x2  => a <= region.x2 - w\n            // region.y1 <= b AND b+h <= region.y2  => b <= region.y2 - h\n            \n            // Combining these constraints to find the valid range for 'a' and 'b'.\n            int min_a = max(region.x1, company.x + 1 - w);\n            int max_a = min(region.x2 - w, company.x);\n            int min_b = max(region.y1, company.y + 1 - h);\n            int max_b = min(region.y2 - h, company.y);\n\n            if (min_a > max_a || min_b > max_b) {\n                // If the valid ranges are empty, it means no position 'a' or 'b' exists\n                // to satisfy all conditions simultaneously. This should ideally not happen\n                // if previous steps (finding valid_dims) were correct and the point is indeed within the region.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose the placement (a, b).\n            // Heuristic: Push the rectangle to the top-left corner (min_a, min_b) of its valid placement range.\n            // This aims to leave larger contiguous areas in the remaining space, potentially aiding future assignments.\n            int a = min_a;\n            int b = min_b;\n            \n            // Assign the rectangle [a, a+w) x [b, b+h) to the company.\n            current_assignments[company_idx] = {a, b, a + w, b + h};\n            ll s_i = (ll)w * h; // Actual area assigned.\n            // Accumulate satisfaction for this company.\n            current_total_satisfaction += calculate_satisfaction(r_i, s_i);\n\n            // Update the list of available regions.\n            // Remove the region that was just used.\n            available_regions.erase(available_regions.begin() + region_to_use_idx);\n\n            // Add the new regions created by partitioning the used region R with the assigned rectangle R_idx.\n            Rect assigned_rect = {a, b, a + w, b + h};\n            \n            // Add region to the left of the assigned rectangle, if it has positive width.\n            if (region.x1 < assigned_rect.x1) {\n                available_regions.push_back({region.x1, region.y1, assigned_rect.x1, region.y2});\n            }\n            // Add region to the right, if it has positive width.\n            if (assigned_rect.x2 < region.x2) {\n                available_regions.push_back({assigned_rect.x2, region.y1, region.x2, region.y2});\n            }\n            // Add region below the assigned rectangle, if it has positive height.\n            if (region.y1 < assigned_rect.y1) {\n                available_regions.push_back({assigned_rect.x1, region.y1, assigned_rect.x2, assigned_rect.y1});\n            }\n            // Add region above the assigned rectangle, if it has positive height.\n            if (assigned_rect.y2 < region.y2) {\n                available_regions.push_back({assigned_rect.x1, assigned_rect.y2, assigned_rect.x2, region.y2});\n            }\n        } // End of while loop: assigning companies within one iteration.\n\n        // After assigning all companies for this iteration, check if it was successful and if it's better than the overall best found so far.\n        if (!iteration_failed && current_total_satisfaction > overall_best_result.total_satisfaction) {\n            overall_best_result.total_satisfaction = current_total_satisfaction;\n            overall_best_result.assignments = current_assignments;\n        }\n    } // End of loop: performing multiple iterations.\n\n    // The problem implies a valid solution is always achievable. If overall_best_result.total_satisfaction is still -1.0,\n    // it means all iterations failed, indicating a potential issue with the algorithm or heuristics.\n    // However, with enough iterations and a reasonable algorithm, at least one should yield a valid assignment.\n\n    return overall_best_result;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n    companies_data.resize(N);\n    ll total_r_sum = 0; // For verification, though problem guarantees sum r_i = 10^8.\n    for (int i = 0; i < N; ++i) {\n        companies_data[i].id = i;\n        cin >> companies_data[i].x >> companies_data[i].y >> companies_data[i].r;\n        total_r_sum += companies_data[i].r;\n    }\n\n    // The problem statement guarantees that the sum of desired areas equals the total area of the 10000x10000 space.\n    // This is a strong hint that an optimal solution involves no wasted space (sum of assigned areas = total area).\n\n    // Initialize the initial available region: the entire 10000x10000 canvas.\n    initial_available_regions.push_back({0, 0, 10000, 10000});\n\n    // Run the solver to get the best assignment found.\n    AssignmentResult final_assignment = solve();\n\n    // Output the resulting rectangle coordinates for each company.\n    for (int i = 0; i < N; ++i) {\n        cout << get<0>(final_assignment.assignments[i]) << \" \"\n             << get<1>(final_assignment.assignments[i]) << \" \"\n             << get<2>(final_assignment.assignments[i]) << \" \"\n             << get<3>(final_assignment.assignments[i]) << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <vector> // Included for general utility, though not strictly used by the final greedy logic\n#include <algorithm> // Included for general utility, e.g., std::fill could be used for initialization\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 50;\n\n// Global arrays for grid data and visited status.\n// Static allocation is used as the grid size is fixed and memory limits are generous.\nint grid[N][N]; // Stores the score p_ij for each square (0 <= p_ij <= 99)\nint tile_map[N][N]; // Stores the tile ID t_ij for each square (0 <= t_ij <= M-1)\nint max_tile_id_plus_1 = 0; // Tracks the total number of unique tiles (M). M is max_tile_id + 1.\n\nbool visited_squares[N][N]; // Boolean matrix to ensure path simplicity (no revisiting squares).\n// The maximum possible tile ID is N*N - 1 (e.g., if all tiles are 1x1 and N*N distinct tiles exist).\n// Thus, an array of size N*N is sufficient to cover all possible tile IDs from 0 to N*N-1.\nbool used_tiles[N * N]; \n\n// Movement directions: Up, Down, Left, Right.\n// These arrays define the change in row (dr) and column (dc) for each of the four cardinal directions.\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\n// Corresponding characters for outputting the path. 'U' for Up, 'D' for Down, 'L' for Left, 'R' for Right.\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize C++ standard streams for faster input/output operations, crucial in competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial position (si, sj) from standard input.\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read the grid scores p_ij for all 50x50 squares.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Read the tile map t_ij for all squares and determine the total number of unique tiles (M).\n    // The problem states that tile IDs range from 0 to M-1, so M is `max_tile_id + 1`.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile_map[i][j];\n            // Update `max_tile_id_plus_1` if a tile ID implies a larger total number of tiles.\n            if (tile_map[i][j] + 1 > max_tile_id_plus_1) {\n                max_tile_id_plus_1 = tile_map[i][j] + 1;\n            }\n        }\n    }\n\n    // Initialize `visited_squares` matrix. Initially, no squares have been visited.\n    // A simple nested loop is efficient for initializing fixed-size arrays.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_squares[i][j] = false;\n        }\n    }\n    \n    // Initialize `used_tiles` array. Initially, no tiles are considered used.\n    // We only need to initialize entries corresponding to actual tile IDs, from 0 up to M-1.\n    for(int i = 0; i < max_tile_id_plus_1; ++i) {\n        used_tiles[i] = false;\n    }\n\n    string path_string = \"\"; // This string will store the sequence of moves (e.g., \"UDLRU\").\n    int current_r = si;    // Initialize current row position to the starting row.\n    int current_c = sj;    // Initialize current column position to the starting column.\n\n    // Mark the starting square as visited and its corresponding tile as used.\n    // This is because Takahashi starts on this square, and it counts as being stepped on.\n    visited_squares[current_r][current_c] = true;\n    // The tile ID at the starting position is guaranteed to be a valid index into `used_tiles`.\n    used_tiles[tile_map[current_r][current_c]] = true;\n\n    // Main loop for constructing the path using a greedy strategy.\n    // The loop continues as long as there are valid moves to make.\n    while (true) {\n        int best_neighbor_score = -1; // Stores the score of the best valid neighbor found. Initialized to -1 to ensure any non-negative score is considered better.\n        int best_dr = -1, best_dc = -1; // Stores the row and column delta for the best move.\n        char best_move_char = ' ';      // Stores the character representation ('U', 'D', 'L', 'R') of the best move.\n\n        // Explore all 4 possible adjacent squares from the current position.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current_r + dr[i]; // Calculate the row of the neighboring square.\n            int nc = current_c + dc[i]; // Calculate the column of the neighboring square.\n\n            // Constraint 1: Boundary Check.\n            // Ensure the neighboring square is within the 50x50 grid limits.\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n                continue; // Skip this neighbor if it's out of bounds.\n            }\n\n            // Constraint 2: Path Simplicity Check.\n            // Ensure the neighboring square has not been visited before in the current path.\n            if (visited_squares[nr][nc]) {\n                continue; // Skip if the square is already visited.\n            }\n\n            // Constraint 3: Tile Usage Check.\n            // Ensure the tile covering this neighboring square has not been used yet.\n            // `tile_map[nr][nc]` is a valid index because `max_tile_id_plus_1` was determined from all tile IDs present in the input.\n            if (used_tiles[tile_map[nr][nc]]) {\n                continue; // Skip if the tile is already used.\n            }\n\n            // If the move to (nr, nc) is valid according to all constraints:\n            // Apply the greedy heuristic: Select the valid neighbor that offers the highest score (`grid[nr][nc]`).\n            if (grid[nr][nc] > best_neighbor_score) {\n                best_neighbor_score = grid[nr][nc]; // Update the highest score found so far.\n                best_dr = dr[i];                    // Record the direction of this best move.\n                best_dc = dc[i];\n                best_move_char = move_char[i];      // Record the character for this best move.\n            }\n        } // End of loop exploring neighbors.\n\n        // If `best_neighbor_score` remained -1, it means no valid moves were found from the current position.\n        // This signifies the end of the path.\n        if (best_neighbor_score == -1) {\n            break; // Exit the path construction loop.\n        }\n\n        // Execute the best move identified:\n        // Update the current position to the coordinates of the chosen neighbor.\n        current_r += best_dr;\n        current_c += best_dc;\n        // Mark the newly entered square as visited to maintain path simplicity.\n        visited_squares[current_r][current_c] = true; \n        // Mark the tile covering this new square as used, enforcing the tile constraint.\n        used_tiles[tile_map[current_r][current_c]] = true; \n        // Append the character representing this move to the output path string.\n        path_string += best_move_char; \n    }\n\n    // Output the generated path string to standard output.\n    cout << path_string << endl;\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cmath>\n#include <iomanip>\n#include <limits>\n#include <algorithm> // For std::reverse\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 30;\n// Represents infinity for distances\nconst double INF = numeric_limits<double>::infinity();\n\n// --- Edge Weights ---\n// h_weights[i][j] stores the weight of the horizontal edge between (i, j) and (i, j+1).\n// i: row index (0 to 29), j: column index (0 to 28).\ndouble h_weights[N][N - 1];\n// v_weights[i][j] stores the weight of the vertical edge between (i, j) and (i+1, j).\n// i: row index (0 to 28), j: column index (0 to 29).\ndouble v_weights[N - 1][N];\n\n// --- Dijkstra's Algorithm Data Structures ---\n// Stores the predecessor vertex for path reconstruction. pred[r][c] = {pr, pc}\npair<int, int> pred[N][N];\n// Stores the shortest estimated distance from the start node to (r, c).\ndouble dist[N][N];\n\n// --- Helper Functions ---\n\n// Gets the weight of the edge between two adjacent vertices (r1, c1) and (r2, c2).\n// Assumes (r1, c1) and (r2, c2) are indeed adjacent.\ndouble get_weight(int r1, int c1, int r2, int c2) {\n    if (r1 == r2) { // Horizontal edge: same row, different columns\n        // Ensure c_min is the smaller column index for array access\n        int c_min = min(c1, c2);\n        return h_weights[r1][c_min];\n    } else { // Vertical edge: same column, different rows\n        // Ensure r_min is the smaller row index for array access\n        int r_min = min(r1, r2);\n        return v_weights[r_min][c1]; // c1 == c2 for vertical edges\n    }\n}\n\n// Updates the weight of the edge between (r1, c1) and (r2, c2) by adding 'delta'.\n// Ensures the weight does not drop below 1.0.\nvoid update_weight(int r1, int c1, int r2, int c2, double delta) {\n    if (r1 == r2) { // Horizontal edge\n        int c_min = min(c1, c2);\n        h_weights[r1][c_min] = max(1.0, h_weights[r1][c_min] + delta);\n    } else { // Vertical edge\n        int r_min = min(r1, r2);\n        v_weights[r_min][c1] = max(1.0, v_weights[r_min][c1] + delta);\n    }\n}\n\n// Dijkstra's algorithm to find the shortest path from start_node to end_node\n// using the current estimated edge weights.\nvoid dijkstra(pair<int, int> start_node, pair<int, int> end_node) {\n    // Initialize distances to infinity and predecessors to an invalid state.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dist[i][j] = INF;\n            pred[i][j] = {-1, -1}; // Sentinel value indicating no predecessor\n        }\n    }\n\n    // Distance to the start node is 0.\n    dist[start_node.first][start_node.second] = 0;\n\n    // Priority queue stores {negative_distance, {row, col}}.\n    // Using negative distance simulates a min-priority queue with std::priority_queue.\n    priority_queue<pair<double, pair<int, int>>> pq;\n    pq.push({0.0, start_node});\n\n    // Possible moves: Up, Down, Left, Right.\n    int dr[] = {-1, 1, 0, 0}; \n    int dc[] = {0, 0, -1, 1};\n\n    while (!pq.empty()) {\n        // Get the node with the smallest distance from the priority queue.\n        auto [d, curr_node] = pq.top();\n        pq.pop();\n        d = -d; // Convert negative distance back to positive.\n\n        int r = curr_node.first;\n        int c = curr_node.second;\n\n        // If the extracted distance is greater than the known shortest distance, skip.\n        if (d > dist[r][c]) {\n            continue;\n        }\n        \n        // If we have reached the destination, we can break.\n        // Since edge weights are positive, this path is guaranteed to be the shortest.\n        if (curr_node == end_node) {\n            break; \n        }\n\n        // Explore neighbors.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid boundaries.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = get_weight(r, c, nr, nc);\n                // If a shorter path to the neighbor is found, update distance and predecessor.\n                if (dist[r][c] + weight < dist[nr][nc]) {\n                    dist[nr][nc] = dist[r][c] + weight;\n                    pred[nr][nc] = {r, c}; // Set current node as predecessor for neighbor.\n                    pq.push({-dist[nr][nc], {nr, nc}}); // Add neighbor to priority queue.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // --- Initialization ---\n    // Initialize all edge weights to a starting guess.\n    // Edge generation values are typically in the range [1000, 9000].\n    // 5000.0 is a reasonable midpoint.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) { // Horizontal edges\n            h_weights[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) { // Vertical edges\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = 5000.0;\n        }\n    }\n\n    // --- Learning Rate Configuration ---\n    // initial_lr determines the magnitude of weight updates.\n    // It decays over time using 1/k.\n    double initial_lr = 1.0; \n\n    // --- Process Queries ---\n    for (int k = 1; k <= 1000; ++k) {\n        // Read start and end nodes for the current query.\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        pair<int, int> start_node = {si, sj};\n        pair<int, int> end_node = {ti, tj};\n\n        // Find the shortest path using Dijkstra with current estimated weights.\n        dijkstra(start_node, end_node);\n\n        // --- Path Reconstruction and Output ---\n        string path_str = \"\";\n        double estimated_path_length = 0.0;\n        vector<pair<int, int>> path_vertices; // Stores the sequence of vertices in the path.\n\n        // Trace back from the end_node to the start_node using predecessor pointers.\n        pair<int, int> curr = end_node;\n        while (!(curr.first == -1 && curr.second == -1)) { // Stop if predecessor is invalid (-1,-1)\n            path_vertices.push_back(curr);\n            if (curr == start_node) break; // Reached the start node\n            curr = pred[curr.first][curr.second];\n        }\n        // The path_vertices are collected in reverse order (end to start). Reverse them.\n        reverse(path_vertices.begin(), path_vertices.end());\n        \n        // If start and end nodes are different, generate the path string and calculate estimated length.\n        if (path_vertices.size() > 1) { \n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i]; // Current vertex\n                pair<int, int> v = path_vertices[i+1]; // Next vertex\n\n                // Add the weight of the edge (u, v) to the estimated path length.\n                estimated_path_length += get_weight(u.first, u.second, v.first, v.second);\n\n                // Determine the move direction and append to the path string.\n                if (u.first < v.first) path_str += 'D'; // Moved Down (row index increased)\n                else if (u.first > v.first) path_str += 'U'; // Moved Up (row index decreased)\n                else if (u.second < v.second) path_str += 'R'; // Moved Right (column index increased)\n                else if (u.second > v.second) path_str += 'L'; // Moved Left (column index decreased)\n            }\n        }\n        \n        // Output the generated path string.\n        cout << path_str << endl;\n        // Flush the output buffer. This is crucial for the judge to receive the output promptly.\n        cout << flush;\n\n        // --- Feedback and Weight Update ---\n        // Read the feedback integer from the judge. This is a noisy measurement of the path's actual length.\n        long long feedback_k_ll; \n        cin >> feedback_k_ll;\n        double feedback_k = static_cast<double>(feedback_k_ll);\n\n        // Calculate the number of edges in the found path.\n        int num_edges = path_vertices.size() - 1;\n        \n        // Only update weights if the path consists of at least one edge (start != end).\n        if (num_edges > 0) { \n            // Calculate the error: difference between observed feedback and estimated length.\n            double error = feedback_k - estimated_path_length;\n            \n            // Calculate the learning rate, which decays with the query number k.\n            double learning_rate = initial_lr / k; \n            \n            // Calculate the update amount to be applied to each edge in the path.\n            // This distributes the total error proportionally across all edges, scaled by the learning rate.\n            double delta_per_edge = learning_rate * error / num_edges;\n            \n            // Update the weights of all edges that constitute the found path.\n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i];\n                pair<int, int> v = path_vertices[i+1];\n                update_weight(u.first, u.second, v.first, v.second, delta_per_edge);\n            }\n        }\n    }\n\n    return 0; // Program finished successfully.\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <set>\n#include <tuple>\n#include <numeric> // For iota\n#include <chrono> // For time-based seed\n\nusing namespace std;\n\nint N;\nint M;\nvector<string> s;\n\n// Matrix characters\nconst char EMPTY = '.';\nconst vector<char> ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nstruct Placement {\n    int string_idx;\n    int r, c, dir; // dir: 0 for horizontal, 1 for vertical\n    vector<pair<int, int>> cells; // List of (row, col) for this placement\n    int id_in_string; // Unique ID for this placement within string_idx\n};\n\nvector<vector<Placement>> all_placements_for_string;\nvector<vector<tuple<int, int, int>>> cell_users; // tuple: (string_idx, placement_id_in_string, pos_in_placement)\nvector<vector<bool>> placement_validity;\nvector<int> valid_placement_count;\nvector<bool> is_matched;\nint num_matched;\nlong long total_cells_filled; // Number of non-empty cells\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Helper for toroidal coordinates\nint mod(int a, int b) {\n    return (a % b + b) % b;\n}\n\n// Calculate score\nlong double calculate_score_value() {\n    if (num_matched < M) {\n        return 1e8 * (long double)num_matched / M;\n    } else {\n        // If c=M, score = round(10^8 * 2 N^2 / (2 N^2 - d))\n        // d = N*N - total_cells_filled\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) { // Avoid division by zero or very small numbers\n            return 2e8; // Effectively max score, or a very high value\n        }\n        return 1e8 * term_numerator / term_denominator;\n    }\n}\n\n// Check if a specific placement is valid in the current matrix A\nbool is_placement_valid(const Placement& p, const vector<string>& A) {\n    for (size_t i = 0; i < p.cells.size(); ++i) {\n        int r_cell = p.cells[i].first;\n        int c_cell = p.cells[i].second;\n        if (A[r_cell][c_cell] != EMPTY && A[r_cell][c_cell] != s[p.string_idx][i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Try to make a move and calculate its score change\n// Returns true if the move is accepted and applied\nbool try_move(vector<string>& A, int r, int c, char new_char) {\n    char old_char = A[r][c];\n    if (old_char == new_char) return false;\n\n    // --- State change calculation ---\n    int current_num_matched = num_matched;\n    long long current_total_cells_filled = total_cells_filled;\n    long double current_score_val = calculate_score_value();\n\n    // Store potential changes in counts for affected strings\n    vector<int> affected_string_indices;\n    if (!cell_users[r][c].empty()) {\n        for (const auto& user : cell_users[r][c]) {\n            affected_string_indices.push_back(get<0>(user));\n        }\n        sort(affected_string_indices.begin(), affected_string_indices.end());\n        affected_string_indices.erase(unique(affected_string_indices.begin(), affected_string_indices.end()), affected_string_indices.end());\n    }\n\n    // Store old validity counts before tentative changes\n    vector<pair<int, int>> old_valid_counts;\n    for(int s_idx : affected_string_indices) {\n        old_valid_counts.push_back({s_idx, valid_placement_count[s_idx]});\n    }\n    \n    // Tentatively apply the change to A\n    A[r][c] = new_char;\n    \n    // Calculate potential changes in num_matched and update placement_validity\n    int delta_num_matched = 0;\n    for (int s_idx : affected_string_indices) {\n        int potential_valid_count = 0;\n        for (const auto& user : cell_users[r][c]) { // Iterate through users of the changed cell\n            if (get<0>(user) == s_idx) {\n                int p_id = get<1>(user);\n                bool old_valid = placement_validity[s_idx][p_id];\n                bool new_valid = is_placement_valid(all_placements_for_string[s_idx][p_id], A);\n                \n                if (old_valid != new_valid) {\n                    placement_validity[s_idx][p_id] = new_valid; // Tentatively update validity\n                }\n            }\n        }\n        \n        // Recalculate the total valid count for s_idx based on updated placement_validity\n        // This needs to check ALL placements for s_idx, not just those using (r,c).\n        // So we must iterate through all placements for s_idx.\n        int current_total_valid_count = 0;\n        for(size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n            // If this placement uses (r,c), its validity was just updated.\n            // Otherwise, check its current validity.\n            bool placement_uses_changed_cell = false;\n            for(const auto& cell_in_p : all_placements_for_string[s_idx][p_id].cells) {\n                if (cell_in_p.first == r && cell_in_p.second == c) {\n                    placement_uses_changed_cell = true;\n                    break;\n                }\n            }\n            if (placement_uses_changed_cell) {\n                // Validity was already updated above. Use the updated value.\n                if(placement_validity[s_idx][p_id]) {\n                    current_total_valid_count++;\n                }\n            } else {\n                // Validity is unchanged. Check if it was valid before.\n                if (placement_validity[s_idx][p_id]) { // If it was valid and still is\n                    current_total_valid_count++;\n                }\n            }\n        }\n\n        // Compare old and new total valid counts to update num_matched\n        int old_count_for_s_idx = 0;\n        for(const auto& state : old_valid_counts) {\n            if (state.first == s_idx) {\n                old_count_for_s_idx = state.second;\n                break;\n            }\n        }\n\n        bool was_matched = (old_count_for_s_idx > 0);\n        bool now_matched = (current_total_valid_count > 0);\n\n        if (was_matched && !now_matched) {\n            delta_num_matched--;\n        } else if (!was_matched && now_matched) {\n            delta_num_matched++;\n        }\n        // Update the global valid_placement_count for s_idx\n        valid_placement_count[s_idx] = current_total_valid_count;\n    }\n\n    // Calculate potential new score\n    int potential_num_matched = current_num_matched + delta_num_matched;\n    long long potential_total_cells_filled = current_total_cells_filled;\n    if (old_char == EMPTY && new_char != EMPTY) potential_total_cells_filled++;\n    if (old_char != EMPTY && new_char == EMPTY) potential_total_cells_filled--;\n    \n    long double potential_score_val;\n    if (potential_num_matched < M) {\n        potential_score_val = 1e8 * (long double)potential_num_matched / M;\n    } else {\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - potential_total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) {\n            potential_score_val = 2e8; // Max score\n        } else {\n            potential_score_val = 1e8 * term_numerator / term_denominator;\n        }\n    }\n\n    // Acceptance criteria\n    bool accept = false;\n    if (potential_score_val > current_score_val) {\n        accept = true;\n    } else if (abs(potential_score_val - current_score_val) < 1e-9) { // Scores are approximately equal\n        // Tie-breaking: prefer filling more cells if c==M\n        if (potential_num_matched == M && current_num_matched == M) {\n            if (potential_total_cells_filled > current_total_cells_filled) { // Prefer fewer dots\n                accept = true;\n            }\n        }\n    }\n\n    if (accept) {\n        // Apply changes permanently\n        total_cells_filled = potential_total_cells_filled;\n        num_matched = potential_num_matched;\n        // The placement_validity has been tentatively updated. The valid_placement_count has also been updated.\n        // is_matched needs to be updated based on final valid_placement_count.\n        for(int s_idx : affected_string_indices) {\n            is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n        }\n        return true;\n    } else {\n        // Revert changes\n        A[r][c] = old_char;\n        // Revert placement validity and counts\n        for(const auto& state : old_valid_counts) {\n            int s_idx = state.first;\n            int old_count = state.second;\n            valid_placement_count[s_idx] = old_count; // Restore count\n        }\n        // Revert placement_validity for affected placements\n        for (int s_idx : affected_string_indices) {\n             for (const auto& user : cell_users[r][c]) {\n                if (get<0>(user) == s_idx) {\n                    int p_id = get<1>(user);\n                    // Find original validity for this placement\n                    bool original_validity_for_p = false;\n                    // We need to re-evaluate validity of this specific placement in the *original* grid A.\n                    // Or, store old validity status for each p_id.\n                    // Simpler: just re-evaluate based on the grid BEFORE the tentative change.\n                    // For now, rely on the fact that only the values for s_idx in affected_string_indices are relevant.\n                    // The state variables `placement_validity` are modified locally.\n                    // The current implementation modifies `placement_validity` directly. This needs careful revert.\n                    // A better way is to store old `placement_validity` values too.\n                    // For simplicity, let's re-evaluate validity in the reverted grid A.\n                    \n                    // For this move, if not accepted, the values calculated were never \"global\".\n                    // `placement_validity` should be restored to its state *before* this function call.\n                    // This requires storing old values for `placement_validity` as well.\n                    // To avoid complex state management, we can re-evaluate `placement_validity` for all affected strings.\n                    \n                    // The issue is that `placement_validity` is modified IN PLACE.\n                    // It needs to be reverted if the move is not accepted.\n                    // This implies we must record the old validity for each affected placement.\n                    // Given the complexity, let's assume the logic in `try_move` that re-calculates `valid_placement_count` and `delta_num_matched` is sufficient, and `placement_validity` modifications are temporary.\n                    // The `placement_validity` modifications are only made permanent if `accept` is true.\n                    // The issue is that the `placement_validity` gets modified even if `accept` is false.\n                    // This requires explicitly reverting `placement_validity`.\n\n                    // Re-evaluating original validity for placement p_id\n                    bool original_validity = is_placement_valid(all_placements_for_string[s_idx][p_id], A); // A is now reverted\n                    placement_validity[s_idx][p_id] = original_validity;\n                }\n            }\n        }\n        return false;\n    }\n}\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M;\n    s.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n    }\n\n    // Precomputation: Generate all possible placements\n    all_placements_for_string.resize(M);\n    cell_users.resize(N, vector<tuple<int, int, int>>(N));\n    \n    int current_placement_id = 0;\n    for (int i = 0; i < M; ++i) {\n        int k = s[i].length();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Horizontal placement\n                Placement p_h;\n                p_h.string_idx = i;\n                p_h.r = r; p_h.c = c; p_h.dir = 0;\n                p_h.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_h.cells[pi] = {r, mod(c + pi, N)};\n                }\n                p_h.id_in_string = all_placements_for_string[i].size(); // ID within string i\n                all_placements_for_string[i].push_back(p_h);\n\n                // Vertical placement\n                Placement p_v;\n                p_v.string_idx = i;\n                p_v.r = r; p_v.c = c; p_v.dir = 1;\n                p_v.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_v.cells[pi] = {mod(r + pi, N), c};\n                }\n                p_v.id_in_string = all_placements_for_string[i].size(); // ID within string i\n                all_placements_for_string[i].push_back(p_v);\n            }\n        }\n    }\n\n    // Populate cell_users: map each cell to which placements use it\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < all_placements_for_string[i].size(); ++j) {\n            const auto& p = all_placements_for_string[i][j];\n            for (size_t cell_idx = 0; cell_idx < p.cells.size(); ++cell_idx) {\n                int r_cell = p.cells[cell_idx].first;\n                int c_cell = p.cells[cell_idx].second;\n                cell_users[r_cell][c_cell].emplace_back(i, j, cell_idx); // string_idx, placement_id_in_string_i, pos_in_placement\n            }\n        }\n    }\n\n    // Initialize matrix and state tracking variables\n    vector<string> A(N, string(N, EMPTY));\n    total_cells_filled = 0;\n\n    placement_validity.resize(M);\n    valid_placement_count.resize(M, 0);\n    is_matched.resize(M, false);\n    num_matched = 0;\n\n    // Initial state: empty grid cannot satisfy specific character requirements.\n    // So, initially, no placement is valid, no string is matched.\n    for (int i = 0; i < M; ++i) {\n        placement_validity[i].resize(all_placements_for_string[i].size(), false);\n    }\n\n    // --- Greedy Seeding Phase ---\n    // Iteratively fill cells to match as many strings as possible.\n    // Repeat until no new strings are matched in a full pass.\n    int max_greedy_passes = 5; // Limit passes to prevent long execution if greedy gets stuck\n    for(int pass = 0; pass < max_greedy_passes; ++pass) {\n        bool new_match_made_in_pass = false;\n        \n        // Create an order of strings to process to break ties and avoid consistent bias\n        vector<int> string_order(M);\n        iota(string_order.begin(), string_order.end(), 0);\n        shuffle(string_order.begin(), string_order.end(), rng);\n\n        for (int s_idx : string_order) {\n            if (is_matched[s_idx]) continue;\n\n            int best_p_id = -1;\n            int min_dots_used_for_best_p = N*N + 1; // Initialize with a value larger than possible\n\n            // Find the best valid placement for s_idx\n            for (size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n                if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                    int current_dots_used = 0;\n                    for (const auto& cell : all_placements_for_string[s_idx][p_id].cells) {\n                        if (A[cell.first][cell.second] == EMPTY) {\n                            current_dots_used++;\n                        }\n                    }\n\n                    // Prioritize placement that uses fewer '.' cells.\n                    if (current_dots_used < min_dots_used_for_best_p) {\n                        min_dots_used_for_best_p = current_dots_used;\n                        best_p_id = p_id;\n                    }\n                }\n            }\n            \n            // If a valid placement was found, apply it\n            if (best_p_id != -1) {\n                const auto& p_to_apply = all_placements_for_string[s_idx][best_p_id];\n                for (const auto& cell : p_to_apply.cells) {\n                    if (A[cell.first][cell.second] == EMPTY) {\n                        // Find the character for this cell in the placement\n                        int cell_pos = -1;\n                        for(size_t pi = 0; pi < p_to_apply.cells.size(); ++pi) {\n                            if (p_to_apply.cells[pi] == cell) {\n                                cell_pos = pi;\n                                break;\n                            }\n                        }\n                        A[cell.first][cell.second] = s[s_idx][cell_pos];\n                        total_cells_filled++;\n                    }\n                }\n                \n                // Update match status for the current string s_idx\n                is_matched[s_idx] = true;\n                num_matched++;\n                new_match_made_in_pass = true;\n\n                // After filling cells, other strings' match statuses might change.\n                // Re-evaluate all strings affected by the newly filled cells.\n                set<int> newly_affected_strings;\n                for(const auto& cell : p_to_apply.cells) {\n                    // Only consider cells that were newly filled\n                    if (A[cell.first][cell.second] != EMPTY) { // Check if it's non-empty now\n                        // Determine if it was indeed newly filled by this placement\n                        bool was_empty_before_fill = false;\n                        for (const auto& user : cell_users[cell.first][cell.second]) {\n                           int user_s_idx = get<0>(user);\n                           int user_p_id = get<1>(user);\n                           const auto& user_p = all_placements_for_string[user_s_idx][user_p_id];\n                           bool cell_is_in_user_p = false;\n                           for(const auto& p_cell : user_p.cells) if(p_cell == cell) cell_is_in_user_p = true;\n\n                           if(cell_is_in_user_p) { // If this user placement uses this cell\n                               // Check if this user placement was valid *before* this current move was applied\n                               // This check is tricky because A has been modified.\n                               // For simplicity, assume any cell filled by this placement can affect others.\n                               newly_affected_strings.insert(get<0>(user));\n                           }\n                        }\n                    }\n                }\n                \n                // Propagate match status updates\n                for(int affected_s_idx : newly_affected_strings) {\n                    if (affected_s_idx == s_idx) continue; // Already handled\n\n                    // Re-evaluate validity for all placements of affected_s_idx\n                    valid_placement_count[affected_s_idx] = 0;\n                    for(size_t p_id_check = 0; p_id_check < all_placements_for_string[affected_s_idx].size(); ++p_id_check) {\n                        placement_validity[affected_s_idx][p_id_check] = is_placement_valid(all_placements_for_string[affected_s_idx][p_id_check], A);\n                        if (placement_validity[affected_s_idx][p_id_check]) {\n                            valid_placement_count[affected_s_idx]++;\n                        }\n                    }\n                    \n                    // Update global match status\n                    bool was_matched = is_matched[affected_s_idx];\n                    bool now_matched = (valid_placement_count[affected_s_idx] > 0);\n\n                    if (was_matched && !now_matched) {\n                        is_matched[affected_s_idx] = false;\n                        num_matched--;\n                        new_match_made_in_pass = true; // Status changed\n                    } else if (!was_matched && now_matched) {\n                        is_matched[affected_s_idx] = true;\n                        num_matched++;\n                        new_match_made_in_pass = true; // Status changed\n                    }\n                }\n            }\n        }\n        if (!new_match_made_in_pass) break; // Stop if no new strings were matched in a full pass\n    }\n\n    // --- Local Search Phase ---\n    // Adjusted ITER_COUNT based on M, to balance exploration and time limit\n    int ITER_COUNT = 100000;\n    if (M > 600) ITER_COUNT = 80000;\n    if (M > 700) ITER_COUNT = 60000;\n    if (M > 750) ITER_COUNT = 50000;\n\n\n    uniform_int_distribution<int> dist_N(0, N - 1);\n    uniform_int_distribution<int> dist_char_idx(0, ALPHABET.size() - 1);\n\n    for (int iter = 0; iter < ITER_COUNT; ++iter) {\n        int r = dist_N(rng);\n        int c = dist_N(rng);\n        char old_char = A[r][c];\n        \n        char new_char;\n        // Determine the target character for the move\n        if (num_matched == M) { \n            // If all strings are matched, focus on reducing dots (increasing filled cells).\n            // Only moves that change a character to EMPTY are beneficial.\n            if (old_char != EMPTY) {\n                new_char = EMPTY;\n            } else {\n                // If the cell is already EMPTY, changing it to a character will increase 'd', decreasing score.\n                // Skip this iteration as it's unlikely to improve score.\n                continue;\n            }\n        } else { \n            // If not all strings are matched, focus on increasing num_matched.\n            // We can try changing to any character or to EMPTY.\n            // Try changing to a random character first.\n            int char_or_empty = rng() % (ALPHABET.size() + 1);\n            if (char_or_empty < ALPHABET.size()) {\n                new_char = ALPHABET[char_or_empty];\n            } else {\n                new_char = EMPTY;\n            }\n        }\n        \n        // Attempt the move. try_move returns true if accepted.\n        try_move(A, r, c, new_char);\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        cout << A[i] << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <utility>\n#include <algorithm>\n#include <cmath>\n#include <iomanip> // For potential debugging\n#include <tuple>   // For std::tuple\n\nusing namespace std;\n\n// Use a large enough value for infinity for Dijkstra distances\nconst long long INF = 1e18;\n\nint N; // Grid size\nint si, sj; // Starting row and column\nvector<string> grid; // Stores the grid characters ('#', '5'-'9')\nvector<vector<int>> cost_grid; // Stores the cost to enter a road square\nvector<pair<int, int>> road_coords; // Stores {row, col} for all road squares\nmap<pair<int, int>, int> coord_to_id; // Maps {row, col} to a unique ID for road squares\nvector<vector<vector<int>>> visible_from; // visible_from[r][c] stores IDs of road squares visible from (r, c)\nvector<vector<pair<int, int>>> adj_grid; // adj_grid[r][c] stores {neighbor_r, neighbor_c} for road squares adjacent to (r,c)\nvector<bool> is_road_covered; // Boolean vector, true if road square with that ID is covered\npair<int, int> current_pos; // Current position of the patrol car\nlong long total_time = 0; // Total travel time of the route\nvector<pair<int, int>> route_path; // Stores the sequence of positions (coordinates) in the route\n\n// Directions for movement: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Function to check if a coordinate is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Function to reconstruct path from Dijkstra's parent pointers\nvector<pair<int, int>> reconstruct_path(const vector<vector<pair<int, int>>>& parent, pair<int, int> start_node, pair<int, int> end_node) {\n    vector<pair<int, int>> path;\n    pair<int, int> curr = end_node;\n\n    // Trace back from end_node to start_node using parent pointers\n    while (!(curr.first == start_node.first && curr.second == start_node.second)) {\n        path.push_back(curr);\n        curr = parent[curr.first][curr.second];\n        // If curr.first is -1, it means we reached an invalid parent, implying no path was found\n        if (curr.first == -1) {\n            // This case should ideally not be reached if a path exists\n            // If start_node and end_node are the same, this loop is skipped\n            break; \n        }\n    }\n    \n    // Add the start node itself to the path\n    // If start_node is same as end_node, the loop above is skipped, path is empty.\n    // We push start_node so path becomes [{start_node}]. This is correct.\n    if (!path.empty() || start_node == end_node) {\n        path.push_back(start_node);\n    } else {\n        // If path is empty and start_node != end_node, it implies start_node was unreachable from end_node.\n        // This scenario should not occur given the problem constraints (connected road graph).\n        // For safety, return an empty path if no path is found.\n        return {};\n    }\n   \n    reverse(path.begin(), path.end()); // Reverse to get path from start to end\n    return path;\n}\n\nvoid solve() {\n    // 1. Read input and initialize data structures\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    cost_grid.resize(N, vector<int>(N));\n    adj_grid.resize(N, vector<pair<int, int>>(N)); // Stores neighbors for each grid cell (only road neighbors)\n    visible_from.resize(N, vector<vector<int>>(N));\n\n    int road_id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') { // If it's a road square\n                cost_grid[i][j] = grid[i][j] - '0'; // Store its travel cost\n                road_coords.push_back({i, j}); // Add its coordinates to the list\n                coord_to_id[{i, j}] = road_id_counter++; // Map its coordinates to a unique ID\n            }\n        }\n    }\n\n    is_road_covered.resize(road_coords.size(), false); // Initialize all roads as not covered\n    current_pos = {si, sj}; // Set current position to the start\n    route_path.push_back(current_pos); // Add start position to the route path\n\n    // 2. Precompute visibility and adjacency for each road square\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] != '#') { // Process only road squares\n                int current_road_id = coord_to_id.at({r, c});\n\n                // A square is always visible from itself\n                visible_from[r][c].push_back(current_road_id);\n\n                // Scan in four directions to find all visible road squares\n                // Left\n                for (int k = c - 1; k >= 0; --k) {\n                    if (grid[r][k] == '#') break; // Stop if an obstacle is encountered\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Right\n                for (int k = c + 1; k < N; ++k) {\n                    if (grid[r][k] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Up\n                for (int k = r - 1; k >= 0; --k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                // Down\n                for (int k = r + 1; k < N; ++k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                \n                // Build adjacency list for road squares: find adjacent road squares\n                for(int i=0; i<4; ++i) {\n                    int nr = r + dr[i];\n                    int nc = c + dc[i];\n                    if (is_valid(nr, nc) && grid[nr][nc] != '#') {\n                        adj_grid[r][c].push_back({nr, nc}); // Store neighbor coordinates\n                    }\n                }\n            }\n        }\n    }\n\n    // Mark initially covered roads based on the starting position\n    for (int visible_road_id : visible_from[si][sj]) {\n        is_road_covered[visible_road_id] = true;\n    }\n\n    // 3. Greedy phase: iteratively move to cover remaining roads\n    int covered_count = 0;\n    for(bool covered : is_road_covered) if(covered) covered_count++;\n\n    while (covered_count < road_coords.size()) {\n        // Find the best next move: one that maximizes coverage gain per unit cost\n        double best_score = -1.0;\n        int best_next_r = -1, best_next_c = -1;\n        \n        // Store candidates for the next move: (score, cost, next_r, next_c)\n        vector<tuple<double, long long, int, int>> candidates; \n\n        // Iterate through adjacent road squares of the current position\n        for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter this neighbor\n\n            int num_newly_covered = 0;\n            // Count how many currently uncovered roads are visible from this neighbor\n            for (int visible_road_id : visible_from[nr][nc]) {\n                if (!is_road_covered[visible_road_id]) {\n                    num_newly_covered++;\n                }\n            }\n\n            // If this move covers at least one new road, consider it as a candidate\n            if (num_newly_covered > 0) {\n                double current_score = (double)num_newly_covered / move_cost; // Coverage gain per unit cost\n                candidates.emplace_back(current_score, move_cost, nr, nc);\n            }\n        }\n\n        // Select the best candidate move\n        if (!candidates.empty()) {\n            // Sort candidates: primarily by score (descending), secondarily by cost (ascending)\n            sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b) {\n                if (abs(get<0>(a) - get<0>(b)) > 1e-9) { // Compare scores with tolerance\n                    return get<0>(a) > get<0>(b); // Higher score first\n                }\n                return get<1>(a) < get<1>(b); // Lower cost first for tie-breaking\n            });\n\n            best_next_r = get<2>(candidates[0]);\n            best_next_c = get<3>(candidates[0]);\n            \n        } else {\n            // Fallback strategy: If no adjacent road square offers new coverage,\n            // choose the cheapest move to any adjacent road square to explore.\n            long long min_fallback_cost = -1;\n            for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n                int nr = neighbor_pos.first;\n                int nc = neighbor_pos.second;\n                long long move_cost = cost_grid[nr][nc];\n\n                if (min_fallback_cost == -1 || move_cost < min_fallback_cost) {\n                    min_fallback_cost = move_cost;\n                    best_next_r = nr;\n                    best_next_c = nc;\n                }\n            }\n            // If best_next_r is still -1, it means current_pos has no road neighbors.\n            // This scenario is unlikely in a connected road graph as per problem statement.\n        }\n        \n        // Apply the chosen move\n        total_time += cost_grid[best_next_r][best_next_c]; // Add cost to enter the new square\n        current_pos = {best_next_r, best_next_c}; // Update current position\n        route_path.push_back(current_pos); // Add the new position to the route path\n\n        // Update the coverage status of roads\n        for (int visible_road_id : visible_from[best_next_r][best_next_c]) {\n            if (!is_road_covered[visible_road_id]) {\n                is_road_covered[visible_road_id] = true; // Mark as covered\n                covered_count++; // Increment total count of covered roads\n            }\n        }\n    }\n\n    // 4. Phase 2: Return to the starting position (si, sj) using Dijkstra's algorithm\n    vector<vector<long long>> dist(N, vector<long long>(N, INF)); // Distances\n    vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1})); // Parent pointers for path reconstruction\n    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq; // Priority queue for Dijkstra\n\n    dist[current_pos.first][current_pos.second] = 0; // Distance from current position to itself is 0\n    pq.push({0, current_pos}); // Push start node for Dijkstra\n\n    pair<int, int> dijkstra_target = {si, sj}; // Target is the original start position\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n\n        // If current distance is greater than recorded distance, skip (already found shorter path)\n        if (d > dist[pos.first][pos.second]) continue;\n        // If we reached the target, break (found shortest path)\n        if (pos == dijkstra_target) break; \n\n        // Explore neighbors\n        for (const auto& neighbor_pos : adj_grid[pos.first][pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter neighbor\n\n            // Relaxation step\n            if (dist[pos.first][pos.second] + move_cost < dist[nr][nc]) {\n                dist[nr][nc] = dist[pos.first][pos.second] + move_cost;\n                parent[nr][nc] = pos; // Set parent for path reconstruction\n                pq.push({dist[nr][nc], {nr, nc}}); // Push neighbor to priority queue\n            }\n        }\n    }\n\n    // Reconstruct and append the return path to the route_path\n    vector<pair<int, int>> return_path_coords = reconstruct_path(parent, current_pos, dijkstra_target);\n    \n    // Append the steps from the return path, starting from the second element\n    // (the first element would be the current_pos itself, which is already in route_path)\n    if (!return_path_coords.empty()) {\n        for (size_t i = 1; i < return_path_coords.size(); ++i) {\n            route_path.push_back(return_path_coords[i]);\n            total_time += cost_grid[return_path_coords[i].first][return_path_coords[i].second]; // Add cost to enter each step\n        }\n    }\n\n    // 5. Generate the output route string (sequence of moves)\n    string result_route = \"\";\n    for (size_t i = 0; i + 1 < route_path.size(); ++i) {\n        pair<int, int> p1 = route_path[i];\n        pair<int, int> p2 = route_path[i+1];\n        int dr_move = p2.first - p1.first;\n        int dc_move = p2.second - p1.second;\n\n        if (dr_move == -1 && dc_move == 0) result_route += 'U'; // Up\n        else if (dr_move == 1 && dc_move == 0) result_route += 'D'; // Down\n        else if (dr_move == 0 && dc_move == -1) result_route += 'L'; // Left\n        else if (dr_move == 0 && dc_move == 1) result_route += 'R'; // Right\n    }\n\n    // Output the generated route string\n    cout << result_route << endl;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main logic\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n// Enum for task status\nenum TaskStatus {\n    UNSTARTED,\n    READY,\n    IN_PROGRESS,\n    COMPLETED\n};\n\n// A large value representing an unknown or very large estimated skill deficit.\n// The maximum possible w_ij could be around K * max(d_ik) ~ 20 * 160 = 3200.\n// Using 3300.0 ensures it's larger than any realistic w_ij.\nconst double INF_ESTIMATED_W = 3300.0; \n\nint N, M, K, R;\nvector<vector<int>> d; // d[task_idx][skill_idx]: required skill levels for task i\nvector<vector<int>> adj; // adj[task_idx]: list of tasks that depend on this task (successors)\nvector<int> in_degree; // in_degree[task_idx]: number of prerequisites not yet met for this task\n\nvector<TaskStatus> task_status;\nvector<bool> member_free; // True if member is available to take a new task\nvector<int> member_current_task; // Stores task_idx if member is busy, -1 otherwise\nvector<int> task_start_day; // Stores the day a task was STARTED (1-indexed day)\n\n// Data for learning and estimation\n// estimated_w[member_idx][task_idx]: estimated skill deficit w_ij for member j on task i.\n// Initialized to INF_ESTIMATED_W. Updated when member j completes task i.\nvector<vector<double>> estimated_w; \n\n// Statistics for members: used for fallback estimation when specific (member, task) w is unknown\nvector<int> member_task_count; // Number of tasks completed by this member\nvector<double> sum_observed_times_member; // Sum of durations of tasks completed by this member\n\n// Global statistics: used as a fallback when member-specific info is also unavailable\ndouble global_average_observed_duration = INF_ESTIMATED_W;\nlong long global_total_tasks_completed = 0;\ndouble global_total_observed_time = 0.0;\n\n// Structure to represent a potential assignment (member, task) with its estimated duration.\n// Used for sorting to greedily pick the best assignments.\nstruct Assignment {\n    double estimated_duration;\n    int member_idx;\n    int task_idx;\n\n    // Custom comparison for sorting: primarily by estimated_duration (ascending).\n    // Smaller duration is better. Tie-breaking is done by member_idx then task_idx for determinism.\n    bool operator<(const Assignment& other) const {\n        // Use a small epsilon for floating point comparisons to avoid issues with precision.\n        if (abs(estimated_duration - other.estimated_duration) > 1e-9) {\n            return estimated_duration < other.estimated_duration;\n        }\n        // Tie-breaking: Prefer lower indexed member, then lower indexed task.\n        if (member_idx != other.member_idx) {\n            return member_idx < other.member_idx;\n        }\n        return task_idx < other.task_idx;\n    }\n};\n\n// Updates the estimated_w for a specific (member_idx, task_idx) pair based on observed time.\n// This function is called at most once for each (member, task) pair because a task\n// is assigned to at most one member, and a member is assigned at most one task at a time.\nvoid update_estimated_w(int member_idx, int task_idx, int observed_time) {\n    double w_val;\n    if (observed_time == 1) {\n        // If task took 1 day, according to the problem statement (w_ij=0 => t_ij=1), w_ij must be 0.\n        w_val = 0.0;\n    } else {\n        // If observed_time > 1, then observed_time = w_ij + r_i, where r_i is a random integer in [-3, 3].\n        // This implies w_ij is in the range [max(0, observed_time - 3), observed_time + 3].\n        // We use the midpoint of this range as our best estimate for w_ij.\n        double w_min = max(0, observed_time - 3);\n        double w_max = observed_time + 3;\n        w_val = (w_min + w_max) / 2.0; \n    }\n    // Store the estimated skill deficit.\n    estimated_w[member_idx][task_idx] = w_val;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial problem parameters.\n    cin >> N >> M >> K >> R;\n\n    // Read task difficulty levels (d_i,k).\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Read task dependencies, build adjacency list (successors) and in-degree array.\n    adj.resize(N);\n    in_degree.resize(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; // Dependency: u must be completed before v can start.\n        cin >> u >> v;\n        --u; --v; // Convert to 0-indexed: u is prerequisite for v.\n        adj[u].push_back(v); // Add v to the adjacency list of u.\n        in_degree[v]++; // Increment in-degree of v.\n    }\n\n    // Initialize state variables for tasks and members.\n    task_status.resize(N, UNSTARTED);\n    member_free.resize(M, true);\n    member_current_task.resize(M, -1);\n    task_start_day.resize(N, -1); // -1 indicates task has not started yet.\n\n    // Initialize data structures for learning and estimation.\n    estimated_w.resize(M, vector<double>(N, INF_ESTIMATED_W));\n    member_task_count.resize(M, 0);\n    sum_observed_times_member.resize(M, 0.0);\n\n    // Identify tasks that are initially ready (have an in-degree of 0).\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) {\n            task_status[i] = READY;\n        }\n    }\n\n    int current_day = 1; // Simulation starts from day 1.\n    int completed_tasks_count = 0; // Counter for total completed tasks.\n\n    // Main simulation loop, runs day by day until all tasks are completed or time limit is reached.\n    while (completed_tasks_count < N) {\n        // 1. Process tasks completed at the END of the previous day.\n        vector<int> completed_members_indices_today; // Store indices of members who finished tasks.\n        int n_completed_input;\n        cin >> n_completed_input;\n\n        // Check for termination signal (-1) from the judge.\n        if (n_completed_input == -1) {\n            break; // Exit simulation if signal is received.\n        }\n\n        for (int i = 0; i < n_completed_input; ++i) {\n            int f_idx_1based;\n            cin >> f_idx_1based;\n            int member_idx = f_idx_1based - 1; // Convert member ID to 0-indexed.\n\n            completed_members_indices_today.push_back(member_idx);\n\n            int task_idx = member_current_task[member_idx]; // Get the task this member was working on.\n            \n            // Calculate the time taken for the task.\n            // A task started on task_start_day[task_idx] and finished at the end of current_day\n            // took current_day - task_start_day[task_idx] days.\n            int observed_time = current_day - task_start_day[task_idx];\n\n            // Update global statistics for overall average performance.\n            global_total_observed_time += observed_time;\n            global_total_tasks_completed++;\n            // Re-calculate global average duration to be more accurate.\n            global_average_observed_duration = global_total_observed_time / global_total_tasks_completed;\n\n            // Learn from the completed task: update estimated_w for this specific (member, task) pair.\n            update_estimated_w(member_idx, task_idx, observed_time);\n            \n            // Update task status to COMPLETED.\n            task_status[task_idx] = COMPLETED;\n            completed_tasks_count++;\n\n            // Mark the member as free, ready for a new assignment.\n            member_free[member_idx] = true;\n            member_current_task[member_idx] = -1;\n            \n            // Update member-specific statistics for future estimations.\n            member_task_count[member_idx]++;\n            sum_observed_times_member[member_idx] += observed_time;\n\n            // Update dependencies: decrement in-degree of successor tasks.\n            // If a successor task's in-degree becomes 0, it becomes READY.\n            for (int dependent_task_idx : adj[task_idx]) {\n                in_degree[dependent_task_idx]--;\n                if (in_degree[dependent_task_idx] == 0) {\n                    task_status[dependent_task_idx] = READY;\n                }\n            }\n        }\n        \n        // 2. Generate potential assignments for the current day.\n        vector<Assignment> candidates; // List to store all possible assignments with their estimated durations.\n        vector<int> ready_tasks_indices;\n        // Collect indices of all tasks that are currently READY.\n        for(int i=0; i<N; ++i) {\n            if (task_status[i] == READY) {\n                ready_tasks_indices.push_back(i);\n            }\n        }\n\n        // For every free member and every ready task, calculate an estimated duration.\n        for (int j = 0; j < M; ++j) { // Iterate through all members\n            if (member_free[j]) { // If member j is available\n                for (int task_idx : ready_tasks_indices) { // Consider all ready tasks\n                    double estimated_duration;\n                    \n                    // Heuristic: Estimate task duration for this (member, task) pair.\n                    // We prioritize assignments with the shortest estimated duration.\n                    // The estimation logic follows a hierarchy of information availability:\n                    // 1. Specific (member, task) estimate: If we have observed member j doing task i before.\n                    // 2. Member's average performance: If member j has completed other tasks.\n                    // 3. Global average performance: If member j is new and no other info is available.\n                    // 4. A very large value: If no historical data exists globally.\n\n                    // 1. Check if `estimated_w[j][task_idx]` has been updated from its initial large value.\n                    // The check ` < INF_ESTIMATED_W - 1.0` is a robust way to see if it's been set.\n                    if (estimated_w[j][task_idx] < INF_ESTIMATED_W - 1.0) { \n                        // `estimated_w` is the estimated skill deficit.\n                        // The estimated time to complete is max(1, estimated_w). This assumes r_i=0 for expected time.\n                        estimated_duration = max(1.0, estimated_w[j][task_idx]);\n                    } else {\n                        // 2. Fallback: Member j has some history (completed other tasks). Use their average completion time.\n                        if (member_task_count[j] > 0) {\n                            estimated_duration = sum_observed_times_member[j] / member_task_count[j];\n                        } else {\n                            // 3. Truly global fallback: Member j is new. Use global average observed time if available.\n                            if (global_total_tasks_completed > 0) {\n                                estimated_duration = global_average_observed_duration;\n                            } else {\n                                // 4. If no tasks have been completed globally yet, use a default high value.\n                                estimated_duration = INF_ESTIMATED_W;\n                            }\n                        }\n                    }\n                    \n                    // Ensure minimum duration is 1 day, as per problem statement.\n                    estimated_duration = max(1.0, estimated_duration);\n                    candidates.push_back({estimated_duration, j, task_idx}); // Add this potential assignment to candidates.\n                }\n            }\n        }\n\n        // Sort all candidate assignments by their estimated duration (ascending).\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Make assignments for the current day.\n        vector<pair<int, int>> assignments_today; // Stores {member_idx, task_idx} for output.\n        vector<bool> task_assigned_today(N, false); // Helper to ensure each task is assigned at most once per day.\n        \n        // Iterate through sorted candidates and make assignments greedily.\n        for (const auto& assignment : candidates) {\n            // Stop if we have already assigned tasks to all M members.\n            if (assignments_today.size() == M) { \n                break;\n            }\n            \n            int member_idx = assignment.member_idx;\n            int task_idx = assignment.task_idx;\n\n            // Check if the member is still free, the task is still ready, and the task hasn't been assigned today.\n            if (member_free[member_idx] && task_status[task_idx] == READY && !task_assigned_today[task_idx]) {\n                // Make the assignment.\n                member_free[member_idx] = false; // Mark member as busy.\n                member_current_task[member_idx] = task_idx; // Assign task to member.\n                task_start_day[task_idx] = current_day; // Record the start day.\n                task_status[task_idx] = IN_PROGRESS; // Update task status.\n                \n                assignments_today.push_back({member_idx, task_idx}); // Record assignment for output.\n                task_assigned_today[task_idx] = true; // Mark task as assigned for today.\n            }\n        }\n\n        // 4. Output assignments for the current day.\n        cout << assignments_today.size(); // Number of assignments.\n        for (const auto& p : assignments_today) {\n            // Output member ID and task ID (1-based).\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1; \n        }\n        cout << endl;\n        cout.flush(); // Ensure output is sent immediately.\n\n        current_day++; // Advance to the next day.\n    }\n\n    return 0; // End of simulation.\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n\n// Use long long for coordinates and distances to be safe, although int might suffice for coordinates\nusing coord_t = int;\nusing dist_t = long long;\n\nstruct Point {\n    coord_t x, y;\n    int id; // Original order ID, or special ID for office\n\n    // Equality operator for point comparisons\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Less than operator for potential use in sets/maps if needed (though not strictly required by this solution)\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// Calculate Manhattan distance between two points\ndist_t manhattan_distance(const Point& p1, const Point& p2) {\n    // Use static_cast to long long to prevent intermediate overflow in abs() if coordinates are large\n    return std::abs(static_cast<long long>(p1.x) - p2.x) + std::abs(static_cast<long long>(p1.y) - p2.y);\n}\n\n// Structure to hold information about a single delivery order\nstruct Order {\n    int id;\n    Point pickup;\n    Point delivery;\n    dist_t internal_dist; // Manhattan distance between pickup and delivery\n    dist_t dist_to_office_pickup; // Manhattan distance from office to pickup\n    dist_t dist_delivery_to_office; // Manhattan distance from delivery to office\n};\n\n// Structure for candidate points during route construction\n// Represents a point to visit next, along with its cost and type (pickup/delivery)\nstruct Candidate {\n    Point p;\n    dist_t cost; // Cost to reach this point from the current location\n    int type; // 0 for pickup, 1 for delivery\n    int order_id; // The ID of the order this point belongs to\n\n    // Custom comparison for sorting candidates by cost\n    bool operator<(const Candidate& other) const {\n        if (cost != other.cost) {\n            return cost < other.cost;\n        }\n        // Tie-breaking: if costs are equal, prioritize deliveries slightly.\n        // This is a minor heuristic and can be adjusted.\n        return type > other.type; // Deliveries (type 1) come after pickups (type 0) in sorting order, so higher cost first.\n                                   // This makes them less likely to be picked if costs are equal.\n                                   // To prioritize deliveries, one would return type < other.type.\n                                   // Let's stick to simple cost sorting for now.\n    }\n};\n\n// Function to perform 2-opt local search on a tour (vector of Points)\n// This heuristic improves a TSP tour by reversing segments.\n// The route vector includes the start and end office points.\nvoid two_opt(std::vector<Point>& route) {\n    int n = route.size();\n    if (n <= 3) return; // Need at least O -> P -> O (3 points) for any meaningful move\n\n    bool improved = true;\n    while (improved) {\n        improved = false;\n        \n        // Iterate through all possible pairs of edges to swap.\n        // The core idea of 2-opt is to reverse a segment of the tour.\n        // For a tour v_0, v_1, ..., v_{n-1}, we consider reversing the segment from v_{i+1} to v_j.\n        // This replaces edges (v_i, v_{i+1}) and (v_j, v_{j+1}) with (v_i, v_j) and (v_{i+1}, v_{j+1}).\n        // Indices i and j are chosen such that 0 <= i < j < n.\n        // The actual segment reversed is route[i+1 ... j].\n        // Loop for i: 0 to n-2 (as route[i] is the node before the segment).\n        // Loop for j: i+1 to n-1 (as route[j] is the node after the segment).\n        for (int i = 0; i < n - 1; ++i) { \n            for (int j = i + 1; j < n; ++j) {\n                \n                // Ensure we are not trying to reverse an empty or single-point segment.\n                // The segment to reverse is route[i+1]...route[j].\n                // If i+1 == j, the segment has only one point route[i+1]. Reversing it does nothing.\n                // If j = i+1, we are considering swapping (route[i], route[i+1]) and (route[i+1], route[i+2]) with (route[i], route[i+1]) and (route[i+1], route[i+2]) - no change.\n                // We need at least two edges to swap, meaning route[i], route[i+1], route[j], route[j+1] must be distinct in terms of edges.\n                // The condition `if (i + 1 < j)` is a common way to ensure the segment to reverse has at least two points.\n                // However, standard 2-opt considers reversing from i+1 to j. So j must be at least i+1.\n                // If j = i+1, we are reversing route[i+1]. This doesn't change anything.\n                // If j = i+2, we are reversing route[i+1], route[i+2].\n                // The segment is route.begin() + i + 1 to route.begin() + j + 1.\n                // This means reversing route[i+1] ... route[j].\n                // Indices `i` and `j` are the *endpoints* of the edges being re-routed.\n                // The new edges are (route[i], route[j]) and (route[i+1], route[j+1]).\n                // For this to be a valid swap of two edges, we must have i < j.\n                // The segment being reversed is from index i+1 to j.\n                // If j = i+1, segment is route[i+1]. Reversing does nothing.\n                // Cost change: dist(route[i], route[j]) + dist(route[i+1], route[j+1]) - dist(route[i], route[i+1]) - dist(route[j], route[j+1])\n                // This calculation correctly represents the cost difference.\n                \n                // Ensure indices are valid and we are not operating on single-edge segments.\n                if (i + 1 < n && j + 1 < n) { // Ensure route[i+1] and route[j+1] are valid indices\n                    dist_t cost_change = manhattan_distance(route[i], route[j]) +\n                                          manhattan_distance(route[i+1], route[j+1]) -\n                                          manhattan_distance(route[i], route[i+1]) -\n                                          manhattan_distance(route[j], route[j+1]);\n\n                    if (cost_change < 0) {\n                        // Improvement found, reverse the segment from index i+1 to j (inclusive).\n                        std::reverse(route.begin() + i + 1, route.begin() + j + 1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Helper function to determine the grid cell coordinates for a given point\nstd::pair<int, int> get_cell(const Point& p) {\n    return {p.x / 80, p.y / 80}; // 800 / 10 = 80\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::vector<Order> all_orders(1000);\n    Point office = {400, 400, -1}; // Office location, ID -1 signifies office\n\n    // Read input for all 1000 orders\n    for (int i = 0; i < 1000; ++i) {\n        all_orders[i].id = i + 1; // Order IDs are 1-based\n        std::cin >> all_orders[i].pickup.x >> all_orders[i].pickup.y >> all_orders[i].delivery.x >> all_orders[i].delivery.y;\n        \n        // Assign original order ID to Point objects\n        all_orders[i].pickup.id = i + 1;\n        all_orders[i].delivery.id = i + 1;\n\n        // Pre-calculate distances for scoring and route construction\n        all_orders[i].internal_dist = manhattan_distance(all_orders[i].pickup, all_orders[i].delivery);\n        all_orders[i].dist_to_office_pickup = manhattan_distance(office, all_orders[i].pickup);\n        all_orders[i].dist_delivery_to_office = manhattan_distance(all_orders[i].delivery, office);\n    }\n\n    // --- Order Selection Heuristic ---\n    // Strategy: Select orders that are spatially clustered and relatively close to the office.\n    // 1. Divide the 800x800 area into 10x10 grid cells.\n    // 2. Group orders by the cell their pickup point falls into.\n    // 3. Score cells based on the average distance from the office to pickup points within them.\n    // 4. Prioritize cells closest to the office.\n    // 5. Collect candidate orders from prioritized cells, sorting them by internal travel distance.\n    // 6. Further refine candidates by a combined score and select the top 50.\n\n    // Map to group orders by their pickup cell\n    std::map<std::pair<int, int>, std::vector<Order*>> cell_to_orders_map;\n\n    for (auto& order : all_orders) {\n        cell_to_orders_map[get_cell(order.pickup)].push_back(&order);\n    }\n\n    // Calculate scores for each cell and store them along with cell coordinates\n    std::vector<std::pair<dist_t, std::pair<int, int>>> cell_scores;\n    for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n        if (order_list.empty()) continue; // Skip empty cells\n        dist_t total_dist_to_cell_pickup = 0;\n        for (Order* order_ptr : order_list) {\n            total_dist_to_cell_pickup += manhattan_distance(office, order_ptr->pickup);\n        }\n        // Average distance = total distance / number of orders in cell\n        cell_scores.push_back({total_dist_to_cell_pickup / order_list.size(), cell_coord});\n    }\n\n    // Sort cells based on their average distance score (ascending)\n    std::sort(cell_scores.begin(), cell_scores.end());\n\n    // Pool of candidate orders to choose from. We aim for more than 50 initially to allow for better final selection.\n    std::vector<Order*> candidate_orders_pool; \n    std::set<int> added_order_ids; // Keep track of added orders to avoid duplicates\n\n    // Collect orders from the best cells first (lowest average distance to office)\n    for (const auto& cell_score_pair : cell_scores) {\n        std::pair<int, int> cell_coord = cell_score_pair.second;\n        if (cell_to_orders_map.count(cell_coord)) {\n            std::vector<Order*>& orders_in_cell = cell_to_orders_map[cell_coord];\n            // Sort orders within this cell by their internal travel distance (shortest first)\n            std::sort(orders_in_cell.begin(), orders_in_cell.end(), [](Order* a, Order* b) {\n                return a->internal_dist < b->internal_dist;\n            });\n            \n            // Add orders from this cell to the candidate pool if not already added\n            for (Order* order_ptr : orders_in_cell) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n        }\n        // Stop collecting if we have enough candidates (e.g., 100 to 150) for refinement\n        if (candidate_orders_pool.size() >= 150) break; \n    }\n\n    // If, for some reason, we still don't have enough candidates after processing all cells,\n    // fill up from any remaining orders not yet considered.\n    if (candidate_orders_pool.size() < 150) {\n        for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n            for (Order* order_ptr : order_list) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n             if (candidate_orders_pool.size() >= 150) break;\n        }\n    }\n    \n    // Sort the pool of candidates by a refined score: \n    // internal_dist + min(dist_to_office_pickup, dist_delivery_to_office).\n    // This score prioritizes orders that are short and/or have at least one endpoint near the office.\n    std::sort(candidate_orders_pool.begin(), candidate_orders_pool.end(), [](Order* a, Order* b) {\n        dist_t score_a = a->internal_dist + std::min(a->dist_to_office_pickup, a->dist_delivery_to_office);\n        dist_t score_b = b->internal_dist + std::min(b->dist_to_office_pickup, b->dist_delivery_to_office);\n        return score_a < score_b;\n    });\n\n    // Select the top 50 orders from the sorted candidate pool.\n    std::vector<int> selected_order_ids;\n    std::vector<Order*> selected_orders_ptr; // Pointers to the actual Order objects for selected orders\n    for (int i = 0; i < 50; ++i) {\n        selected_order_ids.push_back(candidate_orders_pool[i]->id);\n        selected_orders_ptr.push_back(candidate_orders_pool[i]);\n    }\n\n    // --- Route Optimization Heuristic ---\n    // 1. Construct a route greedily, ensuring pickup is always before delivery for any given order.\n    // 2. Apply 2-opt local search to improve the generated route.\n\n    std::vector<Point> route_points; // The sequence of points in the delivery route\n    // Map to quickly access selected order details by their ID\n    std::map<int, Order*> order_map; \n    // Track the visited status of pickups and completed deliveries for selected orders\n    std::map<int, bool> is_pickup_visited;\n    std::map<int, bool> is_delivery_done;\n    \n    // Populate data structures for selected orders\n    for (Order* order_ptr : selected_orders_ptr) {\n        order_map[order_ptr->id] = order_ptr;\n        is_pickup_visited[order_ptr->id] = false;\n        is_delivery_done[order_ptr->id] = false;\n    }\n\n    route_points.push_back(office); // Start the route at the office\n    Point current_location = office;\n    int orders_completed = 0; // Counter for the number of orders fully delivered\n\n    // Greedy construction of the route, ensuring precedence constraints\n    while (orders_completed < 50) {\n        std::vector<Candidate> candidates; // List of possible next points\n\n        // Consider all available pickup points\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_pickup_visited[order_id]) {\n                // Add pickup point as a candidate if its order hasn't had pickup visited yet\n                candidates.push_back({order_ptr->pickup, manhattan_distance(current_location, order_ptr->pickup), 0, order_id});\n            }\n        }\n\n        // Consider all available delivery points IF their pickup has already been visited\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_delivery_done[order_id] && is_pickup_visited[order_id]) {\n                // Add delivery point if its order hasn't been completed AND its pickup has been visited\n                candidates.push_back({order_ptr->delivery, manhattan_distance(current_location, order_ptr->delivery), 1, order_id});\n            }\n        }\n\n        // If no candidates are available, it implies a problem (e.g., deadlock or all tasks done).\n        // This break should ideally not be reached if orders_completed < 50 and we have 50 selected orders.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates by cost to find the cheapest next move\n        std::sort(candidates.begin(), candidates.end());\n        \n        // Select the best candidate (minimum cost)\n        Candidate best_candidate = candidates[0];\n        \n        // Add the chosen point to the route and update current location\n        route_points.push_back(best_candidate.p);\n        current_location = best_candidate.p;\n\n        // Update status based on the type of point visited\n        if (best_candidate.type == 0) { // It was a pickup\n            is_pickup_visited[best_candidate.order_id] = true;\n        } else { // It was a delivery\n            is_delivery_done[best_candidate.order_id] = true;\n            orders_completed++; // Increment count of fully delivered orders\n        }\n    }\n    \n    route_points.push_back(office); // End the route at the office\n\n    // Apply 2-opt heuristic to improve the constructed route.\n    // The start and end points are fixed as office, so 2-opt operates on the interior points.\n    // The `two_opt` function implementation handles indices correctly for this.\n    two_opt(route_points);\n\n    // --- Output ---\n    // Output the list of selected order IDs\n    std::cout << selected_order_ids.size() << std::endl;\n    for (int i = 0; i < selected_order_ids.size(); ++i) {\n        std::cout << selected_order_ids[i] << (i == selected_order_ids.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    // Output the sequence of points in the optimized route\n    std::cout << route_points.size() << std::endl;\n    for (int i = 0; i < route_points.size(); ++i) {\n        std::cout << route_points[i].x << \" \" << route_points[i].y << (i == route_points.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric> // For std::iota\n#include <algorithm> // For std::swap\n\n// Disjoint Set Union (DSU) data structure\n// Used to keep track of connected components.\nstruct DSU {\n    std::vector<int> parent;\n    std::vector<int> sz;\n\n    // Constructor: Initializes DSU for n elements.\n    // Each element is initially in its own set.\n    DSU(int n) {\n        parent.resize(n);\n        // Initialize each element to be its own parent.\n        // std::iota fills the range [begin, end) with sequentially increasing values, starting from value.\n        std::iota(parent.begin(), parent.end(), 0);\n        // Initialize the size of each set to 1.\n        sz.assign(n, 1);\n    }\n\n    // Finds the representative (root) of the set containing element i.\n    // Implements path compression: flattens the tree structure by making every node\n    // on the path from i to the root point directly to the root. This speeds up future find operations.\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n\n    // Unites the sets containing elements i and j.\n    // Returns true if the sets were different and successfully merged, false otherwise\n    // (i.e., if i and j were already in the same set).\n    // Implements union by size: attaches the root of the smaller tree to the root of the larger tree.\n    // This helps keep the tree heights small, improving the efficiency of find operations.\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            // If sizes are different, attach smaller tree to the root of the larger tree.\n            if (sz[root_i] < sz[root_j])\n                std::swap(root_i, root_j);\n            parent[root_j] = root_i;\n            sz[root_i] += sz[root_j];\n            return true; // Successfully merged two distinct sets\n        }\n        return false; // Elements were already in the same set\n    }\n};\n\n// Structure to store edge information: endpoints and calculated d_i\nstruct Edge {\n    int u, v;\n    long long d; // Rounded Euclidean distance\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // std::ios_base::sync_with_stdio(false) unties C++ streams from C stdio.\n    // std::cin.tie(NULL) unties cin from cout, so cin operations do not force a flush of cout.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // Number of vertices\n    int m; // Number of candidate edges\n    std::cin >> n >> m;\n\n    // Read vertex coordinates (x_i, y_i) for each vertex.\n    std::vector<std::pair<int, int>> coords(n);\n    for (int i = 0; i < n; ++i) {\n        std::cin >> coords[i].first >> coords[i].second;\n    }\n\n    // Store edge information: endpoints (u, v) and the calculated d_i for each of the M edges.\n    // We need to pre-calculate d_i because the actual length l_i is revealed later,\n    // but the edge endpoints and their base distance d_i are fixed.\n    std::vector<Edge> edges(m);\n    for (int i = 0; i < m; ++i) {\n        int u_node, v_node;\n        std::cin >> u_node >> v_node;\n        edges[i].u = u_node;\n        edges[i].v = v_node;\n\n        // Calculate the Euclidean distance between endpoints u_node and v_node.\n        // Use long double for intermediate calculations to maintain precision,\n        // especially for sqrt and squaring operations.\n        long double dx = static_cast<long double>(coords[u_node].first) - coords[v_node].first;\n        long double dy = static_cast<long double>(coords[u_node].second) - coords[v_node].second;\n        long double dist_sq = dx * dx + dy * dy;\n        long double dist = std::sqrt(dist_sq);\n        \n        // Round the distance to the nearest integer as per problem statement.\n        edges[i].d = static_cast<long long>(std::round(dist));\n    }\n\n    // Initialize the DSU structure for n vertices.\n    // This structure will track which vertices are connected by the edges we adopt.\n    DSU dsu(n);\n\n    // Process each of the M edges in the order they are revealed.\n    for (int i = 0; i < m; ++i) {\n        long long l_i; // The true edge length for the i-th edge, revealed now.\n        std::cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n\n        // The core strategy: \"Always-Connect\"\n        // We need to ensure the final graph is connected. The most straightforward way\n        // to ensure connectivity while greedily minimizing cost is to adopt an edge\n        // if and only if it connects two previously disconnected components.\n        // If an edge connects two vertices that are already in the same component,\n        // adopting it would create a cycle, increasing the total cost without improving\n        // connectivity. Therefore, we reject such edges.\n        // This strategy is guaranteed to produce a connected graph because:\n        // 1. The original graph is connected, meaning it's possible to connect all vertices.\n        // 2. We always adopt an edge that reduces the number of connected components.\n        // 3. This process continues until all vertices are in a single component.\n\n        if (dsu.find(u) != dsu.find(v)) {\n            // The endpoints u and v belong to different connected components.\n            // Adopting this edge is necessary to merge these components and progress towards full connectivity.\n            std::cout << 1 << std::endl; // Output '1' to adopt the edge.\n            dsu.unite(u, v); // Merge the components of u and v.\n        } else {\n            // The endpoints u and v are already in the same connected component.\n            // This edge is redundant for connectivity. Reject it to save cost.\n            std::cout << 0 << std::endl; // Output '0' to reject the edge.\n        }\n        // std::endl not only inserts a newline character but also flushes the output buffer.\n        // Flushing is required by the problem statement to ensure the judge receives\n        // our output for each step before providing the next input.\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\n// Structures\nstruct Pos {\n    int r, c;\n    // Equality operator for comparing positions\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n    // Less than operator for sorting and using in maps/sets\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n};\n\nstruct Pet {\n    int id;\n    Pos pos;\n    int type;\n};\n\nstruct Human {\n    int id;\n    Pos pos;\n};\n\n// Directions for movement (U, D, L, R)\n// Corresponding dr and dc values\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1}; // U, D, L, R\n// Corresponding characters for movement and blocking actions\nchar move_chars[] = {'U', 'D', 'L', 'R'};\nchar block_chars[] = {'u', 'd', 'l', 'r'};\n\n// --- Helper Functions ---\n\n// Check if a position is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < GRID_SIZE && c >= 0 && c < GRID_SIZE;\n}\n\n// Calculate Manhattan distance between two positions\nint manhattan_distance(Pos p1, Pos p2) {\n    return abs(p1.r - p2.r) + abs(p1.c - p2.c);\n}\n\n// Get character for human movement action (uppercase)\nchar get_direction_char_for_move(Pos from, Pos to) {\n    if (to.r < from.r) return 'U';\n    if (to.r > from.r) return 'D';\n    if (to.c < from.c) return 'L';\n    if (to.c > from.c) return 'R';\n    return '.'; // Should not happen for movement if positions differ\n}\n\n// Get character for human blocking action (lowercase)\nchar get_direction_char_for_block(Pos from, Pos to) {\n    if (to.r < from.r) return 'u';\n    if (to.r > from.r) return 'd';\n    if (to.c < from.c) return 'l';\n    if (to.c > from.c) return 'r';\n    return '.'; // Should not happen for blocking if positions differ\n}\n\n// Get target position from current position and direction character\nPos get_pos_from_dir_char(Pos from, char dir) {\n    Pos to = from;\n    if (dir == 'U' || dir == 'u') to.r--;\n    else if (dir == 'D' || dir == 'd') to.r++;\n    else if (dir == 'L' || dir == 'l') to.c--;\n    else if (dir == 'R' || dir == 'r') to.c++;\n    return to;\n}\n\n// Get precomputed minimum Manhattan distance from a square (r, c) to any pet.\n// Uses a flattened 1D array for quick lookup.\nint get_min_dist_to_pet(int r, int c, const vector<int>& min_pet_dists_flat) {\n    return min_pet_dists_flat[r * GRID_SIZE + c];\n}\n\n// BFS to find reachable squares from a starting position.\n// This function is primarily for scoring calculation after all turns.\npair<int, vector<Pos>> get_reachable_area(Pos start_pos, const vector<vector<bool>>& is_impassable_grid) {\n    vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n    queue<Pos> q;\n    vector<Pos> reachable_squares;\n\n    // If start position is invalid or impassable, return empty area.\n    if (!is_valid(start_pos.r, start_pos.c) || is_impassable_grid[start_pos.r][start_pos.c]) {\n        return {0, {}};\n    }\n\n    q.push(start_pos);\n    visited[start_pos.r][start_pos.c] = true;\n    reachable_squares.push_back(start_pos);\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        // Explore adjacent squares\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n\n            // If adjacent square is valid, not impassable, and not visited, add to queue.\n            if (is_valid(nr, nc) && !is_impassable_grid[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                Pos next_pos = {nr, nc};\n                q.push(next_pos);\n                reachable_squares.push_back(next_pos);\n            }\n        }\n    }\n    return {reachable_squares.size(), reachable_squares};\n}\n\n// --- Global Variables ---\nint N_pets, M_humans;\nvector<Pet> pets_state;\nvector<Human> humans_state;\n// Grid state: true if impassable, false if passable.\nvector<vector<bool>> is_impassable_grid(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n\n// Main logic for the contest problem\nvoid solve() {\n    // Read initial state: pet positions, types, and human positions.\n    cin >> N_pets;\n    pets_state.resize(N_pets);\n    for (int i = 0; i < N_pets; ++i) {\n        pets_state[i].id = i;\n        cin >> pets_state[i].pos.r >> pets_state[i].pos.c >> pets_state[i].type;\n        pets_state[i].pos.r--; pets_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n    cin >> M_humans;\n    humans_state.resize(M_humans);\n    for (int i = 0; i < M_humans; ++i) {\n        humans_state[i].id = i;\n        cin >> humans_state[i].pos.r >> humans_state[i].pos.c;\n        humans_state[i].pos.r--; humans_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n\n    // Game loop for each turn\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        \n        // --- Precomputation for Human Decision Making ---\n        // Calculate minimum distance from every square to any pet.\n        // This is crucial for the human strategy of staying away from pets.\n        vector<int> min_pet_dists_flat(GRID_SIZE * GRID_SIZE);\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                min_pet_dists_flat[r * GRID_SIZE + c] = GRID_SIZE * 2; // Initialize with a large value\n                for (const auto& pet : pets_state) {\n                    min_pet_dists_flat[r * GRID_SIZE + c] = min(min_pet_dists_flat[r * GRID_SIZE + c], manhattan_distance({r, c}, pet.pos));\n                }\n            }\n        }\n\n        // Identify squares that are potentially blockable by humans.\n        // A square is blockable if it's within bounds, not impassable from previous turns,\n        // not occupied by any human or pet at the start of this turn, and not adjacent to any pet.\n        vector<Pos> blockable_squares;\n        vector<bool> is_occupied_at_start(GRID_SIZE * GRID_SIZE, false); // Mark occupied squares for quick checks\n        for (const auto& p : pets_state) is_occupied_at_start[p.pos.r * GRID_SIZE + p.pos.c] = true;\n        for (const auto& h : humans_state) is_occupied_at_start[h.pos.r * GRID_SIZE + h.pos.c] = true;\n\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                // Rule: Cannot block if adjacent to a pet. Minimum distance >= 2.\n                if (!is_impassable_grid[r][c] && !is_occupied_at_start[r * GRID_SIZE + c] && get_min_dist_to_pet(r, c, min_pet_dists_flat) >= 2) {\n                    blockable_squares.push_back({r, c});\n                }\n            }\n        }\n\n        // For each human, store their best potential blocking and moving action.\n        // Format: {score, position}. Initial score is -1.0 indicating no valid option found.\n        vector<pair<double, Pos>> best_block_options(M_humans, {-1.0, {-1, -1}}); \n        vector<pair<double, Pos>> best_move_options(M_humans, {-1.0, {-1, -1}});  \n\n        // --- Evaluate Blocking Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_block_score = -1.0;\n            Pos best_block_pos = {-1, -1};\n\n            for (const auto& sq : blockable_squares) {\n                double current_block_score = 0;\n                // Heuristic: prioritize blocking squares far from pets\n                current_block_score += (double)get_min_dist_to_pet(sq.r, sq.c, min_pet_dists_flat) * 100.0;\n                \n                // Heuristic: prefer extending existing walls (adjacent to already impassable squares)\n                bool adjacent_to_impassable = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = sq.r + dr[d];\n                    int nc = sq.c + dc[d];\n                    if(is_valid(nr, nc) && is_impassable_grid[nr][nc]) {\n                        adjacent_to_impassable = true;\n                        break;\n                    }\n                }\n                if (adjacent_to_impassable) {\n                    current_block_score += 50.0;\n                }\n                \n                // Heuristic: penalize blocking squares far from human's current position (encourages moving towards blocking target)\n                current_block_score -= manhattan_distance(humans_state[i].pos, sq);\n\n                // Update best option if current score is better\n                if (current_block_score > max_block_score) {\n                    max_block_score = current_block_score;\n                    best_block_pos = sq;\n                } else if (abs(current_block_score - max_block_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                    if (sq.r < best_block_pos.r || (sq.r == best_block_pos.r && sq.c < best_block_pos.c)) {\n                        best_block_pos = sq;\n                    }\n                }\n            }\n            // Store the best block option found for human i\n            if (best_block_pos.r != -1) {\n                best_block_options[i] = {max_block_score, best_block_pos};\n            }\n        }\n\n        // --- Evaluate Movement Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_move_score = -1.0;\n            Pos best_move_pos = {-1, -1};\n\n            // Check all 4 adjacent squares for potential movement\n            for (int d = 0; d < 4; ++d) {\n                int nr = humans_state[i].pos.r + dr[d];\n                int nc = humans_state[i].pos.c + dc[d];\n                Pos next_pos = {nr, nc};\n\n                // Can only move to a valid, passable square\n                if (is_valid(nr, nc) && !is_impassable_grid[nr][nc]) {\n                    // Cannot move to a square occupied by another human at the start of the turn\n                    if (!is_occupied_at_start[nr * GRID_SIZE + nc]) { \n                        double current_move_score = 0;\n                        // Heuristic: prefer moving to squares far from pets\n                        current_move_score += (double)get_min_dist_to_pet(nr, nc, min_pet_dists_flat) * 50.0;\n\n                        // Strong incentive to move to a square that this human plans to block\n                        if (best_block_options[i].second == next_pos) {\n                            current_move_score += 100.0;\n                        }\n                        \n                        // Update best option if current score is better\n                        if (current_move_score > max_move_score) {\n                            max_move_score = current_move_score;\n                            best_move_pos = next_pos;\n                        } else if (abs(current_move_score - max_move_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                            if (next_pos.r < best_move_pos.r || (next_pos.r == best_move_pos.r && next_pos.c < best_move_pos.c)) {\n                                best_move_pos = next_pos;\n                            }\n                        }\n                    }\n                }\n            }\n            // Store the best move option found for human i\n            if (best_move_pos.r != -1) {\n                best_move_options[i] = {max_move_score, best_move_pos};\n            }\n        }\n\n        // --- Conflict Resolution and Final Action Assignment ---\n        // This phase determines which actions are actually performed, resolving conflicts.\n        string human_actions_str(M_humans, '.'); // Stores the output action char for each human\n        vector<Pos> squares_to_move_to_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to move\n        vector<Pos> planned_blocks_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to block\n\n        // Structure to hold all potential actions (block or move) for sorting and conflict resolution\n        struct ActionChoice {\n            int human_id;\n            Pos target_pos;\n            double score;\n            bool is_block_action; // true if this choice is to block, false if to move\n\n            // Custom comparator for sorting: higher score first, then lower human_id for tie-breaking\n            bool operator<(const ActionChoice& other) const {\n                if (abs(score - other.score) > 1e-9) return score > other.score; // Sort by score descending\n                return human_id < other.human_id; // Sort by human_id ascending for ties\n            }\n        };\n        vector<ActionChoice> choices;\n\n        // Populate the list of all potential actions\n        for (int i = 0; i < M_humans; ++i) {\n            if (best_block_options[i].first > -1.0) { // If a block option was found\n                choices.push_back({i, best_block_options[i].second, best_block_options[i].first, true});\n            }\n            if (best_move_options[i].first > -1.0) { // If a move option was found\n                choices.push_back({i, best_move_options[i].second, best_move_options[i].first, false});\n            }\n        }\n        // Sort all potential actions based on score and human_id\n        sort(choices.begin(), choices.end());\n\n        vector<bool> human_assigned_action(M_humans, false); // Track if a human has been assigned an action\n\n        // Process sorted choices to assign actions and resolve conflicts\n        for (const auto& choice : choices) {\n            int hid = choice.human_id;\n            Pos target_pos = choice.target_pos;\n            bool is_block = choice.is_block_action;\n\n            if (human_assigned_action[hid]) continue; // Human already has an assigned action\n\n            if (is_block) {\n                // --- Check if this block action is still possible ---\n                bool can_block = true;\n                // 1. Cannot block if target square will be occupied by a moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (squares_to_move_to_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n                // 2. Cannot block if target square is permanently impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) { // If it was impassable before this turn\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) { // And it's currently empty\n                         can_block = false; // Cannot make an already blocked and empty square impassable.\n                     }\n                }\n                // 3. Cannot block if another human has already planned to block this same square.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n\n                // If the block action is valid, assign it.\n                if (can_block) {\n                    human_actions_str[hid] = get_direction_char_for_block(humans_state[hid].pos, target_pos);\n                    planned_blocks_this_turn[hid] = target_pos; // Record this planned block\n                    human_assigned_action[hid] = true;\n                }\n                // If block failed, this human might try their best move action later if available.\n            } else { // This choice is a movement action\n                // --- Check if this move action is still possible ---\n                bool can_move = true;\n                // 1. Cannot move to a square that is already impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) {\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) {\n                         can_move = false;\n                     }\n                }\n                // 2. Cannot move to a square already claimed by another moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (i != hid && squares_to_move_to_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n                // 3. Cannot move to a square that another human plans to block this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n\n                // If the move action is valid, assign it.\n                if (can_move) {\n                    human_actions_str[hid] = get_direction_char_for_move(humans_state[hid].pos, target_pos);\n                    squares_to_move_to_this_turn[hid] = target_pos; // Record this planned move\n                    human_assigned_action[hid] = true;\n                }\n                // If move failed, this human might have a block action as their next best choice.\n            }\n        }\n        \n        // --- Fallback: Handle humans who couldn't get their preferred action or any action ---\n        // If a human's top choice (block or move) was taken or invalid, they might try their second best,\n        // or default to blocking if possible, or default to staying put.\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                // Try to perform the best block action if it failed initially\n                if (best_block_options[i].first > -1.0) {\n                     Pos block_target = best_block_options[i].second;\n                     bool can_block_fallback = true;\n                     // Check availability similar to above\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (squares_to_move_to_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     if (is_impassable_grid[block_target.r][block_target.c]) {\n                          if (!is_occupied_at_start[block_target.r * GRID_SIZE + block_target.c]) { can_block_fallback = false; }\n                     }\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (planned_blocks_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     \n                     if (can_block_fallback) {\n                          human_actions_str[i] = get_direction_char_for_block(humans_state[i].pos, block_target);\n                          planned_blocks_this_turn[i] = block_target;\n                          human_assigned_action[i] = true;\n                     }\n                }\n                // If blocking still not possible, try to perform the best move action if it failed initially\n                if (!human_assigned_action[i] && best_move_options[i].first > -1.0) {\n                    Pos move_target = best_move_options[i].second;\n                    bool can_move_fallback = true;\n                    // Check availability similar to above\n                    if (is_impassable_grid[move_target.r][move_target.c]) {\n                         if (!is_occupied_at_start[move_target.r * GRID_SIZE + move_target.c]) { can_move_fallback = false; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (h_idx != i && squares_to_move_to_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (planned_blocks_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    \n                    if (can_move_fallback) {\n                         human_actions_str[i] = get_direction_char_for_move(humans_state[i].pos, move_target);\n                         squares_to_move_to_this_turn[i] = move_target;\n                         human_assigned_action[i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Final fallback: If a human still has no action assigned, they do nothing (stay put).\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                human_actions_str[i] = '.';\n            }\n        }\n\n        // --- Output Human Actions and Flush ---\n        cout << human_actions_str << endl;\n        cout << flush; // Essential to flush output for interactive problems\n\n        // --- Read Pet Movements and Update Game State ---\n        vector<string> current_pet_moves(N_pets);\n        for (int i = 0; i < N_pets; ++i) {\n            cin >> current_pet_moves[i];\n        }\n\n        // Update Pet Positions based on input movements\n        for (int i = 0; i < N_pets; ++i) {\n            Pos current_pet_pos = pets_state[i].pos; // Current position at start of turn\n            for (char move : current_pet_moves[i]) { // Process each move character in the string\n                if (move == '.') continue; // No move\n\n                Pos next_pet_pos = current_pet_pos;\n                if (move == 'U') next_pet_pos.r--;\n                else if (move == 'D') next_pet_pos.r++;\n                else if (move == 'L') next_pet_pos.c--;\n                else if (move == 'R') next_pet_pos.c++;\n                \n                // Determine if the target square for the pet is passable.\n                // A square is passable for a pet if it's within grid bounds, AND\n                // it's NOT newly blocked by human action THIS turn, AND\n                // it's NOT permanently blocked (from previous turns) AND currently empty.\n                \n                bool target_is_newly_impassable = false; // Blocked by humans THIS turn\n                for(const auto& block_pos : planned_blocks_this_turn) {\n                    if (block_pos == next_pet_pos) {\n                        target_is_newly_impassable = true;\n                        break;\n                    }\n                }\n                \n                bool is_permanently_blocked_and_empty = false; // Blocked from PREVIOUS turns and currently empty\n                if (is_impassable_grid[next_pet_pos.r][next_pet_pos.c]) { // If it was impassable before this turn\n                    if (!is_occupied_at_start[next_pet_pos.r * GRID_SIZE + next_pet_pos.c]) { // And it's currently empty\n                        is_permanently_blocked_and_empty = true;\n                    }\n                }\n\n                // If the target square is valid and passable for the pet, move the pet.\n                if (is_valid(next_pet_pos.r, next_pet_pos.c) && !target_is_newly_impassable && !is_permanently_blocked_and_empty) {\n                    current_pet_pos = next_pet_pos; // Pet successfully moves\n                } else {\n                    // If move is not possible, pet stays put for this move.\n                    // 'current_pet_pos' remains unchanged, and the next move in the string will be attempted from this position.\n                }\n            }\n            pets_state[i].pos = current_pet_pos; // Update pet's final position for the turn\n        }\n\n        // Update Grid State: Apply the squares that humans planned to block.\n        for (int i = 0; i < M_humans; ++i) {\n            if (planned_blocks_this_turn[i].r != -1) { // If human i planned to block a square\n                is_impassable_grid[planned_blocks_this_turn[i].r][planned_blocks_this_turn[i].c] = true;\n            }\n        }\n\n        // Update Human Positions based on their assigned move actions.\n        for (int i = 0; i < M_humans; ++i) {\n            if (human_actions_str[i] != '.' && human_actions_str[i] != 'u' && human_actions_str[i] != 'd' && human_actions_str[i] != 'l' && human_actions_str[i] != 'r') {\n                // This is a move action (uppercase char)\n                humans_state[i].pos = get_pos_from_dir_char(humans_state[i].pos, human_actions_str[i]);\n            }\n        }\n    }\n\n    // --- Scoring Calculation (for local testing/debugging, not submitted) ---\n    /*\n    double total_satisfaction = 0;\n    for (int i = 0; i < M_humans; ++i) {\n        auto [reachable_count, reachable_squares] = get_reachable_area(humans_state[i].pos, is_impassable_grid);\n        int caught_pets = 0;\n        for (const auto& pet : pets_state) {\n            for (const auto& sq : reachable_squares) {\n                if (pet.pos == sq) {\n                    caught_pets++;\n                    break;\n                }\n            }\n        }\n        double s_i = (double)reachable_count / 900.0 * pow(0.5, caught_pets);\n        total_satisfaction += s_i;\n    }\n    double final_score = round(1e8 * total_satisfaction / M_humans);\n    cerr << \"Final Score (approx): \" << fixed << setprecision(10) << final_score << endl;\n    */\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main game logic\n\n    return 0; // Program finished successfully\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Structure to store parent information for path reconstruction.\n// It records the previous grid cell (r, c), the previous step count (k),\n// and the move character that led to the current state.\nstruct ParentInfo {\n    int r, c, k; // Previous grid position and step count.\n    char move;   // The move character that was chosen to transition from (r,c,k) to the current state.\n};\n\n// Structure representing a state in the Dijkstra search.\n// It includes the expected actual time elapsed, current grid position (r, c),\n// and the number of moves (k) that have been decided/processed for the path.\nstruct State {\n    double expected_time;\n    int r, c, k; \n\n    // Custom comparator for the priority queue to implement a min-priority queue.\n    // States with lower expected_time have higher priority.\n    bool operator>(const State& other) const {\n        return expected_time > other.expected_time;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj, ti, tj; // Start and target coordinates.\n    double p;           // Probability of forgetting a move.\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // Read horizontal wall information. h_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i, j+1), 0 otherwise. Size: 20x19.\n    vector<vector<int>> h_walls(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            h_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    // Read vertical wall information. v_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i+1, j), 0 otherwise. Size: 19x20.\n    vector<vector<int>> v_walls(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            v_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    const int MAX_L = 200; // Maximum allowed length of the output string.\n    const double INF = numeric_limits<double>::max(); // Represents infinity for unreachable states.\n\n    // dist[r][c][k]: Stores the minimum expected actual time to reach grid cell (r, c)\n    // after k moves have been decided/processed for the path.\n    // k ranges from 0 to MAX_L.\n    vector<vector<vector<double>>> dist(20, vector<vector<double>>(20, vector<double>(MAX_L + 1, INF)));\n\n    // parent stores ParentInfo to reconstruct the path.\n    vector<vector<vector<ParentInfo>>> parent(20, vector<vector<ParentInfo>>(20, vector<ParentInfo>(MAX_L + 1, {-1, -1, -1, ' '})));\n\n    // Priority queue for Dijkstra's algorithm.\n    priority_queue<State, vector<State>, greater<State>> pq;\n\n    // Initial state: At home (si, sj), 0 moves processed, with an expected time of 0.0.\n    dist[si][sj][0] = 0.0;\n    pq.push({0.0, si, sj, 0});\n\n    // Define movement directions and corresponding characters for 'U', 'D', 'L', 'R'.\n    int dr[] = {-1, 1, 0, 0}; // Delta row for U, D, L, R\n    int dc[] = {0, 0, -1, 1}; // Delta column for U, D, L, R\n    char moves[] = {'U', 'D', 'L', 'R'};\n\n    // Variables to track the best path found to the office.\n    // min_expected_arrival_time stores the minimum expected time to reach the office.\n    // best_k stores the number of moves processed when the office was reached with min_expected_arrival_time.\n    double min_expected_arrival_time = INF;\n    int best_k = -1; \n\n    // Dijkstra's algorithm main loop.\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        double t = current.expected_time; // Expected time to reach this state.\n        int r = current.r;                 // Current row.\n        int c = current.c;                 // Current column.\n        int k = current.k;                 // Number of moves processed so far.\n\n        // If we found a better path to this state already, skip processing.\n        if (t > dist[r][c][k]) {\n            continue;\n        }\n\n        // Check if the current cell is the office.\n        if (r == ti && c == tj) {\n            // If we reached the office and this path is better than the best found so far, update.\n            if (t < min_expected_arrival_time) {\n                min_expected_arrival_time = t;\n                best_k = k; // Record the number of moves processed for this best path.\n            }\n            // Note: We don't 'continue' here because even if we reached the office,\n            // this state might be part of an even better path to the office IF it's reached earlier in terms of actual moves.\n            // However, since the goal is minimizing expected time, and the arrival time `t` is recorded,\n            // any further exploration from `(r,c,k)` for THIS specific path's time `t` is not useful for finding a *shorter* path to the office *via this specific branch*.\n            // But other states in PQ might offer a path with a lower expected time.\n            // The check `if (k == MAX_L)` below handles the path length limit.\n        }\n        \n        // If we have already processed MAX_L moves, we cannot extend this path further.\n        if (k == MAX_L) {\n            continue;\n        }\n\n        // Explore transitions for the next move (the (k+1)-th move in the sequence).\n        // For each of the 4 possible directions ('U', 'D', 'L', 'R'):\n        for (int i = 0; i < 4; ++i) {\n            char move_char = moves[i];\n            int nr_attempt = r, nc_attempt = c; // Initialize potential next position to current.\n\n            // Determine the target cell if the move is successful, considering grid boundaries and walls.\n            bool wall_collision = false; // True if move is blocked by boundary or wall.\n\n            if (move_char == 'U') {\n                // Check for boundary (r=0) or vertical wall v_walls[r-1][c] (between (r-1,c) and (r,c)).\n                if (r > 0 && !v_walls[r - 1][c]) { nr_attempt = r - 1; } else { wall_collision = true; }\n            } else if (move_char == 'D') {\n                // Check for boundary (r=19) or vertical wall v_walls[r][c] (between (r,c) and (r+1,c)).\n                if (r < 19 && !v_walls[r][c]) { nr_attempt = r + 1; } else { wall_collision = true; }\n            } else if (move_char == 'L') {\n                // Check for boundary (c=0) or horizontal wall h_walls[r][c-1] (between (r,c-1) and (r,c)).\n                if (c > 0 && !h_walls[r][c - 1]) { nc_attempt = c - 1; } else { wall_collision = true; }\n            } else if (move_char == 'R') {\n                // Check for boundary (c=19) or horizontal wall h_walls[r][c] (between (r,c) and (r,c+1)).\n                if (c < 19 && !h_walls[r][c]) { nc_attempt = c + 1; } else { wall_collision = true; }\n            }\n\n            // The actual time advances by 1 turn for this step, regardless of success or failure.\n            double next_expected_time = t + 1.0;\n            int next_k = k + 1; // One more move is now processed.\n\n            // Case 1: Move is forgotten (probability p).\n            // Takahashi stays at the current cell (r, c). The next state is (r, c) after k+1 moves.\n            // If the path to this state (r, c, next_k) via this route is better than previously found paths:\n            if (dist[r][c][next_k] > next_expected_time) {\n                dist[r][c][next_k] = next_expected_time;\n                // Record the parent information: we came from (r, c) at step k, and chose 'move_char'\n                // to generate this state at step k+1.\n                parent[r][c][next_k] = {r, c, k, move_char}; \n                pq.push({next_expected_time, r, c, next_k});\n            }\n\n            // Case 2: Move is executed (probability 1-p).\n            // Takahashi moves to (nr_attempt, nc_attempt). The next state is (nr_attempt, nc_attempt) after k+1 moves.\n            // If the path to this state (nr_attempt, nc_attempt, next_k) via this route is better:\n            if (dist[nr_attempt][nc_attempt][next_k] > next_expected_time) {\n                dist[nr_attempt][nc_attempt][next_k] = next_expected_time;\n                // Record parent information: came from (r, c) at step k, chose 'move_char'.\n                parent[nr_attempt][nc_attempt][next_k] = {r, c, k, move_char};\n                pq.push({next_expected_time, nr_attempt, nc_attempt, next_k});\n            }\n        }\n    }\n\n    // Path reconstruction.\n    string path = \"\";\n    if (best_k != -1) { // If the office was reached at least once within MAX_L moves.\n        int curr_r = ti;\n        int curr_c = tj;\n        int curr_k = best_k;\n\n        // Trace back from the office-reaching state to the start state (0 moves processed).\n        // The loop terminates when curr_k becomes 0.\n        while (curr_k > 0) {\n            ParentInfo p_info = parent[curr_r][curr_c][curr_k];\n            // Append the move character to the path string. This character is the (curr_k)-th move in the sequence.\n            path += p_info.move;\n            // Move to the parent state.\n            curr_r = p_info.r;\n            curr_c = p_info.c;\n            curr_k = p_info.k;\n        }\n        // The path string is built in reverse order, so reverse it.\n        reverse(path.begin(), path.end());\n    }\n    // If best_k remains -1, it means the office was not reached within MAX_L moves with a finite expected time.\n    // According to problem statement, failure leads to score 0. An empty path might be output, or a default path.\n    // However, given problem guarantees and structure, best_k should be set if office is reachable.\n    // For contest robustness, if path is empty, a simple BFS path could be a fallback, but Dijkstra should yield the optimal strategy.\n    \n    cout << path << endl; // Output the constructed commuting route.\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <random>\n#include <chrono> // For seeding the random number generator\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_DIRECTIONS = 4;\n\n// Directions: 0:Left, 1:Up, 2:Right, 3:Down\n// di[d] is the row change for direction d\n// dj[d] is the column change for direction d\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Base connections for the 8 tile types\n// base_connections[tile_type][entry_direction] = exit_direction\n// -1 means no connection\n// This table is derived from the problem statement's 'to' array.\nint base_connections[8][NUM_DIRECTIONS] = {\n    {1, 0, -1, -1}, // Type 0: L-U / U-L (Curve)\n    {3, -1, -1, 0}, // Type 1: L-D / D-L (Curve)\n    {-1, -1, 3, 2}, // Type 2: R-D / D-R (Curve)\n    {-1, 2, 1, -1}, // Type 3: R-U / U-R (Curve)\n    {1, 2, 3, 0},   // Type 4: Square path L->U->R->D->L\n    {3, 2, 1, 0},   // Type 5: S-curve like L->D, U->R, R->U, D->L (as per problem's to table)\n    {2, -1, 0, -1}, // Type 6: Horizontal L<->R (Straight)\n    {-1, 3, -1, 1}  // Type 7: Vertical U<->D (Straight)\n};\n\n// Function to map initial tile type and rotation count to effective tile type\n// The problem states how rotation changes the tile type for different groups.\nint map_type(int initial_type, int rotation) {\n    if (initial_type >= 0 && initial_type <= 3) { // Group 1: {0,1,2,3} rotate cyclically\n        return (initial_type + rotation) % 4;\n    } else if (initial_type == 4) { // Group 2a: {4,5} for initial type 4\n        // Rotation 0,2 -> type 4; Rotation 1,3 -> type 5\n        return 4 + (rotation % 2);\n    } else if (initial_type == 5) { // Group 2b: {4,5} for initial type 5\n        // Rotation 0,2 -> type 5; Rotation 1,3 -> type 4\n        return 4 + ((rotation + 1) % 2);\n    } else if (initial_type == 6) { // Group 3a: {6,7} for initial type 6\n        // Rotation 0,2 -> type 6; Rotation 1,3 -> type 7\n        return 6 + (rotation % 2);\n    } else if (initial_type == 7) { // Group 3b: {6,7} for initial type 7\n        // Rotation 0,2 -> type 7; Rotation 1,3 -> type 6\n        return 6 + ((rotation + 1) % 2);\n    }\n    return -1; // Should not happen\n}\n\n// Global variables to store the current configuration and support loop detection\nvector<vector<int>> base_type_input_grid; // Stores the initial tile type for each cell\nvector<vector<int>> current_rotations_grid; // Stores rotation count (0-3) for each cell\nvector<vector<vector<int>>> effective_to_grid; // Stores the connections for the current configuration of all cells\nvector<vector<vector<bool>>> visited_edge; // To mark edges (cell, entry_direction) that have been part of a found loop or dead end path\nvector<int> loop_lengths; // Stores lengths of all detected loop lines\n\n// Function to calculate the connections for a cell (r, c) based on its base type and current rotation\nvector<int> get_cell_connections(int r, int c) {\n    int initial_type = base_type_input_grid[r][c];\n    int rotation = current_rotations_grid[r][c];\n    int effective_type = map_type(initial_type, rotation);\n    // Return a copy of the connection rules for the effective tile type\n    return vector<int>(base_connections[effective_type], base_connections[effective_type] + NUM_DIRECTIONS);\n}\n\n// Function to find all loop lines and calculate the score (L1 * L2)\n// This function is called repeatedly by the local search heuristic.\nlong long evaluate_all_loops() {\n    // 1. Populate the effective_to_grid based on current rotations\n    effective_to_grid.assign(GRID_SIZE, vector<vector<int>>(GRID_SIZE, vector<int>(NUM_DIRECTIONS)));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            effective_to_grid[i][j] = get_cell_connections(i, j);\n        }\n    }\n\n    // 2. Find all loops using Depth First Search\n    loop_lengths.clear();\n    // visited_edge[i][j][d_in] marks if the edge entering cell (i,j) from direction d_in has been visited globally.\n    // This ensures each directed edge is explored at most once across all DFS traversals, making loop detection efficient.\n    visited_edge.assign(GRID_SIZE, vector<vector<bool>>(GRID_SIZE, vector<bool>(NUM_DIRECTIONS, false)));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            for (int d_in = 0; d_in < NUM_DIRECTIONS; ++d_in) {\n                // If this edge has not been visited yet, start a new DFS traversal\n                if (!visited_edge[i][j][d_in]) {\n                    vector<tuple<int, int, int>> current_path; // Stores the sequence of (row, col, entry_direction) visited in this DFS\n                    map<tuple<int, int, int>, int> visited_in_current_dfs; // Maps state to the step index in current_path for cycle detection\n                    \n                    int cur_i = i, cur_j = j, cur_d_in = d_in;\n                    int step = 0;\n\n                    while (true) {\n                        // Check for out of bounds\n                        if (cur_i < 0 || cur_i >= GRID_SIZE || cur_j < 0 || cur_j >= GRID_SIZE) {\n                            break; // Path broken (out of bounds)\n                        }\n\n                        auto state = make_tuple(cur_i, cur_j, cur_d_in);\n                        \n                        // Check for cycle\n                        if (visited_in_current_dfs.count(state)) {\n                            int cycle_start_step = visited_in_current_dfs[state];\n                            int loop_len = step - cycle_start_step;\n                            \n                            // Mark all edges in the found cycle as visited globally\n                            for (int k = cycle_start_step; k < current_path.size(); ++k) {\n                                auto [pi, pj, pd_in] = current_path[k];\n                                visited_edge[pi][pj][pd_in] = true;\n                            }\n                            loop_lengths.push_back(loop_len);\n                            break; // Found a loop, stop this DFS traversal\n                        }\n\n                        // Mark current state as visited in this DFS and add to path\n                        visited_in_current_dfs[state] = step;\n                        current_path.push_back(state);\n\n                        // Determine next tile and direction\n                        int d_out = effective_to_grid[cur_i][cur_j][cur_d_in];\n                        if (d_out == -1) {\n                            break; // Path broken (tile has no exit in this direction)\n                        }\n\n                        cur_i += di[d_out];\n                        cur_j += dj[d_out];\n                        cur_d_in = (d_out + 2) % 4; // The entry direction to the next tile is opposite of the exit direction from current tile\n                        step++;\n                    }\n                    \n                    // Mark all edges in the path explored by this DFS as globally visited.\n                    // This prevents re-exploring dead-end paths or segments that didn't form a cycle.\n                    for(const auto& path_state : current_path) {\n                        auto [pi, pj, pd_in] = path_state;\n                        visited_edge[pi][pj][pd_in] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 3. Calculate the score: L1 * L2\n    sort(loop_lengths.rbegin(), loop_lengths.rend()); // Sort lengths in descending order\n\n    if (loop_lengths.size() < 2) {\n        return 0; // Score is 0 if less than two loop lines are found\n    }\n    // Use long long for score to prevent overflow\n    return (long long)loop_lengths[0] * loop_lengths[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input and store base tile types\n    base_type_input_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            base_type_input_grid[i][j] = row[j] - '0';\n        }\n    }\n\n    // Initialize rotations: start with all tiles at 0 rotation.\n    // This is a common starting point for heuristic search.\n    current_rotations_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0)); \n\n    long long best_score = 0;\n    vector<vector<int>> best_rotations = current_rotations_grid;\n\n    // Calculate initial score for the all-zero rotation configuration\n    best_score = evaluate_all_loops();\n\n    // --- Randomized Iterative Improvement (Hill Climbing Variant) ---\n    // Use a Mersenne Twister engine for good random number generation.\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> cell_dist(0, GRID_SIZE - 1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n\n    // Number of iterations for the local search. This value is a heuristic tuning parameter.\n    // More iterations generally yield better results but increase computation time.\n    int num_iterations = 100000; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        // Pick a random cell (r, c) to potentially change its rotation\n        int r = cell_dist(rng);\n        int c = cell_dist(rng);\n        int original_rotation = current_rotations_grid[r][c];\n\n        // Explore all 4 possible rotations for the chosen cell (r, c).\n        // For each, evaluate the total score. Keep track of the rotation that yields the maximum score locally.\n        long long max_local_score = -1; // Initialize with a value lower than any possible score\n        int best_local_r = original_rotation; // Default to keeping the original rotation if no improvement found\n\n        for (int test_r = 0; test_r < 4; ++test_r) {\n            current_rotations_grid[r][c] = test_r; // Temporarily set this rotation\n            long long score = evaluate_all_loops(); // Evaluate the score for this configuration\n            \n            if (score > max_local_score) {\n                max_local_score = score;\n                best_local_r = test_r;\n            }\n        }\n        \n        // After trying all 4 rotations, commit the best one found for this cell (r, c).\n        // This is a greedy step: always move to a state that improves the local score.\n        current_rotations_grid[r][c] = best_local_r;\n\n        // Update the global best score and configuration if the current configuration is better\n        if (max_local_score > best_score) {\n            best_score = max_local_score;\n            best_rotations = current_rotations_grid; // Save the rotations that achieved this best score\n        }\n    }\n\n    // Output the resulting rotations as a single string of 900 digits.\n    string result_string = \"\";\n    result_string.reserve(GRID_SIZE * GRID_SIZE); // Reserve space for efficiency\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            result_string += to_string(best_rotations[i][j]);\n        }\n    }\n    cout << result_string << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional> // for std::greater\n\nusing namespace std;\n\nint N;\nint T_limit;\nvector<vector<int>> initial_board_grid;\npair<int, int> initial_empty_pos;\n\n// Target configuration: canonical grid graph with empty at (N-1, N-1)\nvector<vector<int>> canonical_board_grid;\n\n// For state representation and visited set\nusing Board = vector<vector<int>>;\nusing StateKey = vector<int>; // Flattened board\n\n// Stores minimum cost (number of moves) and the path to reach a board state.\n// Key: flattened board configuration.\nmap<StateKey, pair<int, string>> visited;\n\n// Movement directions: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\nchar move_chars[] = {'U', 'D', 'L', 'R'};\n\n// --- Heuristic function ---\n// Calculates the Manhattan distance of the empty square from the target position (N-1, N-1).\n// This is an admissible heuristic for sliding tile puzzles.\nint calculate_heuristic(int r, int c) {\n    return abs(r - (N - 1)) + abs(c - (N - 1));\n}\n\n// --- Board to StateKey conversion ---\n// Converts the 2D board representation to a 1D vector for use as a map key.\nStateKey board_to_key(const Board& board) {\n    StateKey key;\n    key.reserve(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            key.push_back(board[r][c]);\n        }\n    }\n    return key;\n}\n\n// --- Custom State struct for Priority Queue ---\n// Represents a state in the search: current board, empty square position, cost (moves), and path.\nstruct SearchState {\n    Board board;\n    int empty_r, empty_c;\n    int cost; // g_cost: number of moves from initial state\n    string path;\n\n    // Operator overload for priority_queue to prioritize states with lower f_cost (g_cost + h_cost).\n    // If f_costs are equal, prioritize states with lower actual cost (g_cost).\n    bool operator>(const SearchState& other) const {\n        int h_self = calculate_heuristic(empty_r, empty_c);\n        int h_other = calculate_heuristic(other.empty_r, other.empty_c);\n        \n        // Primary sort by f_cost (g + h)\n        if ((cost + h_self) != (other.cost + h_other)) {\n            return (cost + h_self) > (other.cost + h_other);\n        }\n        // Secondary sort by actual cost (g) to favor shorter paths when heuristics are equal\n        return cost > other.cost; \n    }\n};\n\nvoid solve() {\n    // 1. Construct the canonical target board configuration.\n    // This configuration aims to form a grid graph spanning tree with the empty square at (N-1, N-1).\n    // Each tile (r, c) (not the empty square) is assigned bits representing lines needed\n    // to connect to its neighbors in the grid, excluding any connection to the empty square.\n    canonical_board_grid.assign(N, vector<int>(N));\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (r == N - 1 && c == N - 1) {\n                canonical_board_grid[r][c] = 0; // The empty square\n            } else {\n                int val = 0;\n                // Tile at (r, c) needs a RIGHT line (bit 4) if neighbor (r, c+1) exists and is not empty.\n                if (c < N - 1) val |= 4; \n                // Tile at (r, c) needs a LEFT line (bit 1) if neighbor (r, c-1) exists.\n                if (c > 0) val |= 1;     \n                // Tile at (r, c) needs a DOWN line (bit 8) if neighbor (r+1, c) exists and is not empty.\n                if (r < N - 1) val |= 8; \n                // Tile at (r, c) needs an UP line (bit 2) if neighbor (r-1, c) exists.\n                if (r > 0) val |= 2;     \n                canonical_board_grid[r][c] = val;\n            }\n        }\n    }\n\n    // 2. Initialize A* search.\n    priority_queue<SearchState, vector<SearchState>, greater<SearchState>> pq;\n    visited.clear();\n\n    StateKey initial_key = board_to_key(initial_board_grid);\n    SearchState initial_state = {initial_board_grid, initial_empty_pos.first, initial_empty_pos.second, 0, \"\"};\n    \n    // Check if the initial state is already the target state.\n    bool is_initial_target = true;\n    if (initial_state.empty_r != N - 1 || initial_state.empty_c != N - 1) {\n        is_initial_target = false;\n    } else {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r == N - 1 && c == N - 1) continue; // Skip the empty square itself\n                if (initial_state.board[r][c] != canonical_board_grid[r][c]) {\n                    is_initial_target = false;\n                    break;\n                }\n            }\n            if (!is_initial_target) break;\n        }\n    }\n\n    if (is_initial_target) {\n        cout << \"\" << endl; // Zero moves needed if already in target state.\n        return;\n    }\n\n    visited[initial_key] = {0, \"\"};\n    pq.push(initial_state);\n\n    // Limit the number of states explored to prevent Time Limit Exceeded.\n    // This limit is heuristic and may need tuning. It's adjusted based on N.\n    int max_states_to_explore = 2500000; // Default value\n    if (N >= 8) max_states_to_explore = 1800000; \n    if (N == 10) max_states_to_explore = 1200000; \n\n    int states_explored = 0;\n\n    // A* search loop.\n    while (!pq.empty() && states_explored < max_states_to_explore) {\n        SearchState current = pq.top();\n        pq.pop();\n\n        states_explored++;\n\n        StateKey current_key = board_to_key(current.board);\n        \n        // If we've found a shorter path to this state already, skip.\n        if (visited.count(current_key) && visited[current_key].first < current.cost) {\n            continue;\n        }\n\n        // Check if the current state is the target state.\n        bool is_target = true;\n        if (current.empty_r != N - 1 || current.empty_c != N - 1) {\n            is_target = false;\n        } else {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (r == N - 1 && c == N - 1) continue; // Skip the empty square\n                    if (current.board[r][c] != canonical_board_grid[r][c]) {\n                        is_target = false;\n                        break;\n                    }\n                }\n                if (!is_target) break;\n            }\n        }\n\n        // If target is reached, print the path and terminate.\n        if (is_target) {\n            cout << current.path << endl;\n            return; \n        }\n        \n        // Explore neighboring states by moving the empty square.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current.empty_r + dr[i];\n            int nc = current.empty_c + dc[i];\n\n            // Check if the potential new position for the empty square is within board bounds.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                Board next_board = current.board; // Create a copy of the current board.\n                // Perform the move: swap the empty square with the adjacent tile.\n                swap(next_board[current.empty_r][current.empty_c], next_board[nr][nc]);\n\n                StateKey next_key = board_to_key(next_board);\n                int next_cost = current.cost + 1;\n\n                // If this state hasn't been visited, or if we found a shorter path to it:\n                if (!visited.count(next_key) || next_cost < visited[next_key].first) {\n                    // Record the new state with its cost and path.\n                    visited[next_key] = {next_cost, current.path + move_chars[i]};\n                    // Add the new state to the priority queue for exploration.\n                    pq.push({next_board, nr, nc, next_cost, current.path + move_chars[i]});\n                }\n            }\n        }\n    }\n    \n    // According to the problem statement, a solution that forms a tree of size N^2-1\n    // is guaranteed to exist within T operations. If the search loop finishes\n    // without finding the target state, it implies that the search limits (e.g.,\n    // max_states_to_explore) were too strict, the heuristic was insufficient,\n    // or the state space exploration was too slow for the given time limit.\n    // In a competitive programming context, if this part is reached, it typically\n    // indicates a need for optimization, a better heuristic, or a different algorithm.\n    // For this problem, we assume the target state is reachable and will be found.\n    // If not found, the program would exit without outputting a path, which would be WA/TLE.\n}\n\n// Helper function to convert hexadecimal character to integer tile value.\nint char_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input: N (board size) and T (move limit).\n    cin >> N >> T_limit;\n\n    // Read the initial board configuration.\n    initial_board_grid.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            initial_board_grid[i][j] = char_to_int(row[j]);\n            // Store the position of the empty square (tile value 0).\n            if (initial_board_grid[i][j] == 0) {\n                initial_empty_pos = {i, j};\n            }\n        }\n    }\n\n    // Solve the puzzle using A* search.\n    solve();\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <iomanip>\n\nusing namespace std;\n\n// Using large constants for line endpoints to ensure they span across the cake.\n// The problem statement allows coordinates up to 10^9, so these are well within range.\nconst long long INF_COORD = 1e9; \n\nstruct Strawberry {\n    long long x, y;\n    int id;\n};\n\n// Structure to represent a line for output\nstruct Line {\n    long long px, py, qx, qy;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    int k; // Maximum number of cuts\n    cin >> n >> k;\n\n    vector<int> a(11); // a[d] is the number of attendees for d years\n    int total_attendees = 0;\n    for (int d = 1; d <= 10; ++d) {\n        cin >> a[d];\n        total_attendees += a[d];\n    }\n\n    vector<Strawberry> strawberries(n);\n    set<long long> x_coords_set, y_coords_set;\n    for (int i = 0; i < n; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        x_coords_set.insert(strawberries[i].x);\n        y_coords_set.insert(strawberries[i].y);\n    }\n\n    // Strategy: Use k/2 vertical lines and k - k/2 horizontal lines.\n    // This creates a grid of (k/2 + 1) * (k - k/2 + 1) regions.\n    // We need to ensure lines do not pass through any strawberry centers.\n    int num_v_lines = k / 2;\n    int num_h_lines = k - num_v_lines;\n\n    vector<long long> v_line_values; // x-coordinates for vertical lines\n    vector<long long> h_line_values; // y-coordinates for horizontal lines\n\n    // Find num_v_lines integer coordinates for vertical lines.\n    // The range for strawberry coordinates is roughly [-10000, 10000].\n    // We search for values outside this range first, then within.\n    long long current_coord = -10001; // Start searching outside the typical strawberry range\n    while (v_line_values.size() < num_v_lines && current_coord >= -10000 - num_v_lines) { // Search downwards\n        if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord--;\n    }\n    current_coord = 10001; // Start searching outside the typical strawberry range\n    while (v_line_values.size() < num_v_lines && current_coord <= 10000 + num_v_lines) { // Search upwards\n         if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n    // If still not enough, search strictly within the coordinate range\n    current_coord = -10000;\n     while (v_line_values.size() < num_v_lines && current_coord <= 10000) {\n        if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n\n\n    // Find num_h_lines integer coordinates for horizontal lines.\n    current_coord = -10001; \n    while (h_line_values.size() < num_h_lines && current_coord >= -10000 - num_h_lines) { // Search downwards\n        if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord--;\n    }\n    current_coord = 10001;\n    while (h_line_values.size() < num_h_lines && current_coord <= 10000 + num_h_lines) { // Search upwards\n         if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n    // If still not enough, search strictly within the coordinate range\n    current_coord = -10000;\n     while (h_line_values.size() < num_h_lines && current_coord <= 10000) {\n        if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n\n\n    // Define boundaries for regions. These are used to define cells.\n    // We use values slightly outside the typical range of strawberry coordinates.\n    vector<long long> v_boundaries = {-20000}; // Sentinel: smaller than any possible x_i\n    v_boundaries.insert(v_boundaries.end(), v_line_values.begin(), v_line_values.end());\n    v_boundaries.push_back(20000); // Sentinel: larger than any possible x_i\n\n    vector<long long> h_boundaries = {-20000};\n    h_boundaries.insert(h_boundaries.end(), h_line_values.begin(), h_line_values.end());\n    h_boundaries.push_back(20000);\n\n    // Sort boundaries and remove duplicates to ensure proper interval definition\n    sort(v_boundaries.begin(), v_boundaries.end());\n    v_boundaries.erase(unique(v_boundaries.begin(), v_boundaries.end()), v_boundaries.end());\n    sort(h_boundaries.begin(), h_boundaries.end());\n    h_boundaries.erase(unique(h_boundaries.begin(), h_boundaries.end()), h_boundaries.end());\n\n    // Count strawberries in each region defined by the grid.\n    // Store regions as pairs: {strawberry_count, region_flat_index}\n    vector<pair<int, int>> region_info; \n    // Group regions by their strawberry count for easier assignment.\n    map<int, vector<int>> regions_by_count; // count -> list of region_flat_indices\n\n    int region_flat_idx = 0;\n    for (size_t j = 0; j < v_boundaries.size() - 1; ++j) {\n        for (size_t k = 0; k < h_boundaries.size() - 1; ++k) {\n            int count = 0;\n            long long min_x = v_boundaries[j];\n            long long max_x = v_boundaries[j+1];\n            long long min_y = h_boundaries[k];\n            long long max_y = h_boundaries[k+1];\n\n            // Count strawberries within the current rectangular region.\n            for (const auto& straw : strawberries) {\n                if (straw.x >= min_x && straw.x < max_x &&\n                    straw.y >= min_y && straw.y < max_y) {\n                    count++;\n                }\n            }\n            \n            // We only care about regions that contain at least one strawberry.\n            if (count > 0) { \n                region_info.push_back({count, region_flat_idx});\n                regions_by_count[count].push_back(region_flat_idx);\n                region_flat_idx++;\n            }\n        }\n    }\n    \n    // Sort regions by their strawberry count. This helps in greedy assignment.\n    sort(region_info.begin(), region_info.end());\n\n    // Assignment phase: greedily assign available regions to satisfy demands a[d].\n    vector<bool> region_taken(region_flat_idx, false); // Tracks if a region has been assigned.\n    vector<int> b_counts(11, 0); // b_counts[d] will store the number of pieces with d strawberries.\n    vector<Line> cuts; // Stores the lines to be output.\n\n    // Iterate through each demand (d from 1 to 10, and for each a[d] attendees).\n    for (int d = 1; d <= 10; ++d) {\n        for (int i = 0; i < a[d]; ++i) {\n            // Try to find an available region with exactly 'd' strawberries.\n            bool found_region_for_demand = false;\n            if (regions_by_count.count(d)) {\n                // Get the list of regions that contain exactly 'd' strawberries.\n                vector<int>& available_regions_for_d = regions_by_count[d];\n                \n                // Iterate through these regions to find one that hasn't been taken.\n                for (size_t region_list_idx = 0; region_list_idx < available_regions_for_d.size(); ++region_list_idx) {\n                    int r_idx = available_regions_for_d[region_list_idx];\n                    if (!region_taken[r_idx]) {\n                        region_taken[r_idx] = true; // Mark this region as taken.\n                        b_counts[d]++;             // Increment the count of pieces with 'd' strawberries.\n                        found_region_for_demand = true;\n                        \n                        // To ensure this region is not considered again for the same demand 'd',\n                        // we move it to the end of the list and then pop it. This is an efficient way\n                        // to \"remove\" it from consideration for future demands of count 'd'.\n                        swap(available_regions_for_d[region_list_idx], available_regions_for_d.back());\n                        available_regions_for_d.pop_back();\n                        break; // Found a region for this specific demand, move to the next demand.\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the cuts.\n    // For each selected vertical line coordinate C, create a line from (C, -INF_COORD) to (C, INF_COORD).\n    for (long long val : v_line_values) {\n        cuts.push_back({val, -INF_COORD, val, INF_COORD});\n    }\n    // For each selected horizontal line coordinate C, create a line from (-INF_COORD, C) to (INF_COORD, C).\n    for (long long val : h_line_values) {\n        cuts.push_back({-INF_COORD, val, INF_COORD, val});\n    }\n\n    cout << cuts.size() << endl;\n    for (const auto& line : cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <set>\n#include <algorithm>\n#include <map>\n#include <tuple>\n\nusing namespace std;\n\nconst long long INF_WEIGHT = -1; // Represents no move found / invalid state\nconst int MAX_OPS = 5000; // Limit the number of operations\n\nstruct Point {\n    int x, y;\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nlong long N;\nPoint center;\nlong long total_weight_sum;\n\nlong long weight(Point p) {\n    long long dx = p.x - center.x;\n    long long dy = p.y - center.y;\n    return dx * dx + dy * dy + 1;\n}\n\n// Store segments using maps for efficient overlap checking\n// For axis-aligned segments\n// Key: y-coordinate, Value: set of {min_x, max_x}\nmap<int, set<pair<int, int>>> h_segments_by_y;\n// Key: x-coordinate, Value: set of {min_y, max_y}\nmap<int, set<pair<int, int>>> v_segments_by_x;\n\n// For 45-degree segments, use transformed coordinates u=x+y, v=x-y\n// A 45-degree line segment in (x,y) becomes an axis-aligned segment in (u,v) space.\n// If dx=dy, segment is horizontal in (u,v): u varies, v is constant.\n// If dx=-dy, segment is vertical in (u,v): v varies, u is constant.\n\n// Key: u-coordinate, Value: set of {min_v, max_v}\nmap<int, set<pair<int, int>>> uv_h_segments_by_u;\n// Key: v-coordinate, Value: set of {min_u, max_u}\nmap<int, set<pair<int, int>>> uv_v_segments_by_v;\n\n// Add a segment to the maps\nvoid add_segment(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        v_segments_by_x[p1.x].insert({min_y, max_y});\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        h_segments_by_y[p1.y].insert({min_x, max_x});\n    } else { // 45-degree segment\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n        if (u1 == u2) { // Vertical in (u,v) space\n            int min_v = min(v1, v2);\n            int max_v = max(v1, v2);\n            uv_v_segments_by_v[v1].insert({min_u, max_u});\n        } else { // Horizontal in (u,v) space (u1 must be == u2 if dx==dy)\n            int min_u = min(u1, u2);\n            int max_u = max(u1, u2);\n            uv_h_segments_by_u[u1].insert({min_u, max_u});\n        }\n    }\n}\n\n// Check if a new segment overlaps with any existing segment\nbool check_segment_overlap(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        auto it_vec = v_segments_by_x.find(p1.x);\n        if (it_vec != v_segments_by_x.end()) {\n            const auto& segments = it_vec->second;\n            // Check for segments that start before or at max_y\n            auto it = segments.upper_bound({max_y, -1}); // Find first segment starting > max_y\n            if (it != segments.begin()) {\n                --it; // Go to the first segment that might overlap\n                do {\n                    // Segment is [seg_min_y, seg_max_y]\n                    // We are checking overlap with [min_y, max_y]\n                    // Overlap exists if seg_max_y >= min_y AND seg_min_y <= max_y\n                    if (it->second >= min_y && it->first <= max_y) {\n                        return true; // Overlap found\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_y); // Optimization: stop if segment starts before min_y\n            }\n        }\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        auto it_vec = h_segments_by_y.find(p1.y);\n        if (it_vec != h_segments_by_y.end()) {\n            const auto& segments = it_vec->second;\n            auto it = segments.upper_bound({max_x, -1});\n            if (it != segments.begin()) {\n                --it;\n                do {\n                    if (it->second >= min_x && it->first <= max_x) {\n                        return true;\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_x);\n            }\n        }\n    } else { // 45-degree segment\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n        \n        if (u1 == u2) { // Vertical in (u,v) space\n            int min_v = min(v1, v2);\n            int max_v = max(v1, v2);\n            auto it_vec = uv_v_segments_by_v.find(v1);\n            if (it_vec != uv_v_segments_by_v.end()) {\n                const auto& segments = it_vec->second;\n                auto it = segments.upper_bound({max_v, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        if (it->second >= min_v && it->first <= max_v) {\n                            return true;\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_v);\n                }\n            }\n        } else { // Horizontal in (u,v) space\n            int min_u = min(u1, u2);\n            int max_u = max(u1, u2);\n            auto it_vec = uv_h_segments_by_u.find(u1);\n            if (it_vec != uv_h_segments_by_u.end()) {\n                const auto& segments = it_vec->second;\n                auto it = segments.upper_bound({max_u, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        if (it->second >= min_u && it->first <= max_u) {\n                            return true;\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_u);\n                }\n            }\n        }\n    }\n    return false; // No overlap\n}\n\n\n// Check if a point is on a line segment (exclusive of endpoints)\nbool is_point_on_segment_exclusive(Point test_p, Point seg_p1, Point seg_p2) {\n    if (seg_p1 == seg_p2) return false;\n\n    // Check collinearity and bounds\n    long long cross_product = (long long)(test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) - (long long)(test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y);\n    if (cross_product != 0) return false;\n\n    // Check if test_p is strictly between seg_p1 and seg_p2\n    bool between_x = (test_p.x > min(seg_p1.x, seg_p2.x) && test_p.x < max(seg_p1.x, seg_p2.x));\n    bool between_y = (test_p.y > min(seg_p1.y, seg_p2.y) && test_p.y < max(seg_p1.y, seg_p2.y));\n\n    if (seg_p1.x == seg_p2.x) { // Vertical segment\n        return between_y;\n    }\n    if (seg_p1.y == seg_p2.y) { // Horizontal segment\n        return between_x;\n    }\n    // For 45-degree segments, both conditions must hold if segment is not horizontal/vertical\n    return between_x && between_y;\n}\n\n// Check condition 2: no other dots on the perimeter segments\nbool check_perimeter_dots(Point p1, Point p2, Point p3, Point p4, const set<Point>& current_dots) {\n    Point segments[4][2] = {{p1, p2}, {p2, p3}, {p3, p4}, {p4, p1}};\n    \n    for (auto& seg : segments) {\n        Point seg_p1 = seg[0];\n        Point seg_p2 = seg[1];\n\n        // If a segment is degenerate, skip\n        if (seg_p1 == seg_p2) continue;\n\n        // Check all grid points that lie strictly between seg_p1 and seg_p2\n        // This needs to be efficient. Iterate points on the line.\n        if (seg_p1.x == seg_p2.x) { // Vertical\n            for (int y = min(seg_p1.y, seg_p2.y) + 1; y < max(seg_p1.y, seg_p2.y); ++y) {\n                Point p = {seg_p1.x, y};\n                if (current_dots.count(p)) return false;\n            }\n        } else if (seg_p1.y == seg_p2.y) { // Horizontal\n            for (int x = min(seg_p1.x, seg_p2.x) + 1; x < max(seg_p1.x, seg_p2.x); ++x) {\n                Point p = {x, seg_p1.y};\n                if (current_dots.count(p)) return false;\n            }\n        } else { // 45-degree\n            int dx = seg_p2.x - seg_p1.x;\n            int dy = seg_p2.y - seg_p1.y;\n            // Iterate along the segment. Step by (dx/abs(dx), dy/abs(dy))\n            int step_x = (dx > 0) ? 1 : -1;\n            int step_y = (dy > 0) ? 1 : -1;\n            for (int d = 1; d < abs(dx); ++d) {\n                Point p = {seg_p1.x + d * step_x, seg_p1.y + d * step_y};\n                if (current_dots.count(p)) return false;\n            }\n        }\n    }\n    return true;\n}\n\n\n// Check if 4 points form a valid rectangle in the given order\n// p1 is the new dot, p2, p3, p4 are existing dots\nbool check_rectangle_shape_and_order(Point p1, Point p2, Point p3, Point p4) {\n    // Check if p1 is empty and p2, p3, p4 have dots\n    // (This is handled by caller, but good for robustness)\n    \n    long long dx1 = p2.x - p1.x;\n    long long dy1 = p2.y - p1.y;\n    long long dx2 = p3.x - p2.x;\n    long long dy2 = p3.y - p2.y;\n    long long dx3 = p4.x - p3.x;\n    long long dy3 = p4.y - p3.y;\n    long long dx4 = p1.x - p4.x;\n    long long dy4 = p1.y - p4.y;\n\n    // Check for axis-aligned rectangles\n    bool is_axis_aligned = false;\n    if (dx1 == 0 && dy2 == 0 && dx3 == 0 && dy4 == 0 && dy1 == dy3 && dx2 == dx4) { // p1-p2 vertical, p2-p3 horiz, p3-p4 vert, p4-p1 horiz\n        if (dx1 == 0 && dx3 == 0 && dy2 == 0 && dy4 == 0 && abs(dy1) > 0 && abs(dx2) > 0 && dy1 == -dy3 && dx2 == -dx4) { // Ensure opposite sides have same length and correct orientation\n             is_axis_aligned = true;\n        }\n    } else if (dy1 == 0 && dx2 == 0 && dy3 == 0 && dx4 == 0 && dx1 == dx3 && dy2 == dy4) { // p1-p2 horiz, p2-p3 vert, p3-p4 horiz, p4-p1 vert\n        if (dy1 == 0 && dy3 == 0 && dx2 == 0 && dx4 == 0 && abs(dx1) > 0 && abs(dy2) > 0 && dx1 == -dx3 && dy2 == -dy4) {\n            is_axis_aligned = true;\n        }\n    }\n\n    if (is_axis_aligned) return true;\n\n    // Check for 45-degree rectangles\n    // Sides must be perpendicular and have equal length\n    // Dot product of adjacent vectors must be 0: dx1*dx2 + dy1*dy2 = 0\n    // Magnitudes must be equal: dx1^2 + dy1^2 = dx2^2 + dy2^2\n    // Also, check other sides for consistency: dx3 = -dx1, dy3 = -dy1, dx4 = -dx2, dy4 = -dy2\n    \n    long long dot_product_12_23 = dx1 * dx2 + dy1 * dy2;\n    long long mag_sq_12 = dx1 * dx1 + dy1 * dy1;\n    long long mag_sq_23 = dx2 * dx2 + dy2 * dy2;\n\n    if (dot_product_12_23 == 0 && mag_sq_12 > 0 && mag_sq_12 == mag_sq_23) {\n        // Check if the remaining sides are consistent\n        if (dx3 == -dx1 && dy3 == -dy1 && dx4 == -dx2 && dy4 == -dy2) {\n             // Also need to check that the sides are indeed 45 degrees, meaning dx = +- dy\n             if (abs(dx1) == abs(dy1) && abs(dx2) == abs(dy2)) {\n                return true;\n             }\n        }\n    }\n\n    return false;\n}\n\n\n// Represents a candidate move\nstruct CandidateMove {\n    Point p1_new; // The new dot\n    Point p2_old, p3_old, p4_old; // The three existing dots\n    long long weight; // Weight of p1_new\n\n    bool operator<(const CandidateMove& other) const {\n        return weight < other.weight; // Max heap behavior with greater<>\n    }\n};\n\n// Function to find all candidate moves\nvector<CandidateMove> find_candidate_moves(const set<Point>& current_dots) {\n    vector<CandidateMove> candidates;\n    vector<Point> dots_vec(current_dots.begin(), current_dots.end());\n\n    // --- Generate Axis-Aligned Rectangle Candidates ---\n    // Iterate through all pairs of dots\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point pa = dots_vec[i];\n            Point pb = dots_vec[j];\n\n            // Case 1: pa and pb share y-coordinate (horizontal segment)\n            if (pa.y == pb.y) {\n                int y = pa.y;\n                int x1 = min(pa.x, pb.x);\n                int x2 = max(pa.x, pb.x);\n                // Look for points on the same vertical lines x1 and x2, but different y\n                for (int dy = 1; ; ++dy) { // Check rows above and below\n                    int y_upper = y + dy;\n                    int y_lower = y - dy;\n                    \n                    Point pc_upper = {x1, y_upper};\n                    Point pd_upper = {x2, y_upper};\n                    Point pc_lower = {x1, y_lower};\n                    Point pd_lower = {x2, y_lower};\n\n                    bool found_upper = current_dots.count(pc_upper) && current_dots.count(pd_upper) && y_upper < N;\n                    bool found_lower = current_dots.count(pc_lower) && current_dots.count(pd_lower) && y_lower >= 0;\n\n                    if (!found_upper && !found_lower) {\n                        if (dy > N) break; // Optimization: stop if we've checked too far\n                        continue;\n                    }\n                    \n                    if (found_upper) {\n                        // Potential rectangle: (x1, y), (x2, y), (x1, y_upper), (x2, y_upper)\n                        // Try adding dot at (x1, y_upper) or (x2, y_upper)\n                        Point vertices[4] = {{x1, y}, {x2, y}, pc_upper, pd_upper};\n                        Point empty_candidates[2] = {pc_upper, pd_upper};\n                        Point known_dots[2] = {pa, pb};\n\n                        for(int k=0; k<2; ++k) {\n                            Point p_new = empty_candidates[k];\n                            if (!current_dots.count(p_new)) {\n                                Point p_known1 = known_dots[0];\n                                Point p_known2 = known_dots[1];\n                                Point p_known3 = empty_candidates[1-k];\n\n                                // Form the operation: p_new, p_known1, p_known2, p_known3 ? Order must be correct.\n                                // The vertices are: V1=(x1,y), V2=(x2,y), V3=(x2,y_upper), V4=(x1,y_upper).\n                                // If p_new is V4=(x1,y_upper), possible operations are:\n                                // (V4, V1, V2, V3) -> p1=V4, p2=V1, p3=V2, p4=V3\n                                // (V4, V3, V2, V1) -> p1=V4, p2=V3, p3=V2, p4=V1\n                                Point ops_p2[2] = {{x1,y}, {x2,y_upper}};\n                                Point ops_p3[2] = {{x2,y}, {x2,y_upper}};\n                                Point ops_p4[2] = {{x2,y_upper}, {x1,y}};\n\n                                for(int op_idx=0; op_idx<2; ++op_idx) {\n                                    Point cur_p2 = ops_p2[op_idx];\n                                    Point cur_p3 = ops_p3[op_idx];\n                                    Point cur_p4 = ops_p4[op_idx];\n                                    \n                                    if (current_dots.count(cur_p2) && current_dots.count(cur_p3) && current_dots.count(cur_p4)) {\n                                        if (check_rectangle_shape_and_order(p_new, cur_p2, cur_p3, cur_p4)) {\n                                            if (!check_segment_overlap(p_new, cur_p2) &&\n                                                !check_segment_overlap(cur_p2, cur_p3) &&\n                                                !check_segment_overlap(cur_p3, cur_p4) &&\n                                                !check_segment_overlap(cur_p4, p_new)) {\n                                                if (check_perimeter_dots(p_new, cur_p2, cur_p3, cur_p4, current_dots)) {\n                                                     candidates.push_back({p_new, cur_p2, cur_p3, cur_p4, weight(p_new)});\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_upper && found_lower) break; // If both found, no need to check further in this dy direction\n                    if (!found_upper && !found_lower) break; // If neither found, further dy won't find them either.\n                }\n            }\n\n            // Case 2: pa and pb share x-coordinate (vertical segment)\n            if (pa.x == pb.x) {\n                int x = pa.x;\n                int y1 = min(pa.y, pb.y);\n                int y2 = max(pa.y, pb.y);\n                // Look for points on the same horizontal lines y1 and y2, but different x\n                for (int dx = 1; ; ++dx) { // Check columns left and right\n                    int x_right = x + dx;\n                    int x_left = x - dx;\n                    \n                    Point pc_right = {x_right, y1};\n                    Point pd_right = {x_right, y2};\n                    Point pc_left = {x_left, y1};\n                    Point pd_left = {x_left, y2};\n\n                    bool found_right = current_dots.count(pc_right) && current_dots.count(pd_right) && x_right < N;\n                    bool found_left = current_dots.count(pc_left) && current_dots.count(pd_left) && x_left >= 0;\n\n                    if (!found_right && !found_left) {\n                        if (dx > N) break;\n                        continue;\n                    }\n                    \n                    if (found_right) {\n                        // Potential rectangle: (x, y1), (x, y2), (x_right, y1), (x_right, y2)\n                        // Try adding dot at (x_right, y1) or (x_right, y2)\n                        Point vertices[4] = {{x, y1}, {x, y2}, pd_right, pc_right};\n                        Point empty_candidates[2] = {pc_right, pd_right};\n                        Point known_dots[2] = {pa, pb};\n\n                         for(int k=0; k<2; ++k) {\n                            Point p_new = empty_candidates[k];\n                            if (!current_dots.count(p_new)) {\n                                Point p_known1 = known_dots[0];\n                                Point p_known2 = known_dots[1];\n                                Point p_known3 = empty_candidates[1-k];\n\n                                // Vertices: V1=(x,y1), V2=(x,y2), V3=(x_right,y2), V4=(x_right,y1)\n                                // If p_new is V4=(x_right, y1)\n                                Point ops_p2[2] = {{x,y1}, {x_right,y2}};\n                                Point ops_p3[2] = {{x,y2}, {x_right,y2}};\n                                Point ops_p4[2] = {{x_right,y2}, {x,y1}};\n                                \n                                for(int op_idx=0; op_idx<2; ++op_idx) {\n                                    Point cur_p2 = ops_p2[op_idx];\n                                    Point cur_p3 = ops_p3[op_idx];\n                                    Point cur_p4 = ops_p4[op_idx];\n                                    \n                                    if (current_dots.count(cur_p2) && current_dots.count(cur_p3) && current_dots.count(cur_p4)) {\n                                        if (check_rectangle_shape_and_order(p_new, cur_p2, cur_p3, cur_p4)) {\n                                            if (!check_segment_overlap(p_new, cur_p2) &&\n                                                !check_segment_overlap(cur_p2, cur_p3) &&\n                                                !check_segment_overlap(cur_p3, cur_p4) &&\n                                                !check_segment_overlap(cur_p4, p_new)) {\n                                                if (check_perimeter_dots(p_new, cur_p2, cur_p3, cur_p4, current_dots)) {\n                                                     candidates.push_back({p_new, cur_p2, cur_p3, cur_p4, weight(p_new)});\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_right && found_left) break;\n                    if (!found_right && !found_left) break;\n                }\n            }\n        }\n    }\n\n    // --- Generate 45-degree Rectangle Candidates ---\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point p_a = dots_vec[i];\n            Point p_b = dots_vec[j];\n\n            long long dx_ab = p_b.x - p_a.x;\n            long long dy_ab = p_b.y - p_a.y;\n\n            // Check if they could be adjacent vertices of a 45-degree rectangle\n            if (abs(dx_ab) == abs(dy_ab) && dx_ab != 0) {\n                // Possible vectors for the next side (perpendicular and same length)\n                // v1 = (-dy_ab, dx_ab)\n                // v2 = (dy_ab, -dx_ab)\n                \n                int possible_v[2][2] = {{- (int)dy_ab, (int)dx_ab}, {(int)dy_ab, - (int)dx_ab}};\n\n                for (int k = 0; k < 2; ++k) {\n                    long long next_dx = possible_v[k][0];\n                    long long next_dy = possible_v[k][1];\n\n                    // Candidate p_c = p_b + next_vector\n                    Point p_c = {p_b.x + (int)next_dx, p_b.y + (int)next_dy};\n                    // Candidate p_d = p_a + next_vector\n                    Point p_d = {p_a.x + (int)next_dx, p_a.y + (int)next_dy};\n\n                    if (p_c.x >= 0 && p_c.x < N && p_c.y >= 0 && p_c.y < N &&\n                        p_d.x >= 0 && p_d.x < N && p_d.y >= 0 && p_d.y < N) {\n                        \n                        if (current_dots.count(p_c) && current_dots.count(p_d)) {\n                            // We have a rectangle p_a, p_b, p_c, p_d\n                            // Try adding a dot at any of these points if it's empty.\n                            // For rule: \"p_i,1 ... and three grid points p_i,2, p_i,3, p_i,4 which satisfy...\"\n                            // this means p_a is the NEW dot, and p_b,p_c,p_d are EXISTING.\n                            // The order is p_a, p_b, p_c, p_d.\n                            if (!current_dots.count(p_a)) {\n                                if (check_rectangle_shape_and_order(p_a, p_b, p_c, p_d)) {\n                                    if (!check_segment_overlap(p_a, p_b) &&\n                                        !check_segment_overlap(p_b, p_c) &&\n                                        !check_segment_overlap(p_c, p_d) &&\n                                        !check_segment_overlap(p_d, p_a)) {\n                                        if (check_perimeter_dots(p_a, p_b, p_c, p_d, current_dots)) {\n                                            candidates.push_back({p_a, p_b, p_c, p_d, weight(p_a)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Other points could be new, but we've covered all pairs as 'p_a' already\n                            // E.g., if p_b was new, it would be tested when considering p_a and p_b as endpoints.\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M;\n    cin >> N >> M;\n\n    center = {(int)(N - 1) / 2, (int)(N - 1) / 2};\n    total_weight_sum = 0;\n\n    set<Point> current_dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        current_dots.insert({x, y});\n        total_weight_sum += weight({x, y});\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    int ops_count = 0;\n    while (ops_count < MAX_OPS) {\n        vector<CandidateMove> candidates = find_candidate_moves(current_dots);\n\n        if (candidates.empty()) {\n            break; // No more moves possible\n        }\n\n        // Sort candidates by weight (descending)\n        sort(candidates.rbegin(), candidates.rend());\n\n        // Select the best move (highest weight)\n        const auto& best_move = candidates[0];\n\n        // Add the new dot\n        current_dots.insert(best_move.p1_new);\n        total_weight_sum += best_move.weight;\n        ops_count++;\n\n        // Record the operation\n        operations.emplace_back(best_move.p1_new.x, best_move.p1_new.y,\n                                best_move.p2_old.x, best_move.p2_old.y,\n                                best_move.p3_old.x, best_move.p3_old.y,\n                                best_move.p4_old.x, best_move.p4_old.y);\n\n        // Add the segments of the new rectangle\n        add_segment(best_move.p1_new, best_move.p2_old);\n        add_segment(best_move.p2_old, best_move.p3_old);\n        add_segment(best_move.p3_old, best_move.p4_old);\n        add_segment(best_move.p4_old, best_move.p1_new);\n    }\n\n    cout << operations.size() << endl;\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) << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int SIZE = 10;\nint board[SIZE][SIZE]; // 0 for empty, 1, 2, 3 for flavors\n\n// Helper to find the p_t-th empty cell\npair<int, int> find_empty_cell(int p_t) {\n    int empty_count = 0;\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            if (board[r][c] == 0) {\n                empty_count++;\n                if (empty_count == p_t) {\n                    return {r, c};\n                }\n            }\n        }\n    }\n    return {-1, -1}; // Should not happen\n}\n\n// Helper to apply a tilt and update the board\nvoid apply_tilt(char dir) {\n    if (dir == 'F') { // Move down\n        for (int col = 0; col < SIZE; ++col) {\n            vector<pair<int, int>> occupied_cells; // {original_row, flavor}\n            for (int row = 0; row < SIZE; ++row) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({row, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[SIZE - 1 - (k - 1 - i)][col] = occupied_cells[i].second;\n            }\n            for (int row = 0; row < SIZE - k; ++row) {\n                board[row][col] = 0;\n            }\n        }\n    } else if (dir == 'B') { // Move up\n        for (int col = 0; col < SIZE; ++col) {\n            vector<pair<int, int>> occupied_cells; // {original_row, flavor}\n            for (int row = 0; row < SIZE; ++row) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({row, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[i][col] = occupied_cells[i].second;\n            }\n            for (int row = k; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n        }\n    } else if (dir == 'R') { // Move right\n        for (int row = 0; row < SIZE; ++row) {\n            vector<pair<int, int>> occupied_cells; // {original_col, flavor}\n            for (int col = 0; col < SIZE; ++col) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({col, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][SIZE - 1 - (k - 1 - i)] = occupied_cells[i].second;\n            }\n            for (int col = 0; col < SIZE - k; ++col) {\n                board[row][col] = 0;\n            }\n        }\n    } else { // dir == 'L', Move left\n        for (int row = 0; row < SIZE; ++row) {\n            vector<pair<int, int>> occupied_cells; // {original_col, flavor}\n            for (int col = 0; col < SIZE; ++col) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({col, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][i] = occupied_cells[i].second;\n            }\n            for (int col = k; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) {\n        cin >> f[i];\n    }\n\n    for (int i = 0; i < SIZE; ++i) {\n        for (int j = 0; j < SIZE; ++j) {\n            board[i][j] = 0;\n        }\n    }\n\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        cin >> p_t;\n\n        pair<int, int> cell = find_empty_cell(p_t);\n        int current_r = cell.first;\n        int current_c = cell.second;\n        board[current_r][current_c] = f[t];\n\n        if (t == 100) {\n            // No output for the 100th tilt as per problem statement\n            continue;\n        }\n\n        char best_tilt = 'F';\n        int min_final_dist = 1000; // Larger than any possible Manhattan distance\n\n        for (char tilt_dir : {'F', 'B', 'L', 'R'}) {\n            int sim_r_final = -1, sim_c_final = -1;\n\n            if (tilt_dir == 'F') { // Move down\n                vector<pair<int, int>> occupied_in_col; // {original_row, flavor}\n                for (int row = 0; row < SIZE; ++row) {\n                    if (board[row][current_c] != 0) {\n                        occupied_in_col.push_back({row, board[row][current_c]});\n                    }\n                }\n                sort(occupied_in_col.begin(), occupied_in_col.end());\n\n                int k = occupied_in_col.size();\n                sim_c_final = current_c; // Column doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_row = occupied_in_col[i].first;\n                    int new_row = SIZE - 1 - (k - 1 - i); // Packed to the bottom\n                    if (original_row == current_r) {\n                        sim_r_final = new_row;\n                    }\n                }\n            } else if (tilt_dir == 'B') { // Move up\n                vector<pair<int, int>> occupied_in_col; // {original_row, flavor}\n                for (int row = 0; row < SIZE; ++row) {\n                    if (board[row][current_c] != 0) {\n                        occupied_in_col.push_back({row, board[row][current_c]});\n                    }\n                }\n                sort(occupied_in_col.begin(), occupied_in_col.end());\n\n                int k = occupied_in_col.size();\n                sim_c_final = current_c; // Column doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_row = occupied_in_col[i].first;\n                    int new_row = i; // Packed to the top\n                    if (original_row == current_r) {\n                        sim_r_final = new_row;\n                    }\n                }\n            } else if (tilt_dir == 'R') { // Move right\n                vector<pair<int, int>> occupied_in_row; // {original_col, flavor}\n                for (int col = 0; col < SIZE; ++col) {\n                    if (board[current_r][col] != 0) {\n                        occupied_in_row.push_back({col, board[current_r][col]});\n                    }\n                }\n                sort(occupied_in_row.begin(), occupied_in_row.end());\n\n                int k = occupied_in_row.size();\n                sim_r_final = current_r; // Row doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_col = occupied_in_row[i].first;\n                    int new_col = SIZE - 1 - (k - 1 - i); // Packed to the right\n                    if (original_col == current_c) {\n                        sim_c_final = new_col;\n                    }\n                }\n            } else { // tilt_dir == 'L', Move left\n                vector<pair<int, int>> occupied_in_row; // {original_col, flavor}\n                for (int col = 0; col < SIZE; ++col) {\n                    if (board[current_r][col] != 0) {\n                        occupied_in_row.push_back({col, board[current_r][col]});\n                    }\n                }\n                sort(occupied_in_row.begin(), occupied_in_row.end());\n\n                int k = occupied_in_row.size();\n                sim_r_final = current_r; // Row doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_col = occupied_in_row[i].first;\n                    int new_col = i; // Packed to the left\n                    if (original_col == current_c) {\n                        sim_c_final = new_col;\n                    }\n                }\n            }\n\n            // Calculate min distance from (sim_r_final, sim_c_final) to same flavored candies\n            int current_min_dist = 1000;\n            bool found_other_candy = false;\n            for (int r_other = 0; r_other < SIZE; ++r_other) {\n                for (int c_other = 0; c_other < SIZE; ++c_other) {\n                    // Check if it's a candy of the same flavor AND it's NOT the one we just placed\n                    if (board[r_other][c_other] == f[t] && !(r_other == current_r && c_other == current_c)) {\n                        found_other_candy = true;\n                        int dist = abs(sim_r_final - r_other) + abs(sim_c_final - c_other);\n                        current_min_dist = min(current_min_dist, dist);\n                    }\n                }\n            }\n            \n            // If current_min_dist is still 1000, it means there are no other candies of the same flavor.\n            // In this case, any tilt is equally \"good\" in terms of distance.\n            // The tie-breaking logic below will handle this.\n\n            if (current_min_dist < min_final_dist) {\n                min_final_dist = current_min_dist;\n                best_tilt = tilt_dir;\n            } else if (current_min_dist == min_final_dist) {\n                // Tie-breaking: F < B < L < R\n                // The loop order {'F', 'B', 'L', 'R'} naturally implements this.\n                // If a new direction gives the same min distance, we do NOT update `best_tilt`.\n                // Thus, the first direction encountered that achieved `min_final_dist` is kept.\n            }\n        }\n\n        apply_tilt(best_tilt);\n        cout << best_tilt << endl;\n        cout << flush;\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\n// Function to convert an adjacency matrix to its bitstring representation.\n// The order of edges in the string is lexicographical by (i, j) pairs where i < j.\nstd::string adj_matrix_to_string(int N, const std::vector<std::vector<bool>>& adj) {\n    std::string s = \"\";\n    s.reserve(N * (N - 1) / 2); // Pre-allocate memory for efficiency\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Function to compute the degree sequence of a graph from its bitstring representation.\n// The degree sequence is returned as a vector of integers.\nstd::vector<int> get_degrees_from_string(int N, const std::string& s) {\n    std::vector<int> degrees(N, 0); // Initialize degrees for all vertices to 0\n    int k = 0; // Index for iterating through the bitstring\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (s[k] == '1') { // If an edge exists between vertex i and vertex j\n                degrees[i]++; // Increment degree of vertex i\n                degrees[j]++; // Increment degree of vertex j\n            }\n            k++; // Move to the next character in the bitstring\n        }\n    }\n    // The degree sequence comparison uses the canonical degree sequence of G_i,\n    // which is stored in precomputed_degrees. We do NOT sort degrees_H here,\n    // as we compare it against the specific, non-sorted degree sequences of G_i.\n    return degrees;\n}\n\nint main() {\n    // Fast I/O operations\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    std::cin >> M >> epsilon;\n\n    // Heuristic choice for N:\n    // The score formula round(10^9 * 0.9^E / N) implies a smaller N is better for the score multiplier (1/N).\n    // However, N must be large enough to create M distinct graphs that are robust to noise and vertex shuffling.\n    // The total number of possible edges in an N-vertex graph is N*(N-1)/2.\n    // To distinguish M graphs using edge counts as a primary feature, we need N*(N-1)/2 >= M-1.\n    // For M=100, this implies N=15 (since 14*13/2=91 and 15*14/2=105).\n    // Given epsilon can be up to 0.4, relying solely on edge counts might be insufficient.\n    // N=20 provides 190 edges, offering more structural diversity and thus better distinguishability.\n    // It balances the 1/N score factor (1/20) with sufficient edge capacity for M=100 graphs.\n    // N=20 is within the problem's constraint [4, 100].\n    int N = 20; \n\n    // Store precomputed degree sequences for G_0, ..., G_{M-1}.\n    // This allows for quick comparison during query processing.\n    std::vector<std::vector<int>> precomputed_degrees(M, std::vector<int>(N));\n    // Store the string representations of G_0, ..., G_{M-1} for output.\n    std::vector<std::string> graph_strings(M);\n\n    // Seed the random number generator for graph generation.\n    // Using a fixed seed (0) ensures that the generated graphs are identical\n    // across different runs for the same M and epsilon values, which is crucial for reproducibility.\n    std::mt19937 rng(0); \n\n    // Maximum possible edges in an N-vertex graph.\n    int max_possible_edges = N * (N - 1) / 2;\n\n    // Generate M distinct graphs.\n    for (int i = 0; i < M; ++i) {\n        // Generate graphs with edge counts spaced out to maximize distinguishability.\n        // The i-th graph (0-indexed) will have approximately i * (max_edges / (M-1)) edges.\n        // This strategy spreads the edge counts evenly from 0 up to max_possible_edges.\n        // Since M >= 10, M-1 is at least 9, so division by zero is avoided.\n        int target_edges = static_cast<int>(static_cast<double>(i) * max_possible_edges / (M - 1));\n        \n        // Ensure target_edges is within valid bounds [0, max_possible_edges].\n        // This is a safeguard against potential floating-point inaccuracies or edge cases.\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n\n        // Initialize an adjacency matrix for the graph G_i.\n        std::vector<std::vector<bool>> adj(N, std::vector<bool>(N, false));\n        int edges_added = 0;\n\n        // Add exactly target_edges randomly to the graph G_i.\n        // This loop picks random pairs of vertices and adds an edge if it doesn't exist,\n        // until the target number of edges is reached.\n        // For N=20, this approach is efficient enough.\n        if (target_edges > 0) {\n            while (edges_added < target_edges) {\n                int u = rng() % N; // Pick a random vertex u\n                int v = rng() % N; // Pick a random vertex v\n                if (u == v) continue; // Avoid self-loops\n                if (u > v) std::swap(u, v); // Ensure consistent ordering (u < v) for edge representation\n                \n                if (!adj[u][v]) { // If the edge (u,v) does not exist yet\n                    adj[u][v] = adj[v][u] = true; // Add the edge (undirected)\n                    edges_added++; // Increment the count of added edges\n                }\n            }\n        }\n        \n        // Convert the constructed adjacency matrix to the required string format.\n        graph_strings[i] = adj_matrix_to_string(N, adj);\n        // Compute and store the degree sequence for this graph G_i.\n        precomputed_degrees[i] = get_degrees_from_string(N, graph_strings[i]);\n    }\n\n    // Output N, followed by the string representations of the M generated graphs.\n    std::cout << N << std::endl;\n    for (int i = 0; i < M; ++i) {\n        std::cout << graph_strings[i] << std::endl;\n    }\n    // Flush the output buffer to ensure all generated graph data is sent to the judge.\n    std::cout << std::flush; \n\n    // Process the 100 queries.\n    for (int k = 0; k < 100; ++k) {\n        std::string H_str; // The graph string received for the current query H_k.\n        std::cin >> H_str;\n\n        // Compute the degree sequence of the received graph H_k.\n        std::vector<int> degrees_H = get_degrees_from_string(N, H_str);\n\n        int best_match_idx = -1; // Stores the index of the best matching G_i found so far.\n        // Initialize min_dist to a value larger than any possible L1 distance.\n        // For N=20, the maximum L1 distance is N*(N-1) = 20*19 = 380.\n        // Using -1 as a flag indicates that no comparison has been made yet.\n        long long min_dist = -1; \n\n        // Find which precomputed graph G_i has a degree sequence 'closest' to H_k's degree sequence.\n        // Closeness is measured by the L1 distance.\n        for (int i = 0; i < M; ++i) {\n            long long current_dist = 0; // L1 distance for G_i.\n            for (int j = 0; j < N; ++j) {\n                // Sum of absolute differences in degrees between H_k and G_i for each vertex.\n                current_dist += std::abs(degrees_H[j] - precomputed_degrees[i][j]);\n            }\n\n            // If this is the first graph considered (best_match_idx == -1), or\n            // if the current graph G_i is closer to H_k than the current best match,\n            // update the best match.\n            if (best_match_idx == -1 || current_dist < min_dist) {\n                min_dist = current_dist;\n                best_match_idx = i;\n            }\n        }\n        \n        // Output the predicted index t_k. This is the index of the graph G_i\n        // that H_k is most likely generated from based on degree sequence similarity.\n        std::cout << best_match_idx << std::endl;\n        // Flush the output buffer to ensure the prediction is sent immediately.\n        std::cout << std::flush; \n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Use a large value for infinity, greater than any possible shortest path sum.\n// Max path length can be approximately N * max_w = 1000 * 10^6 = 10^9.\n// The problem uses 10^9 for unreachable distances. Our internal INF must be larger\n// to correctly identify unreachable nodes in Dijkstra's algorithm.\nconst long long INF = 4e15; \n\n// Structure to represent an edge in the graph.\nstruct Edge {\n    int u, v, w, id;       // Endpoints, weight, and original index of the edge.\n    long long dist_uv;     // Shortest path distance between u and v in the original graph.\n    int assignment;        // The day this edge is scheduled for repair.\n};\n\n// Structure for Dijkstra's priority queue: stores distance and vertex.\nstruct State {\n    long long dist;\n    int vertex;\n\n    // For priority_queue: sort by distance (min-heap).\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\n// Dijkstra's algorithm to find shortest paths from a single source vertex.\n// It returns a vector containing the shortest distance from start_node to every other node.\n// Time complexity: O(M log N) or O(M + N log N) depending on priority queue implementation.\nvector<long long> dijkstra(int start_node, int n, const vector<vector<pair<int, int>>>& adj) {\n    vector<long long> dist(n + 1, INF); // Initialize distances to infinity.\n    dist[start_node] = 0;               // Distance from source to itself is 0.\n    priority_queue<State, vector<State>, greater<State>> pq;\n    pq.push({0, start_node});\n\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        long long d = current.dist;\n        int v = current.vertex;\n\n        // If we found a shorter path to 'v' already, skip this one.\n        if (d > dist[v]) {\n            continue;\n        }\n\n        // Explore neighbors of vertex 'v'.\n        for (auto& edge_info : adj[v]) {\n            int neighbor = edge_info.first;\n            int weight = edge_info.second;\n            \n            // Relaxation step: If a shorter path to 'neighbor' is found through 'v'.\n            // Check for overflow before addition. If dist[v] is INF, dist[v] + weight will be larger than any finite path or INF, so this condition handles INF correctly.\n            if (dist[v] != INF && dist[v] + weight < dist[neighbor]) {\n                dist[neighbor] = dist[v] + weight;\n                pq.push({dist[neighbor], neighbor});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, d_days, k_limit;\n    cin >> n >> m >> d_days >> k_limit;\n\n    // Adjacency list for graph: vector of vectors of pairs {neighbor, weight}.\n    // Vertices are 1-indexed in input, so we use size n+1 for 1-based indexing.\n    vector<vector<pair<int, int>>> adj(n + 1);\n    vector<Edge> edges;\n    edges.reserve(m); // Pre-allocate memory for edges.\n\n    // Read edges and build the adjacency list.\n    for (int i = 0; i < m; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w}); // Graph is undirected.\n        // Store edge details including its original index 'i' (0 to m-1).\n        edges.push_back({u, v, w, i, 0, 0});\n    }\n\n    // Step 1: Compute all-pairs shortest paths (APSP).\n    // This is done by running Dijkstra from each vertex.\n    // For a planar graph, M is roughly proportional to N, so complexity is approximately N * O(M log N).\n    // With N=1000, M=3000, this is ~1000 * 3000 * log(1000) which is around 3e7 operations, feasible.\n    vector<vector<long long>> dist_matrix(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        dist_matrix[i] = dijkstra(i, n, adj);\n    }\n\n    // Step 2: For each edge, calculate the shortest path distance between its endpoints.\n    // This 'dist_uv' value is used as a heuristic: edges connecting vertices that are far apart\n    // in the graph (large shortest path distance) are considered more critical to the network's structure.\n    for (auto& edge : edges) {\n        edge.dist_uv = dist_matrix[edge.u][edge.v];\n        // The problem guarantees the graph is 2-edge-connected, implying it is connected.\n        // Therefore, dist_matrix[edge.u][edge.v] will always be a finite value (not INF).\n    }\n\n    // Step 3: Sort edges based on heuristics to decide the order of repair.\n    // Heuristic: Prioritize edges connecting vertices that are far apart (large dist_uv).\n    // If dist_uv is equal, prioritize heavier edges (large w).\n    // This strategy aims to group critical \"arteries\" (long-span, heavy edges) together on the same day.\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        if (a.dist_uv != b.dist_uv) {\n            return a.dist_uv > b.dist_uv; // Sort by dist_uv descending: edges spanning larger distances first.\n        }\n        // Tie-breaker: if dist_uv is the same, sort by weight descending.\n        // This prioritizes heavier edges among those connecting distant nodes.\n        return a.w > b.w; \n    });\n\n    // Step 4: Assign edges to days greedily.\n    // Iterate through days from 1 to D. For each day, assign up to k_limit edges\n    // from the beginning of the sorted 'edges' list.\n    vector<int> assignments(m); // To store the day assignment for each edge, indexed by its original ID.\n    int current_edge_idx = 0;   // Index into the sorted 'edges' vector.\n\n    for (int day = 1; day <= d_days; ++day) {\n        int edges_assigned_today = 0;\n        // Assign up to k_limit edges for the current day, or until all edges are assigned.\n        while (edges_assigned_today < k_limit && current_edge_idx < m) {\n            // Assign the current edge (from the sorted list) to the current day.\n            edges[current_edge_idx].assignment = day;\n            // Store the assignment in the 'assignments' array using the edge's original ID.\n            assignments[edges[current_edge_idx].id] = day;\n            \n            edges_assigned_today++;\n            current_edge_idx++;\n        }\n        \n        // If all edges have been assigned, we can stop the day assignment process early.\n        if (current_edge_idx == m) {\n            break;\n        }\n    }\n\n    // Step 5: Output the assignments for each edge in the order they appeared in the input.\n    for (int i = 0; i < m; ++i) {\n        cout << assignments[i] << (i == m - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\n// Grid index helpers\n#define GRID_IDX(x, y, z, D) ((x) * (D) * (D) + (y) * (D) + (z))\n\n// Grid access macros\n#define GRID_GET(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n#define GRID_WRITE(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n\n// Polycube representation\nstruct Polycube {\n    vector<tuple<int, int, int>> cells;\n\n    // Custom comparison for Polycube, used for std::map keys\n    bool operator<(const Polycube& other) const {\n        return cells < other.cells;\n    }\n    bool operator==(const Polycube& other) const {\n        return cells == other.cells;\n    }\n    int volume() const { return cells.size(); }\n};\n\n// Global parameters\nint D;\nvector<string> f1_str, r1_str, f2_str, r2_str;\nvector<bool> G1_grid, G2_grid; // G1_grid[idx] is true if cell can be occupied for obj1\n\n// Helper to create a 3D grid vector\ntemplate<typename T>\nvector<T> create_grid_vec(size_t size, T default_val) {\n    return vector<T>(size, default_val);\n}\n\n// Convert string silhouettes to boolean grids representing valid cell locations\nvoid setup_grids() {\n    G1_grid.assign(D * D * D, false);\n    G2_grid.assign(D * D * D, false);\n\n    // For object 1, a cell (x,y,z) can be occupied if f1(z,x)=1 and r1(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int x = 0; x < D; ++x) {\n            if (f1_str[z][x] == '1') {\n                for (int y = 0; y < D; ++y) {\n                    if (r1_str[z][y] == '1') {\n                        GRID_GET(G1_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // For object 2, a cell (x,y,z) can be occupied if f2(z,x)=1 and r2(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int y = 0; y < D; ++y) {\n            if (r2_str[z][y] == '1') {\n                for (int x = 0; x < D; ++x) {\n                    if (f2_str[z][x] == '1') {\n                        GRID_GET(G2_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalize a polycube: translate its cells so the minimum coordinate is (0,0,0)\n// and sort the cells lexicographically. This gives a canonical representation for translation.\nPolycube normalize(const Polycube& poly) {\n    if (poly.cells.empty()) return poly;\n    int min_x = get<0>(poly.cells[0]);\n    int min_y = get<1>(poly.cells[0]);\n    int min_z = get<2>(poly.cells[0]);\n    for (const auto& cell : poly.cells) {\n        min_x = min(min_x, get<0>(cell));\n        min_y = min(min_y, get<1>(cell));\n        min_z = min(min_z, get<2>(cell));\n    }\n    Polycube normalized_poly;\n    normalized_poly.cells.reserve(poly.cells.size());\n    for (const auto& cell : poly.cells) {\n        normalized_poly.cells.emplace_back(get<0>(cell) - min_x, get<1>(cell) - min_y, get<2>(cell) - min_z);\n    }\n    sort(normalized_poly.cells.begin(), normalized_poly.cells.end());\n    return normalized_poly;\n}\n\n// Generate all 24 unique orientations (rotations) of a polycube\nvector<Polycube> get_orientations(const Polycube& poly) {\n    set<Polycube> unique_orientations;\n    \n    vector<tuple<int,int,int>> current_cells = poly.cells;\n\n    // Apply rotations around X, Y, Z axes\n    // Loop 4 times for each axis to cover 0, 90, 180, 270 degrees\n    for (int rotx = 0; rotx < 4; ++rotx) { // Rotations around X-axis\n        vector<tuple<int,int,int>> current_cells_y = current_cells;\n        for (int roty = 0; roty < 4; ++roty) { // Rotations around Y-axis\n            vector<tuple<int,int,int>> current_cells_z = current_cells_y;\n            for (int rotz = 0; rotz < 4; ++rotz) { // Rotations around Z-axis\n                Polycube oriented_poly;\n                oriented_poly.cells = current_cells_z;\n                unique_orientations.insert(normalize(oriented_poly));\n                \n                // Rotate around Z: (x, y, z) -> (-y, x, z)\n                vector<tuple<int,int,int>> next_z;\n                next_z.reserve(current_cells_z.size());\n                for(const auto& cell : current_cells_z) {\n                    next_z.emplace_back(-get<1>(cell), get<0>(cell), get<2>(cell));\n                }\n                current_cells_z = next_z;\n            }\n            // Rotate around Y: (x, y, z) -> (z, y, -x)\n            vector<tuple<int,int,int>> next_y;\n            next_y.reserve(current_cells_y.size());\n            for(const auto& cell : current_cells_y) {\n                next_y.emplace_back(get<2>(cell), get<1>(cell), -get<0>(cell));\n            }\n            current_cells_y = next_y;\n        }\n        // Rotate around X: (x, y, z) -> (x, -z, y)\n        vector<tuple<int,int,int>> next_x;\n        next_x.reserve(current_cells.size());\n        for(const auto& cell : current_cells) {\n            next_x.emplace_back(get<0>(cell), -get<2>(cell), get<1>(cell));\n        }\n        current_cells = next_x;\n    }\n\n    vector<Polycube> orientations;\n    orientations.reserve(unique_orientations.size());\n    for (const auto& p : unique_orientations) {\n        orientations.push_back(p);\n    }\n    return orientations;\n}\n\n// Map to store canonical form of a polycube to its assigned unique ID\nmap<Polycube, int> canonical_shape_to_id;\nint next_block_id; // Counter for assigning new block IDs\n\n// Store final block assignments for each object\nstruct BlockAssignment {\n    int id;\n    Polycube shape;\n};\nvector<BlockAssignment> assignments1, assignments2;\n\n// Utility to check if a cell coordinate is within the DxD D grid bounds\nbool is_valid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n    \n// Attempt to place a given block_shape at (target_x, target_y, target_z)\n// The target cell must be uncovered and valid for the current object.\n// Returns true if a valid placement is found, false otherwise.\n// placed_block_out will contain the normalized, placed polycube if successful.\nbool try_place(const Polycube& block_shape, int target_x, int target_y, int target_z,\n               const vector<bool>& G, // Grid indicating valid cell locations\n               const vector<bool>& covered, // Grid indicating already occupied cells\n               Polycube& placed_block_out) {\n\n    // Iterate through each cell of the block_shape. Try to align this cell with (target_x, target_y, target_z).\n    // This determines the potential origin of the block if it were placed.\n    for (const auto& cell_in_shape : block_shape.cells) {\n        int shape_cell_x, shape_cell_y, shape_cell_z;\n        tie(shape_cell_x, shape_cell_y, shape_cell_z) = cell_in_shape;\n\n        // Calculate the potential origin of the block in the grid\n        int origin_x = target_x - shape_cell_x;\n        int origin_y = target_y - shape_cell_y;\n        int origin_z = target_z - shape_cell_z;\n\n        Polycube current_placement_poly;\n        bool possible = true;\n\n        // Check if all cells of the block, when placed at this origin, are valid\n        for (const auto& cell_in_shape_ : block_shape.cells) {\n            int cx, cy, cz;\n            tie(cx, cy, cz) = cell_in_shape_;\n            int px = origin_x + cx;\n            int py = origin_y + cy;\n            int pz = origin_z + cz;\n\n            // Check boundaries, if cell is allowed by G, and if it's not already covered\n            if (!is_valid(px, py, pz) || !GRID_GET(G, px, py, pz, D) || GRID_GET(covered, px, py, pz, D)) {\n                possible = false;\n                break;\n            }\n            current_placement_poly.cells.emplace_back(px, py, pz);\n        }\n\n        if (possible) {\n            // Found a valid placement. Normalize it and return.\n            placed_block_out = normalize(current_placement_poly);\n            return true;\n        }\n    }\n    return false; // No valid placement found for this block shape at this target cell\n}\n\n// Greedily fill the target grid G with blocks from the library.\n// Prioritizes larger blocks.\nvoid fill_object(const vector<bool>& G,\n                 vector<bool>& covered,\n                 vector<BlockAssignment>& assignments,\n                 bool is_object1) {\n\n    // Library of candidate block shapes with their volumes.\n    // These are basic polycubes. More complex ones could be generated from components of G.\n    vector<pair<int, Polycube>> candidate_blocks_with_vol; // volume, shape\n    \n    // Basic shapes (monomino, domino, trominoes, tetrominoes)\n    candidate_blocks_with_vol.push_back({1, {{{0,0,0}}}}); // Monomino\n    candidate_blocks_with_vol.push_back({2, {{{0,0,0}, {1,0,0}}}}); // Domino (linear)\n    candidate_blocks_with_vol.push_back({3, {{{0,0,0}, {1,0,0}, {2,0,0}}}}); // Tromino (linear)\n    candidate_blocks_with_vol.push_back({3, {{{0,0,0}, {1,0,0}, {0,1,0}}}}); // Tromino (L)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}}}}); // Tetromino (square)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {3,0,0}}}}); // Tetromino (linear I)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}}}}); // Tetromino (linear I vertical)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {1,1,0}}}}); // Tetromino (T)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {2,1,0}}}}); // Tetromino (L)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {1,1,0}, {2,1,0}}}}); // Tetromino (skew)\n    // Add more shapes if needed (e.g., pentominoes)\n\n    // TODO: Optionally, generate connected components from G and add their shapes to candidate_blocks_with_vol.\n    // This part is omitted for simplicity in this example, focusing on a fixed library.\n\n    // Sort candidate blocks by volume in descending order to prioritize larger blocks\n    sort(candidate_blocks_with_vol.rbegin(), candidate_blocks_with_vol.rend());\n\n    // Pre-calculate all orientations for each library block shape\n    vector<pair<int, vector<Polycube>>> library_orientations; // volume, list of orientations\n    for(auto const& [vol, shape] : candidate_blocks_with_vol) {\n        library_orientations.push_back({vol, get_orientations(shape)});\n    }\n\n    // Iterate through all cells of the grid. If a cell must be filled (in G) and is not yet covered:\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 (GRID_GET(G, x, y, z, D) && !GRID_GET(covered, x, y, z, D)) {\n                    // Found an uncovered cell that must be filled\n                    \n                    bool placed_best_block_this_turn = false;\n                    Polycube best_placed_shape; // The actual placed shape in the grid\n                    int best_block_id = -1;\n                    int max_volume_placed = -1; // Track the volume of the best block placed for this cell\n\n                    // Try to place the largest possible block from the library that fits\n                    for (const auto& lib_item : library_orientations) {\n                        int current_vol = lib_item.first;\n                        const vector<Polycube>& orientations = lib_item.second;\n                        \n                        // Optimization: If the current block's volume is less than or equal to the best one\n                        // already found for this cell, we can skip it.\n                        if (placed_best_block_this_turn && current_vol <= max_volume_placed) continue;\n\n                        for (const auto& oriented_shape : orientations) {\n                            Polycube placed_block;\n                            \n                            // Attempt to place the oriented shape to cover (x,y,z)\n                            if (try_place(oriented_shape, x, y, z, G, covered, placed_block)) {\n                                \n                                // If placement is successful, get its canonical form to check for shared blocks\n                                Polycube canonical_shape = normalize(placed_block);\n                                int current_id;\n\n                                // Assign an existing ID if this shape has been used before, otherwise assign a new one\n                                if (canonical_shape_to_id.count(canonical_shape)) {\n                                    current_id = canonical_shape_to_id[canonical_shape];\n                                } else {\n                                    current_id = next_block_id++;\n                                    canonical_shape_to_id[canonical_shape] = current_id;\n                                }\n\n                                // Update the best placement found for this cell if this block is larger\n                                if (!placed_best_block_this_turn || current_vol > max_volume_placed) {\n                                    best_placed_shape = placed_block;\n                                    best_block_id = current_id;\n                                    max_volume_placed = current_vol;\n                                    placed_best_block_this_turn = true;\n                                }\n                            }\n                        }\n                    }\n\n                    // If a block was successfully placed, apply it to the grid and assignments\n                    if (placed_best_block_this_turn) {\n                        assignments.push_back({best_block_id, best_placed_shape});\n                        // Mark all cells occupied by this block as covered\n                        for (const auto& cell : best_placed_shape.cells) {\n                            GRID_GET(covered, get<0>(cell), get<1>(cell), get<2>(cell), D) = true;\n                        }\n                    } else {\n                        // Fallback: If no block from the library could be placed, use a 1x1x1 unit block.\n                        Polycube unit_block = {{{0,0,0}}}; // A single cell at relative (0,0,0)\n                        Polycube canonical_unit = normalize(unit_block);\n                        int current_id;\n                        // Assign ID for unit block (it will be a new ID if not used before)\n                        if (canonical_shape_to_id.count(canonical_unit)) {\n                            current_id = canonical_shape_to_id[canonical_unit];\n                        } else {\n                            current_id = next_block_id++;\n                            canonical_shape_to_id[canonical_unit] = current_id;\n                        }\n                        assignments.push_back({current_id, unit_block});\n                        GRID_GET(covered, x, y, z, D) = true; // Mark this single cell as covered\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input D (dimension of the grid)\n    cin >> D;\n    \n    // Resize input strings for silhouettes\n    f1_str.resize(D); r1_str.resize(D);\n    f2_str.resize(D); r2_str.resize(D);\n\n    // Read the four silhouette images\n    for (int i = 0; i < D; ++i) cin >> f1_str[i];\n    for (int i = 0; i < D; ++i) cin >> r1_str[i];\n    for (int i = 0; i < D; ++i) cin >> f2_str[i];\n    for (int i = 0; i < D; ++i) cin >> r2_str[i];\n\n    // Initialize the grids that define where cells can be occupied\n    setup_grids();\n\n    // --- Filling for Object 1 ---\n    next_block_id = 1; // Reset block ID counter for each object, shared IDs are managed by map\n    canonical_shape_to_id.clear(); // Clear map for potentially new shared blocks\n    assignments1.clear(); // Clear previous assignments\n    vector<bool> covered1(D * D * D, false); // Track covered cells for object 1\n    fill_object(G1_grid, covered1, assignments1, true); // Call the greedy fill function\n\n    // --- Filling for Object 2 ---\n    // Note: canonical_shape_to_id is NOT cleared here. This ensures that if a shape\n    // used in object 1 is also used in object 2, it gets the same ID.\n    vector<bool> covered2(D * D * D, false); // Track covered cells for object 2\n    assignments2.clear(); // Clear previous assignments\n    fill_object(G2_grid, covered2, assignments2, false); // Call the greedy fill function\n\n    // --- Output ---\n    // The total number of unique blocks used across both objects\n    cout << next_block_id - 1 << endl;\n\n    // Output the block assignments for object 1\n    vector<int> b1_output(D * D * D, 0);\n    for (const auto& assign : assignments1) {\n        for (const auto& cell : assign.shape.cells) {\n            GRID_WRITE(b1_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b1_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    // Output the block assignments for object 2\n    vector<int> b2_output(D * D * D, 0);\n    for (const auto& assign : assignments2) {\n        for (const auto& cell : assign.shape.cells) {\n            GRID_WRITE(b2_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b2_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <set>\n#include <queue>\n\n// Use long double for precision in distance calculations\nusing ftype = long double;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n    ftype dist_sq; // Squared Euclidean distance\n};\n\nstruct Resident {\n    int id;\n    Point pos;\n};\n\nint N_stations_global, M_edges_global, K_residents_global;\nstd::vector<Point> station_pos_global;\nstd::vector<Edge> edges_global;\nstd::vector<Resident> residents_global;\n\n// Precomputed distances: dists[i][k] is distance from station i to resident k\nstd::vector<std::vector<ftype>> dists_global;\n\n// Function to calculate squared Euclidean distance between two points\nftype distSq(Point p1, Point p2) {\n    ftype dx = static_cast<ftype>(p1.x) - p2.x;\n    ftype dy = static_cast<ftype>(p1.y) - p2.y;\n    return dx * dx + dy * dy;\n}\n\n// Function to calculate Euclidean distance\nftype dist(Point p1, Point p2) {\n    return std::sqrt(distSq(p1, p2));\n}\n\n// Check connectivity of V_prime from station 0\nbool is_connected(int start_node, const std::vector<int>& V_prime_indices, const std::vector<int>& edge_indices_B) {\n    if (V_prime_indices.empty()) return true;\n    \n    std::vector<bool> is_in_V_prime(N_stations_global, false);\n    for(int idx : V_prime_indices) is_in_V_prime[idx] = true;\n\n    std::vector<std::vector<int>> adj(N_stations_global);\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (edge_indices_B[j]) {\n            adj[edges_global[j].u - 1].push_back(edges_global[j].v - 1);\n            adj[edges_global[j].v - 1].push_back(edges_global[j].u - 1);\n        }\n    }\n\n    std::vector<bool> visited(N_stations_global, false);\n    std::queue<int> q;\n\n    // Find the first node in V_prime to start BFS from. It must be connected to vertex 1.\n    // If vertex 1 itself is not in V_prime, this check is different.\n    // The problem guarantees station 1 is at (0,0) and it's the source.\n    // So we always check connectivity from station 0 (which is vertex 1).\n    if (!is_in_V_prime[start_node]) return false; // Source must be in V_prime\n\n    q.push(start_node);\n    visited[start_node] = true;\n    int count_visited_in_V_prime = 0;\n    if (is_in_V_prime[start_node]) count_visited_in_V_prime++;\n\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n\n        for (int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                if (is_in_V_prime[v]) {\n                    count_visited_in_V_prime++;\n                }\n            }\n        }\n    }\n    \n    // Check if all stations in V_prime are reachable from start_node\n    return count_visited_in_V_prime == V_prime_indices.size();\n}\n\n// Calculate total cost\nlong long calculate_total_cost(const std::vector<int>& P, const std::vector<int>& B) {\n    long long edge_cost = 0;\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (B[j]) {\n            edge_cost += edges_global[j].w;\n        }\n    }\n    long long station_cost = 0;\n    for (int i = 0; i < N_stations_global; ++i) {\n        station_cost += static_cast<long long>(P[i]) * P[i];\n    }\n    return station_cost + edge_cost;\n}\n\n// Represents a potential connection for coverage\nstruct CoverageOption {\n    ftype radius; // d_ik\n    int station_idx; // i\n    int resident_idx; // k\n\n    bool operator<(const CoverageOption& other) const {\n        return radius < other.radius;\n    }\n};\n\n// Greedy assignment for P_i values using marginal cost\nstd::vector<int> solve_P_greedy_marginal_cost(const std::vector<int>& V_prime_indices) {\n    std::vector<int> P(N_stations_global, 0);\n    std::vector<bool> resident_covered(K_residents_global, false);\n    int uncovered_count = K_residents_global;\n    \n    std::vector<int> current_V_prime_indices = V_prime_indices; // Copy V_prime\n\n    int iterations = 0;\n    const int MAX_ITER = 2 * K_residents_global + 50; // Heuristic limit\n\n    while (uncovered_count > 0 && iterations < MAX_ITER) {\n        iterations++;\n        \n        int best_resident_to_cover = -1;\n        int best_station_to_use = -1;\n        long long min_marginal_cost = -1; \n\n        // Find an uncovered resident and a station to cover it with minimum marginal cost\n        for(int k = 0; k < K_residents_global; ++k) {\n            if (!resident_covered[k]) {\n                for(int station_idx : current_V_prime_indices) {\n                    ftype d = dists_global[station_idx][k];\n                    if (d > 5000.0) continue; // Station cannot cover this resident within limit\n\n                    int required_p_int = static_cast<int>(std::ceil(d));\n                    if (required_p_int > 5000) required_p_int = 5000;\n\n                    long long current_p_sq = static_cast<long long>(P[station_idx]) * P[station_idx];\n                    long long new_p_val = std::max(P[station_idx], required_p_int);\n                    long long new_p_sq = new_p_val * new_p_val;\n                    \n                    long long marginal_cost = new_p_sq - current_p_sq;\n\n                    if (best_station_to_use == -1 || marginal_cost < min_marginal_cost) {\n                        min_marginal_cost = marginal_cost;\n                        best_station_to_use = station_idx;\n                        best_resident_to_cover = k;\n                    } else if (marginal_cost == min_marginal_cost) {\n                        // Tie-breaking: prefer smaller radius, then smaller current P, then smaller station index\n                        ftype current_best_d = dists_global[best_station_to_use][best_resident_to_cover];\n                        ftype new_d = d;\n                        if (new_d < current_best_d) {\n                            best_station_to_use = station_idx;\n                            best_resident_to_cover = k;\n                        } else if (new_d == current_best_d) {\n                            if (P[station_idx] < P[best_station_to_use]) {\n                                best_station_to_use = station_idx;\n                                best_resident_to_cover = k;\n                            } else if (P[station_idx] == P[best_station_to_use]) {\n                                if (station_idx < best_station_to_use) {\n                                     best_station_to_use = station_idx;\n                                     best_resident_to_cover = k;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_station_to_use != -1) {\n            // Update P for the chosen station\n            ftype d = dists_global[best_station_to_use][best_resident_to_cover];\n            int required_p_int = static_cast<int>(std::ceil(d));\n            if (required_p_int > 5000) required_p_int = 5000;\n            P[best_station_to_use] = std::max(P[best_station_to_use], required_p_int);\n            \n            // Update coverage status for all residents\n            int newly_covered_in_this_step = 0;\n            for(int k=0; k<K_residents_global; ++k) {\n                if (!resident_covered[k]) {\n                    ftype d_k = dists_global[best_station_to_use][k];\n                    if (d_k <= P[best_station_to_use]) {\n                        resident_covered[k] = true;\n                        newly_covered_in_this_step++;\n                    }\n                }\n            }\n            uncovered_count -= newly_covered_in_this_step;\n        } else {\n            // Cannot cover any more residents with available stations and P <= 5000.\n            // This could happen if remaining residents require radii > 5000 from available stations.\n            // Based on problem statement, this shouldn't be the case unless V_prime is too small.\n            break; \n        }\n    }\n\n    // Final fallback: ensure all residents are covered. If not, increase P of closest station to 5000.\n    if (uncovered_count > 0) {\n        for(int k=0; k<K_residents_global; ++k) {\n            if (!resident_covered[k]) {\n                ftype min_d = 5001.0;\n                int best_station_idx = -1;\n                for (int station_idx : current_V_prime_indices) {\n                    ftype d = dists_global[station_idx][k];\n                    if (d < min_d) {\n                        min_d = d;\n                        best_station_idx = station_idx;\n                    }\n                }\n                if (best_station_idx != -1 && min_d <= 5000.0) {\n                    P[best_station_idx] = std::max(P[best_station_to_use], 5000); // Force coverage\n                    // Mark all residents as covered by this station if P is now 5000\n                    for(int kk=0; kk<K_residents_global; ++kk) {\n                        if (!resident_covered[kk]) {\n                            ftype d_kk = dists_global[best_station_to_use][kk];\n                            if (d_kk <= P[best_station_to_use]) {\n                                resident_covered[kk] = true;\n                                uncovered_count--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return P;\n}\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> N_stations_global >> M_edges_global >> K_residents_global;\n\n    station_pos_global.resize(N_stations_global);\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cin >> station_pos_global[i].x >> station_pos_global[i].y;\n    }\n\n    edges_global.resize(M_edges_global);\n    for (int i = 0; i < M_edges_global; ++i) {\n        edges_global[i].id = i;\n        std::cin >> edges_global[i].u >> edges_global[i].v >> edges_global[i].w;\n        edges_global[i].u--; // 0-indexed\n        edges_global[i].v--; // 0-indexed\n        edges_global[i].dist_sq = distSq(station_pos_global[edges_global[i].u], station_pos_global[edges_global[i].v]);\n    }\n\n    residents_global.resize(K_residents_global);\n    for (int i = 0; i < K_residents_global; ++i) {\n        residents_global[i].id = i;\n        std::cin >> residents_global[i].pos.x >> residents_global[i].pos.y;\n    }\n\n    // 1. Precompute all distances\n    dists_global.resize(N_stations_global, std::vector<ftype>(K_residents_global));\n    for (int i = 0; i < N_stations_global; ++i) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            dists_global[i][k] = dist(station_pos_global[i], residents_global[k].pos);\n        }\n    }\n\n    // 2. Initial Connectivity: Use Minimum Spanning Tree (Kruskal's algorithm)\n    std::sort(edges_global.begin(), edges_global.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    std::vector<int> parent(N_stations_global);\n    std::iota(parent.begin(), parent.end(), 0);\n    auto find_set = [&](auto self, int v) -> int {\n        if (v == parent[v]) return v;\n        return parent[v] = self(self, parent[v]);\n    };\n    auto unite_sets = [&](int a, int b) -> bool {\n        a = find_set(find_set, a);\n        b = find_set(find_set, b);\n        if (a != b) {\n            parent[b] = a;\n            return true;\n        }\n        return false;\n    };\n\n    std::vector<int> B_mst(M_edges_global, 0);\n    std::vector<int> mst_edge_indices;\n    int edges_count = 0;\n    for (const auto& edge : edges_global) {\n        if (unite_sets(edge.u, edge.v)) {\n            B_mst[edge.id] = 1;\n            mst_edge_indices.push_back(edge.id);\n            edges_count++;\n            if (edges_count == N_stations_global - 1) break;\n        }\n    }\n    // If graph was not connected initially, MST might not span all nodes.\n    // However, problem statement guarantees a connected graph.\n\n    // 3. Edge Pruning (Iterative Improvement)\n    std::vector<int> B = B_mst; // Start with MST edges\n    std::vector<int> current_V_prime_indices;\n    \n    // Sort edges by weight for pruning\n    std::vector<Edge> sorted_edges = edges_global;\n    std::sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    // Try to remove edges in increasing order of weight\n    for (const auto& edge_to_consider : sorted_edges) {\n        int edge_id = edge_to_consider.id;\n        \n        // Temporarily remove the edge\n        B[edge_id] = 0;\n\n        // Determine V_prime with the current set of active edges B\n        std::vector<int> temp_V_prime_indices;\n        std::vector<bool> station_in_V_prime(N_stations_global, false);\n        \n        std::vector<std::vector<int>> adj(N_stations_global);\n        for(int j=0; j<M_edges_global; ++j) {\n            if (B[j]) {\n                adj[edges_global[j].u].push_back(edges_global[j].v);\n                adj[edges_global[j].v].push_back(edges_global[j].u);\n            }\n        }\n\n        std::queue<int> q;\n        if (!adj[0].empty() || N_stations_global == 1) { // Station 0 must be reachable from itself\n            q.push(0);\n            station_in_V_prime[0] = true;\n            temp_V_prime_indices.push_back(0);\n        }\n        \n        std::vector<bool> visited(N_stations_global, false);\n        visited[0] = true;\n        \n        while(!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for(int v : adj[u]) {\n                if (!visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                    station_in_V_prime[v] = true;\n                    temp_V_prime_indices.push_back(v);\n                }\n            }\n        }\n        \n        // Check if removing this edge disconnects any station that *might* need power ON (i.e. P > 0)\n        // Initially, we don't know P. So we need all stations to be reachable from 0.\n        // The strategy is: prune edges until all stations are disconnected from station 0.\n        // Then, we must re-add edges to ensure connectivity for stations that *will* have P_i > 0.\n        // This is tricky. A simpler pruning: remove edges that are not part of any minimal spanning tree connecting {0} to {stations that will have P_i > 0}.\n        // Let's try: remove edge if all stations that will have P_i > 0 are still reachable.\n        // For now, assume we need to connect all stations.\n        \n        // A simpler pruning: if removing edge disconnects the graph of currently active edges, put it back.\n        // This means `temp_V_prime_indices` should contain all N_stations_global IF we initially connect all.\n        // If `temp_V_prime_indices.size() != N_stations_global`, then removing this edge disconnects the component.\n        // If we want to ensure all stations are potentially usable, we need to keep edges that keep the graph connected.\n        \n        // A more accurate check: after pruning, will all stations that are *needed* (i.e., will have P_i > 0) be reachable?\n        // This is hard to know beforehand. Let's simplify: we must connect station 0 to all stations *that we decide to use*.\n        // For now, let's try to keep a connected component of all stations from station 0.\n\n        if (temp_V_prime_indices.size() < N_stations_global) {\n            // Removing this edge disconnected the graph. Restore it.\n            B[edge_id] = 1;\n        }\n    }\n\n    // 4. Assign initial P values for the determined V_prime\n    // First, get the final V_prime based on the pruned edges B\n    current_V_prime_indices.clear();\n    std::vector<bool> station_in_V_prime(N_stations_global, false);\n    \n    std::vector<std::vector<int>> adj(N_stations_global);\n    for(int j=0; j<M_edges_global; ++j) {\n        if (B[j]) {\n            adj[edges_global[j].u].push_back(edges_global[j].v);\n            adj[edges_global[j].v].push_back(edges_global[j].u);\n        }\n    }\n\n    std::queue<int> q;\n    if (!adj[0].empty() || N_stations_global == 1) { // Station 0 is always source\n        q.push(0);\n        station_in_V_prime[0] = true;\n        current_V_prime_indices.push_back(0);\n    }\n    \n    std::vector<bool> visited(N_stations_global, false);\n    visited[0] = true;\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for(int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                station_in_V_prime[v] = true;\n                current_V_prime_indices.push_back(v);\n            }\n        }\n    }\n    \n    // Now, `current_V_prime_indices` contains all stations reachable from station 0.\n    // Assign P values using the greedy marginal cost approach for the determined V_prime.\n    std::vector<int> P = solve_P_greedy_marginal_cost(current_V_prime_indices);\n\n    // 5. Local Search / Iterative Refinement (Optional but good for score)\n    // This part is complex and time-consuming. For a contest heuristic, we might skip this\n    // or implement a very simple version.\n    // Example: Try removing edges one by one again, and re-optimizing P.\n    // If total cost decreases, keep the edge removed.\n\n    // Let's try a simple local search for edge removal and P re-optimization.\n    // Iterate multiple times to allow for cascading improvements.\n    // Maximum number of local search iterations.\n    const int LOCAL_SEARCH_ITER = 10000; \n\n    for(int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        bool improved = false;\n\n        // --- Edge Removal ---\n        // Try removing edges by increasing weight\n        std::vector<Edge> edges_to_try_removing = edges_global;\n        std::sort(edges_to_try_removing.begin(), edges_to_try_removing.end(), [](const Edge& a, const Edge& b) {\n            return a.w < b.w;\n        });\n\n        for (const auto& edge_to_consider : edges_to_try_removing) {\n            int edge_id = edge_to_consider.id;\n            if (B[edge_id] == 0) continue; // Already removed\n\n            // Temporarily remove the edge\n            B[edge_id] = 0;\n\n            // Determine new V_prime\n            current_V_prime_indices.clear();\n            std::fill(station_in_V_prime.begin(), station_in_V_prime.end(), false);\n            std::fill(&adj[0][0], &adj[0][0] + N_stations_global * N_stations_global, 0); // Clear adjacency list\n            for(int j=0; j<M_edges_global; ++j) {\n                if (B[j]) {\n                    adj[edges_global[j].u].push_back(edges_global[j].v);\n                    adj[edges_global[j].v].push_back(edges_global[j].u);\n                }\n            }\n            \n            std::queue<int> q_ls;\n            if (!adj[0].empty() || N_stations_global == 1) {\n                q_ls.push(0);\n                station_in_V_prime[0] = true;\n                current_V_prime_indices.push_back(0);\n            }\n            std::vector<bool> visited_ls(N_stations_global, false);\n            visited_ls[0] = true;\n            \n            while(!q_ls.empty()) {\n                int u = q_ls.front();\n                q_ls.pop();\n                for(int v : adj[u]) {\n                    if (!visited_ls[v]) {\n                        visited_ls[v] = true;\n                        q_ls.push(v);\n                        station_in_V_prime[v] = true;\n                        current_V_prime_indices.push_back(v);\n                    }\n                }\n            }\n\n            // Re-solve P values for the new V_prime\n            std::vector<int> next_P = solve_P_greedy_marginal_cost(current_V_prime_indices);\n            \n            // Calculate cost\n            long long current_total_cost = calculate_total_cost(P, B); // Cost before removing edge_id\n            long long next_total_cost = calculate_total_cost(next_P, B);\n            \n            // Check if this move is valid and improves the solution\n            // Validity: all residents must be covered by next_P and next_V_prime\n            bool coverage_ok = true;\n            if (current_V_prime_indices.empty() && K_residents_global > 0) coverage_ok = false;\n            else {\n                std::vector<bool> covered(K_residents_global, false);\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    for(int station_idx : current_V_prime_indices) {\n                        if (next_P[station_idx] > 0 && dists_global[station_idx][k] <= next_P[station_idx]) {\n                            covered[k] = true;\n                            break;\n                        }\n                    }\n                    if(covered[k]) covered_count++;\n                }\n                if (covered_count < K_residents_global) coverage_ok = false;\n            }\n\n            if (coverage_ok && next_total_cost < current_total_cost) {\n                P = next_P; // Update P values\n                // B is already updated (edge_id is 0)\n                improved = true;\n            } else {\n                // Revert the change\n                B[edge_id] = 1;\n            }\n        }\n        \n        // --- P Value Adjustment ---\n        // Try to decrease P values for stations in V_prime\n        if (!current_V_prime_indices.empty()) {\n            int station_to_adjust = current_V_prime_indices[rand() % current_V_prime_indices.size()]; // Pick random station in V_prime\n            \n            if (P[station_to_adjust] > 0) {\n                int original_P = P[station_to_adjust];\n                P[station_to_adjust]--; // Try decreasing P by 1\n                \n                // Re-check coverage. This is slow. A quicker check:\n                // Which residents are ONLY covered by this station with original P?\n                // If decreasing P makes them uncovered, we must revert or increase P elsewhere.\n                \n                // Full check:\n                long long cost_before_p_adjust = calculate_total_cost(P, B); // P still has original value here\n                //temporarily P is decreased\n                P[station_to_adjust]--;\n                \n                // Check coverage with new P\n                bool coverage_ok = true;\n                std::vector<bool> covered(K_residents_global, false);\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    for(int station_idx : current_V_prime_indices) {\n                         if (P[station_idx] > 0 && dists_global[station_idx][k] <= P[station_idx]) {\n                            covered[k] = true;\n                            break;\n                        }\n                    }\n                    if(covered[k]) covered_count++;\n                }\n                if (covered_count < K_residents_global) coverage_ok = false;\n                \n                long long cost_after_p_adjust = calculate_total_cost(P, B);\n\n                if (coverage_ok && cost_after_p_adjust < cost_before_p_adjust) {\n                    // Keep the decrease\n                    improved = true;\n                } else {\n                    // Revert\n                    P[station_to_adjust] = original_P;\n                }\n            }\n        }\n\n        if (!improved) break; // Stop if no improvement in an iteration\n    }\n\n    // Output final P values and B values\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cout << P[i] << (i == N_stations_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n    for (int j = 0; j < M_edges_global; ++j) {\n        std::cout << B[j] << (j == M_edges_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <map>\n\n// Maximum number of tiers\nconst int N = 30;\n// Total number of balls\nconst int M = N * (N + 1) / 2;\n\n// Structure to represent coordinates (tier x, position y)\nstruct Coord {\n    int x, y;\n\n    // Operator overloading for map keys and comparisons\n    bool operator<(const Coord& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Coord& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Convert pyramid coordinates (x, y) to a linear index.\n// This index is used to define the target state: ball with value `idx` should be at the coordinate with index `idx`.\nint get_idx_from_coord(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Map to store current ball values at their coordinates.\n    // Key: Coord, Value: ball value\n    std::map<Coord, int> current_values_map;\n    // Vector to store all valid coordinates in the pyramid.\n    // This allows iterating through balls and their positions.\n    std::vector<Coord> all_coords;\n    all_coords.reserve(M);\n\n    // Read input and populate initial state\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            Coord c = {x, y};\n            all_coords.push_back(c);\n            int value;\n            std::cin >> value;\n            current_values_map[c] = value;\n        }\n    }\n\n    // Store performed swaps. Each swap is represented by two adjacent coordinates.\n    std::vector<std::pair<Coord, Coord>> swaps;\n    const int MAX_SWAPS = 10000;\n\n    // Heuristic strategy:\n    // The problem asks to satisfy V(x,y) < V(x+1,y) and V(x,y) < V(x+1,y+1)\n    // with minimal operations K and violations E. The scoring heavily favors E=0.\n    // The target configuration that achieves E=0 is when ball with value `idx` is at the coordinate with index `idx`.\n    // i.e., current_values_map[{x,y}] == get_idx_from_coord(x,y).\n    // Since K is limited to 10000, we cannot guarantee reaching E=0 if it requires too many swaps.\n    // We perform up to MAX_SWAPS operations. In each operation, we greedily pick a swap that\n    // moves balls towards their target configuration.\n    // A swap is chosen if it swaps two adjacent balls c1 and c2 such that their current values\n    // violate the target order, i.e., V(c1) > V(c2) but target_idx(c1) < target_idx(c2).\n    // Swapping them moves a smaller value to the position that should have a smaller index value,\n    // and a larger value to the position that should have a larger index value.\n    // This is similar to a limited number of passes of bubble sort on the graph.\n\n    // Define relative coordinates for the 6 possible adjacent moves\n    int dx[] = {1, 1, 0, 0, -1, -1}; // change in x\n    int dy[] = {0, 1, 1, -1, 0, 1}; // change in y\n\n    for (int k = 0; k < MAX_SWAPS; ++k) {\n        bool swapped_in_this_pass = false;\n        \n        // Iterate through all balls and their potential neighbors\n        for (Coord c1 : all_coords) {\n            int val1 = current_values_map[c1];\n            int idx1 = get_idx_from_coord(c1.x, c1.y);\n\n            // Check each of the 6 possible adjacent neighbors\n            for (int i = 0; i < 6; ++i) {\n                Coord c2 = {c1.x + dx[i], c1.y + dy[i]};\n\n                // Check if the neighbor coordinate c2 is valid within the pyramid\n                if (c2.x < 0 || c2.x >= N || c2.y < 0 || c2.y > c2.x) {\n                    continue; // c2 is outside the pyramid\n                }\n\n                int val2 = current_values_map[c2];\n                int idx2 = get_idx_from_coord(c2.x, c2.y);\n\n                // Check if the current values violate the target order.\n                // Target order: smaller index should have smaller value.\n                // If idx1 < idx2 but val1 > val2, it's a violation. Swapping them is beneficial.\n                // We prioritize swapping c1 and c2 where idx1 < idx2 because it means\n                // c1 is \"higher\" in the conceptual sorted order.\n                // This greedy choice ensures we are moving smaller values \"up\".\n                if (idx1 < idx2 && val1 > val2) {\n                    // Found a pair (c1, c2) that violates target order and are adjacent.\n                    // Swap their values.\n                    current_values_map[c1] = val2;\n                    current_values_map[c2] = val1;\n                    \n                    // Record the swap operation\n                    // The problem output format requires (x1,y1) (x2,y2) where (x1,y1) and (x2,y2) are adjacent.\n                    // We store the swap that moves val2 to c1 and val1 to c2.\n                    swaps.push_back({c1, c2});\n                    swapped_in_this_pass = true;\n                    \n                    // If we reach MAX_SWAPS, stop immediately.\n                    if (swaps.size() >= MAX_SWAPS) {\n                        goto end_sorting; // Exit loops\n                    }\n                    \n                    // After a swap, it's good practice to re-evaluate from the start or\n                    // focus on the affected area. For simplicity and given the swap limit,\n                    // we continue checking other pairs in this pass, or restart.\n                    // A full restart from all_coords might be too slow.\n                    // Continuing the loop is a form of limited bubble sort pass.\n                }\n            }\n        }\n        \n        // If no swaps were made in a full pass, the configuration might be stable\n        // or stuck in a local optimum. Given the swap limit, we just continue up to MAX_SWAPS.\n        // No explicit break here if no swaps occurred, as we must reach MAX_SWAPS if possible.\n        // If MAX_SWAPS is reached, we exit via goto.\n    }\n\nend_sorting:\n\n    // Output the number of operations and the operations themselves\n    std::cout << swaps.size() << std::endl;\n    for (const auto& sw : swaps) {\n        std::cout << sw.first.x << \" \" << sw.first.y << \" \" << sw.second.x << \" \" << sw.second.y << std::endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions and properties\nconst int MAX_D = 9; // D is fixed at 9 for all test cases\nint D;\nbool is_obstacle[MAX_D][MAX_D];\nint dist[MAX_D][MAX_D];\npair<int, int> entrance;\n\n// Directions for BFS: North, East, South, West\n// These correspond to changes in (row, column) coordinates.\nint dr[] = {-1, 0, 1, 0};\nint dc[] = {0, 1, 0, -1};\n\n// Structure to hold cell information: row, column, and its shortest distance from the entrance.\n// This is used for sorting storage locations.\nstruct CellInfo {\n    int r, c, d;\n\n    // Custom comparison operator for sorting:\n    // 1. Primarily by distance (ascending).\n    // 2. Secondarily by row index (ascending).\n    // 3. Tertiarily by column index (ascending).\n    bool operator<(const CellInfo& other) const {\n        if (d != other.d) {\n            return d < other.d;\n        }\n        if (r != other.r) {\n            return r < other.r;\n        }\n        return c < other.c;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming performance.\n    // `ios_base::sync_with_stdio(false)` unties C++ streams from C stdio.\n    // `cin.tie(NULL)` unties cin from cout, meaning cin operations do not force cout to flush.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N; // Number of obstacles\n    cin >> D >> N;\n\n    // Set entrance coordinates (0-indexed). D is always 9, so (D-1)/2 is 4.\n    entrance = {0, (D - 1) / 2};\n\n    // Initialize grid properties: mark all cells as not an obstacle and unreachable initially.\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            is_obstacle[i][j] = false;\n            dist[i][j] = -1; // -1 indicates unreachable or unvisited\n        }\n    }\n\n    // Read and mark obstacle locations.\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    // --- BFS to calculate shortest distances ---\n    // We perform a Breadth-First Search starting from the entrance to find the shortest\n    // path distance to all reachable non-obstacle cells.\n    queue<pair<int, int>> q;\n\n    // The entrance is guaranteed not to be an obstacle.\n    dist[entrance.first][entrance.second] = 0;\n    q.push(entrance);\n\n    // This vector will store information about all reachable cells (including the entrance)\n    // along with their distances.\n    vector<CellInfo> all_reachable_cells;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n\n        // Add the current cell to our list of reachable cells.\n        all_reachable_cells.push_back({r, c, dist[r][c]});\n\n        // Explore neighbors in all four directions.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid bounds, is not an obstacle, and has not been visited yet.\n            if (nr >= 0 && nr < D && nc >= 0 && nc < D && !is_obstacle[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1; // Distance is one more than the current cell's distance.\n                q.push({nr, nc}); // Add the neighbor to the queue for exploration.\n            }\n        }\n    }\n\n    // --- Sorting Storage Locations ---\n    // The problem states that containers are stored in squares other than the entrance and obstacles.\n    // The total number of containers is M = D*D - 1 - N. These will occupy M storage locations.\n    // We need to sort these storage locations based on their proximity to the entrance to establish an order.\n    vector<CellInfo> sorted_storage_locs;\n    for (const auto& cell : all_reachable_cells) {\n        // The entrance cell itself is not a storage location, so we skip it.\n        if (cell.r == entrance.first && cell.c == entrance.second) {\n            continue;\n        }\n        sorted_storage_locs.push_back(cell);\n    }\n\n    // Sort the storage locations using the custom comparison operator defined in CellInfo.\n    // This ensures they are ordered by distance, then row, then column.\n    sort(sorted_storage_locs.begin(), sorted_storage_locs.end());\n\n    // Calculate the total number of containers to be stored.\n    int num_containers = D * D - 1 - N;\n\n    // --- Container Placement Phase ---\n    // This phase handles the arrival of containers one by one.\n    // For each arriving container, we decide where to store it.\n    // Our strategy: The d-th container to arrive (with ID t_d) is placed in the d-th location\n    // from our sorted list of storage locations (`sorted_storage_locs`). This greedy approach aims\n    // to keep containers with smaller target retrieval IDs in \"closer\" or more accessible locations.\n    \n    // We need to record the arrival order for each container ID.\n    // `container_arrival_idx[container_id]` will store the index `d` (0 to num_containers-1)\n    // representing the order in which `container_id` arrived and was placed.\n    vector<int> container_arrival_idx(num_containers); \n\n    for (int d = 0; d < num_containers; ++d) {\n        int container_id; // The ID of the container arriving at step d.\n        cin >> container_id;\n\n        // The d-th arriving container is placed at the d-th location in our sorted list.\n        CellInfo current_storage_loc = sorted_storage_locs[d];\n        pair<int, int> pos = {current_storage_loc.r, current_storage_loc.c};\n        \n        // Output the chosen storage location (row and column) for this container.\n        cout << pos.first << \" \" << pos.second << endl;\n        // `endl` typically flushes the output buffer in C++ streams, which is required.\n        \n        // Record that `container_id` arrived at step `d` and was assigned to `sorted_storage_locs[d]`.\n        // This means container_id is stored at the d-th closest available slot.\n        container_arrival_idx[container_id] = d; \n    }\n\n    // --- Container Retrieval Phase ---\n    // After all containers are stored, we need to determine the order in which they are transported out.\n    // The goal is to minimize the number of inversions in the retrieval sequence `b_0, b_1, ..., b_{M-1}`.\n    // This is achieved by aiming for the sorted sequence `0, 1, ..., M-1`.\n    // Our placement strategy (d-th arrival at d-th closest slot) allows for this.\n    // Container `k` is placed at `sorted_storage_locs[container_arrival_idx[k]]`.\n    // By retrieving containers in increasing order of their IDs (0, 1, 2, ...), we can achieve minimal inversions.\n    // Container `k` can be retrieved at step `k` because its location is guaranteed to be reachable.\n    // All containers `0, ..., k-1` are retrieved before container `k`, making their locations empty.\n    // The entire storage area is connected to the entrance, ensuring reachability.\n    \n    for (int k = 0; k < num_containers; ++k) {\n        // We want to retrieve container with ID `k` at step `k` of the retrieval sequence.\n        // Find out which storage slot `d` this container `k` was assigned to based on its arrival order.\n        int d = container_arrival_idx[k]; \n        \n        // The location of container `k` is the d-th sorted storage location.\n        CellInfo retrieved_cell = sorted_storage_locs[d];\n        pair<int, int> pos = {retrieved_cell.r, retrieved_cell.c};\n        \n        // Output the coordinates of the container to be transported out at this step.\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> initial_grid;\nvector<vector<int>> output_grid; // -1: unassigned, 0..m: assigned color\nvector<vector<bool>> adj;\nvector<pair<int, int>> dx = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n// Checks if assigning color 'color_to_assign' to a cell is valid\n// given the colors of its already assigned neighbors.\n// 'neighbor_colors' is a set of colors of already assigned neighbors of the cell.\nbool is_valid(int color_to_assign, const set<int>& neighbor_colors) {\n    for (int neighbor_color : neighbor_colors) {\n        if (color_to_assign != neighbor_color) {\n            if (!adj[min(color_to_assign, neighbor_color)][max(color_to_assign, neighbor_color)]) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> n >> m;\n\n    initial_grid.resize(n, vector<int>(n));\n    output_grid.resize(n, vector<int>(n, -1)); // Initialize all cells as unassigned (-1)\n\n    // Store first occurrence of each color (1 to m) as a seed\n    vector<pair<int, int>> seeds(m + 1, {-1, -1});\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> initial_grid[i][j];\n            if (initial_grid[i][j] >= 1 && initial_grid[i][j] <= m) {\n                if (seeds[initial_grid[i][j]].first == -1) {\n                    seeds[initial_grid[i][j]] = {i, j};\n                }\n            }\n        }\n    }\n\n    // Compute adjacency matrix for colors 0 to m\n    adj.resize(m + 1, vector<bool>(m + 1, false));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = initial_grid[i][j];\n            if (c1 != 0) { // Only check adjacencies for non-zero colors in the input\n                for (auto& move : dx) {\n                    int ni = i + move.first;\n                    int nj = j + move.second;\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int c2 = initial_grid[ni][nj];\n                        if (c1 != c2) {\n                            adj[min(c1, c2)][max(c1, c2)] = true;\n                        }\n                    } else { // Neighbor is outside the grid, which means it's adjacent to color 0\n                        adj[min(c1, 0)][max(c1, 0)] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // BFS queue stores cells to process. We prioritize processing non-zero colors.\n    queue<pair<int, int>> q;\n\n    // Seed the grid with initial colors and add them to the queue\n    // Priority is given to non-zero colors.\n    for (int k = 1; k <= m; ++k) {\n        if (seeds[k].first != -1) {\n            int r = seeds[k].first;\n            int c = seeds[k].second;\n            if (output_grid[r][c] == -1) { // If cell is unassigned\n                output_grid[r][c] = k;\n                q.push({r, c});\n            }\n        }\n    }\n\n    // Initialize color 0 for cells that are initially 0 and on the border,\n    // or if the input color was 0. These ensure color 0 connectivity.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (initial_grid[i][j] == 0) {\n                if (output_grid[i][j] == -1) { // If unassigned and input was 0\n                    output_grid[i][j] = 0;\n                    // We don't push color 0 to the queue because color 0 expansion is implicit\n                    // and doesn't drive the assignment of non-zero colors.\n                    // However, if 0 is the *only* color assigned initially (e.g. all 0s input),\n                    // we might need to seed it if it's a border cell.\n                }\n            }\n        }\n    }\n    // Ensure border cells that are unassigned default to 0.\n    for (int i = 0; i < n; ++i) {\n        if (output_grid[i][0] == -1) { output_grid[i][0] = 0; }\n        if (output_grid[i][n-1] == -1) { output_grid[i][n-1] = 0; }\n    }\n    for (int j = 0; j < n; ++j) {\n        if (output_grid[0][j] == -1) { output_grid[0][j] = 0; }\n        if (output_grid[n-1][j] == -1) { output_grid[n-1][j] = 0; }\n    }\n\n\n    // BFS to fill the grid\n    // The queue `q` primarily contains seeds of non-zero colors.\n    // When a non-zero cell expands, it decides the color of its unassigned neighbors.\n    while (!q.empty()) {\n        pair<int, int> current_cell = q.front();\n        q.pop();\n        int r = current_cell.first;\n        int c = current_cell.second;\n        int current_color = output_grid[r][c];\n\n        for (auto& move : dx) {\n            int nr = r + move.first;\n            int nc = c + move.second;\n\n            if (nr >= 0 && nr < n && nc >= 0 && nc < n) {\n                if (output_grid[nr][nc] == -1) { // If neighbor is unassigned\n                    // Collect colors of already assigned neighbors of (nr, nc)\n                    set<int> neighbor_colors;\n                    for (auto& next_move : dx) {\n                        int nnr = nr + next_move.first;\n                        int nnc = nc + next_move.second;\n                        if (nnr >= 0 && nnr < n && nnc >= 0 && nnc < n) {\n                            if (output_grid[nnr][nnc] != -1) { // Collect colors of assigned neighbors\n                                neighbor_colors.insert(output_grid[nnr][nnc]);\n                            }\n                        }\n                    }\n\n                    int color_to_assign = -1;\n\n                    // Strategy:\n                    // 1. Try to assign color 0 if it's valid.\n                    // 2. If 0 is not valid, try to assign a non-zero color K.\n                    //    - Prioritize K if it's required by `current_color` (i.e., `adj[current_color][K]` is true).\n                    //    - If multiple such K exist, pick the smallest.\n                    //    - If no prioritized K is found, pick the smallest valid K.\n\n                    bool can_be_zero = is_valid(0, neighbor_colors);\n\n                    if (can_be_zero) {\n                        // Color 0 is valid. We prefer it to maximize score.\n                        // Assigning 0 means it remains 0 (since output_grid[nr][nc] was -1, and now becomes 0).\n                        // We do not push 0 to the queue as its expansion is implicit.\n                        color_to_assign = 0;\n                    } else {\n                        // Color 0 is NOT valid. We MUST assign a non-zero color.\n                        int best_k = -1;\n\n                        // First, try to find a K required by current_color\n                        if (current_color != 0) { // current_color is non-zero, check its adjacencies\n                            for (int k = 1; k <= m; ++k) {\n                                if (adj[min(current_color, k)][max(current_color, k)]) { // k is required by current_color\n                                    if (is_valid(k, neighbor_colors)) { // k is valid for this cell\n                                        best_k = k; // Found a candidate K\n                                        break; // Prioritize first such K\n                                    }\n                                }\n                            }\n                        }\n\n                        // If no prioritized K was found, find any valid non-zero color K\n                        if (best_k == -1) {\n                            for (int k = 1; k <= m; ++k) {\n                                if (is_valid(k, neighbor_colors)) {\n                                    best_k = k;\n                                    break; // Found first valid non-zero color K\n                                }\n                            }\n                        }\n                        color_to_assign = best_k;\n                    }\n\n                    // Assign the determined color and enqueue if it's non-zero.\n                    if (color_to_assign != -1) {\n                        output_grid[nr][nc] = color_to_assign;\n                        if (color_to_assign != 0) { // Only push non-zero colors to the queue\n                            q.push({nr, nc});\n                        }\n                    } else {\n                        // This case implies that no color (0 or 1..m) could be validly assigned.\n                        // This could happen if the problem constraints are impossible for this heuristic,\n                        // or if the seeding/expansion order leads to a dead end.\n                        // For a contest, leaving it as -1 and filling later might be an option,\n                        // but the problem implies a solution exists. We assume best_k is found if !can_be_zero.\n                        // As a fallback, we might assign 0 if it was valid but not preferred, or if problem implies any solution is fine.\n                        // However, the logic implies if !can_be_zero, then best_k MUST be found.\n                        // If it's not found, the strategy fails.\n                        // Given the scoring and heuristic nature, this state is unlikely if adjacencies are feasible.\n                    }\n                }\n            }\n        }\n    }\n\n    // Final pass: Fill any remaining unassigned cells (-1) with color 0.\n    // This ensures connectivity of color 0 and maximizes the score.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (output_grid[i][j] == -1) {\n                output_grid[i][j] = 0;\n            }\n        }\n    }\n\n    // Print the output grid\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << output_grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Use a large value for infinity in distance calculations.\n// Given N <= 100, a path length is at most N-1. Max difference per step is 1.\n// So N+5 should be sufficiently large for INF.\nconst long long INF = 1e18; \n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, d, q;\n    cin >> n >> d >> q;\n\n    // Stores the result of pairwise comparisons:\n    // comparison[i][j] = 1 if w_i < w_j\n    // comparison[i][j] = -1 if w_i > w_j\n    // comparison[i][j] = 0 if w_i = w_j\n    // comparison[i][j] = 2 if unknown\n    vector<vector<int>> comparison(n, vector<int>(n, 2));\n\n    int queries_budget = q;\n    int current_queries = 0;\n\n    // Phase 1: Prioritize comparisons between items with small index differences.\n    // This helps establish local relationships and might reveal structured weight distributions.\n    // We check differences from 1 up to a certain limit. The limit is capped by N/2\n    // to avoid redundant checks (e.g., diff=1 queries (0,1), (1,2), ..., (N-1,0). diff=N-1 queries (0,N-1), etc. which are inverse of diff=1).\n    // Also, cap the number of differences to check to not exceed Q.\n    int max_diff_to_check = min(10, n / 2); \n\n    for (int diff = 1; diff <= max_diff_to_check; ++diff) {\n        if (current_queries >= queries_budget) break;\n        for (int i = 0; i < n; ++i) {\n            if (current_queries >= queries_budget) break;\n            int j = (i + diff) % n; // Circular index difference\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1; // Symmetric relation\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1; // Symmetric relation\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0; // Symmetric relation\n                }\n            }\n        }\n    }\n    \n    // Phase 2: If budget remains, query arbitrary pairs (i, j) with i < j.\n    // This strategy aims to gather as many direct pairwise comparisons as possible.\n    for (int i = 0; i < n; ++i) {\n        if (current_queries >= queries_budget) break;\n        for (int j = i + 1; j < n; ++j) { // Iterate through unique pairs (i, j) with i < j\n            if (current_queries >= queries_budget) break;\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1;\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1;\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0;\n                }\n            }\n        }\n    }\n\n    // Initialize distance matrix for Floyd-Warshall algorithm.\n    // dist[i][j] will store the minimum possible value of (w_i - w_j).\n    // Weights w_i are positive integers (>= 1).\n    // If w_i < w_j, then w_i - w_j <= -1. The minimum possible difference is -1.\n    // If w_i > w_j, then w_i - w_j >= 1. The minimum possible difference is 1.\n    // If w_i = w_j, then w_i - w_j = 0.\n    vector<vector<long long>> dist(n, vector<long long>(n));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (i == j) {\n                dist[i][j] = 0; // Distance to self is 0\n            } else if (comparison[i][j] == 1) { // w_i < w_j => w_i - w_j <= -1\n                dist[i][j] = -1;\n            } else if (comparison[i][j] == -1) { // w_i > w_j => w_i - w_j >= 1\n                dist[i][j] = 1;\n            } else if (comparison[i][j] == 0) { // w_i = w_j\n                dist[i][j] = 0;\n            } else { // Unknown relationship\n                dist[i][j] = INF; // Initialize with infinity\n            }\n        }\n    }\n\n    // Run Floyd-Warshall to compute all-pairs shortest paths (minimum differences).\n    // This step integrates all pairwise comparisons to infer transitive relationships.\n    for (int k = 0; k < n; ++k) { // Intermediate node\n        for (int i = 0; i < n; ++i) { // Source node\n            for (int j = 0; j < n; ++j) { // Destination node\n                // If paths through k are possible, update distance\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    // Estimate weights based on the computed differences.\n    // We use dist[0][i] which represents the minimum inferred difference w_0 - w_i.\n    // So, w_i = w_0 + dist[0][i].\n    // To get an estimate of w_i's magnitude, we can use -dist[0][i] as a proxy.\n    // If dist[0][i] is -5, it implies w_i is roughly 5 units heavier than w_0. So -dist[0][i] = 5.\n    // If dist[0][i] is 3, it implies w_i is roughly 3 units lighter than w_0. So -dist[0][i] = -3.\n    // This gives a relative ordering.\n    vector<pair<long long, int>> estimated_weights(n);\n    long long min_estimated_val = 0; // To find the minimum estimated value for shifting\n    \n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i] = {-dist[0][i], i}; // Use -dist[0][i] as estimated weight\n        min_estimated_val = min(min_estimated_val, estimated_weights[i].first);\n    }\n\n    // Shift the estimated weights so that the minimum weight is 1.\n    // This ensures all estimated weights are positive integers, respecting the problem's constraint.\n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i].first = estimated_weights[i].first - min_estimated_val + 1;\n    }\n\n    // Sort items by their estimated weights in descending order.\n    // This is for the Largest Processing Time (LPT) heuristic, commonly used for multiway number partitioning.\n    sort(estimated_weights.rbegin(), estimated_weights.rend());\n\n    // Partitioning phase using the LPT heuristic.\n    // We want to assign items to 'd' bins such that the sum of weights in each bin is as equal as possible.\n    vector<long long> bin_sums(d, 0); // Stores the current total estimated weight for each bin\n    vector<int> assignment(n);       // Stores the final bin assignment for each item\n\n    for (const auto& item_pair : estimated_weights) {\n        long long weight = item_pair.first; // Estimated weight of the current item\n        int item_idx = item_pair.second;    // Original index of the item\n\n        // Find the bin with the minimum current sum of weights.\n        int best_bin = 0;\n        for (int b = 1; b < d; ++b) {\n            if (bin_sums[b] < bin_sums[best_bin]) {\n                best_bin = b;\n            }\n        }\n\n        // Assign the current item to the bin with the minimum sum.\n        assignment[item_idx] = best_bin;\n        bin_sums[best_bin] += weight; // Update the sum for this bin\n    }\n\n    // Output the final assignment of items to bins.\n    for (int i = 0; i < n; ++i) {\n        cout << assignment[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\n// Use 1-based indexing for boxes, 0-based for internal stack indices.\n// Output requires 1-based indexing for stacks.\n\nstruct BoxLocation {\n    int stack_idx; // 0-indexed\n    int pos_in_stack; // 0-indexed from bottom\n};\n\n// Global variables to store state\nstd::vector<std::vector<int>> stacks;\nstd::vector<BoxLocation> box_locations;\nstd::vector<bool> is_carried_out;\nint n_boxes, m_stacks;\nint next_box_to_carry_id = 1;\nstd::vector<std::pair<int, int>> operations; // pair {box_id, destination_stack_idx+1 or 0}\n\n// Helper to update box_locations after a stack modification\nvoid update_box_locations_in_stack(int stack_idx, const std::vector<int>& stack_content) {\n    for (int i = 0; i < stack_content.size(); ++i) {\n        int box_id = stack_content[i];\n        box_locations[box_id] = {stack_idx, i};\n    }\n}\n\n// Function to perform operation 1\n// Moves the block starting from `v_id` (and everything above it) from its current stack\n// to `dest_stack_idx`. The `v_id` is the box that initiates the move, as per problem statement.\nvoid perform_move_operation(int v_id, int dest_stack_idx) {\n    int src_stack_idx = box_locations[v_id].stack_idx;\n    int v_pos_in_src_stack = box_locations[v_id].pos_in_stack;\n    \n    std::vector<int>& src_stack = stacks[src_stack_idx];\n\n    // The block to move starts at v_id and goes to the top of the current stack.\n    int start_move_pos = v_pos_in_src_stack;\n    \n    std::vector<int> block_to_move;\n    for (int i = start_move_pos; i < src_stack.size(); ++i) {\n        block_to_move.push_back(src_stack[i]);\n    }\n    \n    // The first element of block_to_move is the box `v` for the operation.\n    // In this strategy, v_id is always `next_box_to_carry_id`, which is block_to_move[0].\n    // int op_v_id = block_to_move[0]; // This is guaranteed to be v_id in our strategy.\n\n    // Output operation (v_id, dest_stack_idx + 1). dest_stack_idx is 0-indexed.\n    operations.push_back({v_id, dest_stack_idx + 1});\n\n    // Update source stack: remove the block\n    src_stack.resize(start_move_pos);\n    // Update locations for boxes remaining in source stack\n    update_box_locations_in_stack(src_stack_idx, src_stack);\n\n    // Update destination stack: add the block\n    auto& dest_stack = stacks[dest_stack_idx];\n    for (int box_id : block_to_move) {\n        dest_stack.push_back(box_id);\n        box_locations[box_id] = {dest_stack_idx, dest_stack.size() - 1};\n    }\n}\n\nvoid solve() {\n    std::cin >> n_boxes >> m_stacks;\n\n    stacks.resize(m_stacks);\n    // box_locations will store {stack_idx, pos_in_stack} for each box ID (1 to n_boxes).\n    // Initialize with invalid values or resize as needed. Size n_boxes + 1 for 1-based indexing.\n    box_locations.resize(n_boxes + 1); \n\n    for (int i = 0; i < m_stacks; ++i) {\n        int num_boxes_in_stack = n_boxes / m_stacks; // Problem constraint\n        stacks[i].resize(num_boxes_in_stack);\n        for (int j = 0; j < num_boxes_in_stack; ++j) {\n            std::cin >> stacks[i][j];\n            // Record initial location for each box\n            box_locations[stacks[i][j]] = {i, j};\n        }\n    }\n\n    is_carried_out.resize(n_boxes + 1, false);\n\n    // Main loop: process boxes 1 to n in order.\n    while (next_box_to_carry_id <= n_boxes) {\n        int current_box_id = next_box_to_carry_id;\n        int src_stack_idx = box_locations[current_box_id].stack_idx;\n        int pos_in_stack = box_locations[current_box_id].pos_in_stack;\n        std::vector<int>& current_stack = stacks[src_stack_idx];\n\n        // Check if the current box is at the top of its stack\n        if (pos_in_stack == current_stack.size() - 1) { \n            // Operation 2: Carry out the box\n            operations.push_back({current_box_id, 0}); // 0 signifies carry-out\n            is_carried_out[current_box_id] = true;\n            current_stack.pop_back();\n            \n            // Update locations for any boxes that might have been affected (none in this case, as no boxes were above)\n            // For safety, call update on the stack, though pop_back doesn't shift elements' indices.\n            update_box_locations_in_stack(src_stack_idx, current_stack);\n            \n            next_box_to_carry_id++; // Move to the next box\n        } else { \n            // Operation 1 is required because `current_box_id` is NOT at the top.\n            // Heuristic for choosing destination stack:\n            // 1. Prefer an empty stack with the smallest index.\n            // 2. If no empty stacks exist, prefer a non-empty stack whose top element is MINIMIZED.\n            //    If there's a tie in minimum top element, pick the stack with the smallest index.\n            \n            int dest_stack_idx = -1;\n            int min_top_val = -1; // Sentinel for \"no suitable non-empty stack found yet\"\n            bool found_empty_stack = false;\n\n            for (int i = 0; i < m_stacks; ++i) {\n                if (i == src_stack_idx) continue; // Cannot move to the same stack.\n\n                if (stacks[i].empty()) {\n                    if (!found_empty_stack) { // Found the first empty stack\n                        dest_stack_idx = i;\n                        found_empty_stack = true;\n                    }\n                    // If multiple empty stacks, `dest_stack_idx` will naturally hold the smallest index encountered first.\n                } else { // Stack `i` is not empty\n                    if (!found_empty_stack) { // Only consider non-empty stacks if no empty ones were found\n                        int top_val = stacks[i].back();\n                        if (min_top_val == -1 || top_val < min_top_val) {\n                            min_top_val = top_val;\n                            dest_stack_idx = i;\n                        } else if (top_val == min_top_val) {\n                            // Tie-breaking: prefer smaller index\n                            if (i < dest_stack_idx) {\n                                dest_stack_idx = i;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Fallback: If for some reason dest_stack_idx wasn't set (e.g., m=1, which is not the case here),\n            // pick the first available stack other than the source.\n            if (dest_stack_idx == -1) {\n                 for(int i = 0; i < m_stacks; ++i) {\n                     if (i != src_stack_idx) {\n                         dest_stack_idx = i;\n                         break;\n                     }\n                 }\n            }\n\n            // Perform the move operation. The box initiating the move (v_id) is `current_box_id`.\n            perform_move_operation(current_box_id, dest_stack_idx);\n            \n            // `next_box_to_carry_id` does NOT increment because `current_box_id` is still not at the top\n            // of its NEW stack after the move. The loop will repeat for `current_box_id` again.\n        }\n    }\n\n    // Output all recorded operations\n    for (const auto& op : operations) {\n        std::cout << op.first << \" \" << op.second << \"\\n\";\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n    \n    solve();\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\nint N;\nvector<string> h_walls, v_walls;\nvector<vector<int>> d;\n\n// Adjacency list for grid graph\n// Stores pairs of {neighbor_row, neighbor_col, move_char, wall_type}\n// wall_type: 0 for no wall, 1 for horizontal wall, 2 for vertical wall\n// This information is not strictly needed if we check walls dynamically,\n// but could be useful for pathfinding. For this problem, we check walls directly.\nvector<pair<int, int>> adj[40][40];\n\nint dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar moves[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (r, c) to (nr, nc) is valid (no wall)\nbool is_valid_move(int r, int c, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n        return false;\n    }\n    if (nr == r - 1) { // Moving Up\n        if (v_walls[r][c] == '1') return false;\n    } else if (nr == r + 1) { // Moving Down\n        if (h_walls[r][c] == '1') return false;\n    } else if (nc == c - 1) { // Moving Left\n        if (v_walls[r][c-1] == '1') return false;\n    } else if (nc == c + 1) { // Moving Right\n        if (v_walls[r][c] == '1') return false;\n    }\n    return true;\n}\n\n// DFS to generate an initial path that visits all nodes\nstring initial_path_str;\nbool visited_dfs[40][40];\nint initial_path_len = 0;\nmap<pair<int, int>, int> visit_counts_dfs;\n\nvoid dfs_generate(int r, int c) {\n    visited_dfs[r][c] = true;\n    visit_counts_dfs[{r, c}]++;\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited_dfs[nr][nc]) {\n            if (is_valid_move(r, c, nr, nc)) {\n                initial_path_str += moves[i];\n                initial_path_len++;\n                dfs_generate(nr, nc);\n                initial_path_str += moves[i ^ 1]; // Move back\n                initial_path_len++;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[i];\n\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Build adjacency list implicitly by checking walls in is_valid_move\n    // DFS to generate initial path\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_dfs[i][j] = false;\n        }\n    }\n    dfs_generate(0, 0);\n    \n    // Ensure (0,0) is visited twice if DFS starts/ends there\n    // The DFS logic above adds return moves, so (0,0) is visited at start and end\n    // If initial_path_len is 0 (e.g. 1x1 grid, though N>=20), handle it.\n    if (N > 0 && initial_path_len == 0) { // For N=1, this might happen. But N>=20.\n        // If grid is just one cell (0,0), path is empty, length 0.\n        // But problem says N>=20. So DFS should generate a path.\n    }\n\n\n    // Target visit counts proportional to sqrt(d_i,j)\n    // Minimize sum( d_i,j / N_i,j^2 )\n    // Equivalent to maximizing sum( d_i,j / N_i,j^2 )\n    // For total visits V, N_i,j should be proportional to sqrt(d_i,j)\n    // N_i,j = C * sqrt(d_i,j)\n    // Sum(N_i,j) = V => C = V / Sum(sqrt(d_i,j))\n    // N_i,j = V * sqrt(d_i,j) / Sum(sqrt(d_k,m))\n\n    // Max path length is 100000.\n    // Initial path length L_dfs.\n    // Each additional visit can be achieved by a detour X->Y->X, adding 2 moves.\n    // Max number of extra visits K_max = (100000 - L_dfs) / 2\n    // Total max visits V_max = N*N + K_max\n\n    long double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((long double)d[i][j]);\n        }\n    }\n\n    int max_total_visits = 100000; // Maximum allowed path length\n\n    vector<long long> target_N(N * N, 0);\n    long long current_total_visits = 0;\n\n    // Ensure each cell is visited at least once\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            target_N[i * N + j] = 1;\n            current_total_visits++;\n        }\n    }\n    \n    // Distribute remaining visits greedily based on sqrt(d_i,j)\n    // We have `max_total_visits - current_total_visits` visits to distribute.\n    // This number is an upper bound on the sum of ADDITIONAL visits beyond the first one for each cell.\n    // Let's use the objective function to guide distribution: maximize sum(d_i,j / N_i,j^2)\n    // This implies N_i,j should be proportional to sqrt(d_i,j).\n\n    // Strategy: calculate proportional counts for all cells, then scale and adjust.\n    vector<pair<long double, pair<int, int>>> proportional_visits;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            proportional_visits.push_back({sqrt((long double)d[i][j]), {i, j}});\n        }\n    }\n    sort(proportional_visits.rbegin(), proportional_visits.rend());\n\n    // Distribute visits until total path length constraint is met.\n    // We have `max_total_visits` moves. Each visit adds at least 1 move, often 2 (detour).\n    // Let's use the rule that each visit adds 2 moves (detour)\n    // Total visits V should satisfy L_dfs + 2 * (V - N*N) <= 100000\n    // 2 * (V - N*N) <= 100000 - L_dfs\n    // V - N*N <= (100000 - L_dfs) / 2\n    // V <= N*N + (100000 - L_dfs) / 2\n    int max_additional_visits = (100000 - initial_path_len) / 2;\n    if (max_additional_visits < 0) max_additional_visits = 0;\n\n    current_total_visits = N * N; // All cells visited once initially\n\n    // Greedily assign additional visits to cells with high sqrt(d_i,j)\n    vector<long long> N_final(N * N, 1); // Start with 1 visit for each cell\n    long long visits_added_count = 0;\n\n    // First, distribute visits to reach max_additional_visits for sqrt(d_i,j) based proportional counts\n    vector<pair<long double, pair<int,int>>> sqrt_d_sorted;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) sqrt_d_sorted.push_back({sqrt((long double)d[i][j]), {i,j}});\n    sort(sqrt_d_sorted.rbegin(), sqrt_d_sorted.rend());\n    \n    for(const auto& p : sqrt_d_sorted) {\n        if (visits_added_count >= max_additional_visits) break;\n        int r = p.second.first;\n        int c = p.second.second;\n        N_final[r*N+c]++;\n        visits_added_count++;\n    }\n\n    // If we still have budget for more visits (e.g. if max_additional_visits was very large, and sum of sqrt(d_i,j) was small)\n    // we can add more visits to cells with highest d_i,j, using the priority queue logic.\n    // However, the proportional distribution up to max_additional_visits is likely optimal.\n\n    // If current_total_visits (N*N) + visits_added_count > 100000 (this check is redundant if max_additional_visits is calculated correctly)\n    // we need to cap it. But max_additional_visits ensures total length <= 100000.\n\n    // Current visit counts based on initial DFS and N_final assignment\n    map<pair<int, int>, int> current_N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_N[{i, j}] = visit_counts_dfs.count({i, j}) ? visit_counts_dfs[{i, j}] : 0;\n        }\n    }\n\n    // Adjust initial DFS counts to match N_final targets\n    // The DFS path might visit cells more than once initially.\n    // We need to reach N_final counts.\n    vector<pair<long double, pair<int, int>>> pq_cells; // (priority, {r, c})\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (current_N[{i, j}] < N_final[i * N + j]) {\n                pq_cells.push_back({ (long double)d[i][j] / (long double)(current_N[{i, j}] * current_N[{i, j}]), {i, j} });\n            }\n        }\n    }\n    sort(pq_cells.rbegin(), pq_cells.rend());\n\n    vector<pair<int, int>> cells_to_visit_extra; // Cells to add extra visits to\n    vector<int> extra_visits_count(N*N, 0);\n\n    int current_extra_visits_total = 0;\n    for(const auto& p : pq_cells) {\n        int r = p.second.first;\n        int c = p.second.second;\n        int needed = N_final[r*N+c] - current_N[{r,c}];\n        for(int k=0; k<needed; ++k) {\n            if (current_extra_visits_total >= max_additional_visits) break;\n            cells_to_visit_extra.push_back({r, c});\n            extra_visits_count[r*N+c]++;\n            current_extra_visits_total++;\n        }\n        if (current_extra_visits_total >= max_additional_visits) break;\n    }\n    \n    // Construct final path by adding detours\n    string final_path = initial_path_str;\n    int current_path_len = initial_path_len;\n\n    // Store path as sequence of cells for easier detour insertion\n    vector<pair<int, int>> path_cells;\n    path_cells.push_back({0,0});\n    int cur_r = 0, cur_c = 0;\n    for(char move : initial_path_str) {\n        if (move == 'U') cur_r--;\n        else if (move == 'D') cur_r++;\n        else if (move == 'L') cur_c--;\n        else if (move == 'R') cur_c++;\n        path_cells.push_back({cur_r, cur_c});\n    }\n\n    // Add detours\n    for (int r_target = 0; r_target < N; ++r_target) {\n        for (int c_target = 0; c_target < N; ++c_target) {\n            int count_to_add = extra_visits_count[r_target * N + c_target];\n            if (count_to_add == 0) continue;\n\n            // For each cell, add `count_to_add` detours.\n            // Simple detour: find last visit to (r_target, c_target) and insert a minimal path to it.\n            // This is complicated. A simpler approach: append detours from the END of current path.\n            // Path: P_dfs, then for each (r,c) to visit K times: append path(current_pos, r, c), append path(r,c, current_pos)\n            \n            for(int k=0; k<count_to_add; ++k) {\n                 if (current_path_len + 2 > 100000) break; // Safety break\n\n                // Find current end of path\n                cur_r = path_cells.back().first;\n                cur_c = path_cells.back().second;\n                \n                // Find shortest path from (cur_r, cur_c) to (r_target, c_target)\n                queue<pair<int, int>> q;\n                q.push({cur_r, cur_c});\n                vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited(N, vector<bool>(N, false));\n                visited[cur_r][cur_c] = true;\n                bool found = false;\n\n                while (!q.empty()) {\n                    pair<int, int> curr = q.front();\n                    q.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == r_target && c_curr == c_target) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited[nr][nc]) {\n                            visited[nr][nc] = true;\n                            parent[nr][nc] = {r_curr, c_curr};\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen as all cells are reachable */ continue; }\n\n                // Reconstruct path from (cur_r, cur_c) to (r_target, c_target)\n                vector<char> detour_fwd;\n                vector<pair<int, int>> detour_cells_fwd;\n                pair<int, int> trace = {r_target, c_target};\n                while (trace.first != cur_r || trace.second != cur_c) {\n                    pair<int, int> p_trace = parent[trace.first][trace.second];\n                    if (p_trace.first == -1) break; // Should not happen\n\n                    if (trace.first == p_trace.first - 1) detour_fwd.push_back('U');\n                    else if (trace.first == p_trace.first + 1) detour_fwd.push_back('D');\n                    else if (trace.second == p_trace.second - 1) detour_fwd.push_back('L');\n                    else if (trace.second == p_trace.second + 1) detour_fwd.push_back('R');\n                    \n                    detour_cells_fwd.push_back(trace);\n                    trace = p_trace;\n                }\n                reverse(detour_fwd.begin(), detour_fwd.end());\n                reverse(detour_cells_fwd.begin(), detour_cells_fwd.end());\n\n                // Add detour path to cells list\n                for(char move : detour_fwd) {\n                    path_cells.push_back({r_target,c_target}); // add target cell\n                    if (move == 'U') path_cells.push_back({path_cells.back().first - 1, path_cells.back().second});\n                    else if (move == 'D') path_cells.push_back({path_cells.back().first + 1, path_cells.back().second});\n                    else if (move == 'L') path_cells.push_back({path_cells.back().first, path_cells.back().second - 1});\n                    else if (move == 'R') path_cells.push_back({path_cells.back().first, path_cells.back().second + 1});\n                }\n                \n                // Add the final (r_target, c_target) cell itself\n                path_cells.push_back({r_target, c_target});\n                \n                // Now add path back to original current position (cur_r, cur_c)\n                // This is BFS from (r_target, c_target) to (cur_r, cur_c)\n                queue<pair<int, int>> q_ret;\n                q_ret.push({r_target, c_target});\n                vector<vector<pair<int, int>>> parent_ret(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited_ret(N, vector<bool>(N, false));\n                visited_ret[r_target][c_target] = true;\n                found = false;\n\n                while (!q_ret.empty()) {\n                    pair<int, int> curr = q_ret.front();\n                    q_ret.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == cur_r && c_curr == cur_c) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited_ret[nr][nc]) {\n                            visited_ret[nr][nc] = true;\n                            parent_ret[nr][nc] = {r_curr, c_curr};\n                            q_ret.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen */ continue; }\n\n                // Reconstruct path back\n                trace = {cur_r, cur_c};\n                while(trace.first != r_target || trace.second != c_target) {\n                     pair<int, int> p_trace = parent_ret[trace.first][trace.second];\n                     if (p_trace.first == -1) break;\n\n                     if (trace.first == p_trace.first - 1) path_cells.push_back({p_trace.first - 1, p_trace.second});\n                     else if (trace.first == p_trace.first + 1) path_cells.push_back({p_trace.first + 1, p_trace.second});\n                     else if (trace.second == p_trace.second - 1) path_cells.push_back({p_trace.second - 1, p_trace.second});\n                     else if (trace.second == p_trace.second + 1) path_cells.push_back({p_trace.second + 1, p_trace.second});\n                     trace = p_trace;\n                }\n\n                // Update current path length and position\n                current_path_len = path_cells.size() - 1;\n                if (current_path_len > 100000) { // Cap path length\n                    path_cells.resize(100000 + 1); // Keep start and end for length 100000\n                    current_path_len = 100000;\n                }\n            }\n        }\n    }\n\n    // Convert path_cells back to moves string, truncated if necessary\n    final_path = \"\";\n    for (size_t i = 0; i < path_cells.size() - 1; ++i) {\n        if (final_path.length() >= 100000) break;\n\n        int r1 = path_cells[i].first;\n        int c1 = path_cells[i].second;\n        int r2 = path_cells[i+1].first;\n        int c2 = path_cells[i+1].second;\n\n        if (r2 == r1 - 1) final_path += 'U';\n        else if (r2 == r1 + 1) final_path += 'D';\n        else if (c2 == c1 - 1) final_path += 'L';\n        else if (c2 == c1 + 1) final_path += 'R';\n    }\n\n    cout << final_path << endl;\n\n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <map>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nint N;\nchar grid[15][15];\nvector<string> t;\nint start_r, start_c;\n\n// For Dijkstra to find path for one string\n// dp[p][r][c]: min cost to type first p characters of target string, ending at (r,c)\n// where grid[r][c] matches the p-th character.\n// p from 1 to 5.\nlong long dp[6][15][15];\npair<int, int> pred[6][15][15]; // Stores previous coordinates to reconstruct path\n\n// Directions for BFS/Dijkstra\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nstruct State {\n    long long cost;\n    int r, c;\n\n    bool operator>(const State& other) const {\n        return cost > other.cost;\n    }\n};\n\n// Computes the minimum cost and path to type target_str starting from (sr, sc)\n// Returns {min_total_cost, end_r, end_c, sequence_of_operations}\ntuple<long long, int, int, vector<pair<int, int>>> compute_path(const string& target_str, int sr, int sc) {\n    for (int p = 0; p <= 5; ++p) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                dp[p][r][c] = INF;\n                pred[p][r][c] = {-1, -1};\n            }\n        }\n    }\n\n    char first_char = target_str[0];\n    \n    // Base case: p=1 (typing the first character)\n    // dp[1][r][c] = min cost to type first character (target_str[0]) ending at (r,c)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] == first_char) {\n                dp[1][r][c] = abs(r - sr) + abs(c - sc) + 1;\n                // pred[1][r][c] remains {-1, -1} to signify start\n            }\n        }\n    }\n\n    // Fill DP table for p = 2 to 5\n    for (int p = 2; p <= 5; ++p) {\n        char current_char_needed = target_str[p - 1];\n        \n        priority_queue<State, vector<State>, greater<State>> pq;\n        vector<vector<long long>> dist(N, vector<long long>(N, INF));\n        vector<vector<pair<int, int>>> layer_pred(N, vector<pair<int, int>>(N, {-1,-1}));\n\n        // Initialize Dijkstra PQ with costs from previous step (p-1)\n        // States in PQ are (cost_to_type_p-1_chars_ending_here, r, c)\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (dp[p - 1][r][c] != INF) {\n                    pq.push({dp[p - 1][r][c], r, c});\n                    dist[r][c] = dp[p - 1][r][c]; // dist here is min cost to reach (r,c) having typed p-1 chars\n                }\n            }\n        }\n\n        // Run Dijkstra\n        // We want to find min cost to reach any cell (nr, nc) for current_char_needed\n        // from any cell (r,c) which is a valid end for p-1 characters.\n        while (!pq.empty()) {\n            State current = pq.top();\n            pq.pop();\n\n            long long d = current.cost;\n            int r = current.r;\n            int c = current.c;\n\n            if (d > dist[r][c]) continue;\n\n            // Explore neighbors\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i];\n                int nc = c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    // Cost to move from (r,c) to (nr,nc) AND append grid[nr][nc]\n                    long long move_cost = abs(nr - r) + abs(nc - c) + 1;\n                    \n                    // If the neighbor cell (nr, nc) has the character needed for the current step (p)\n                    if (grid[nr][nc] == current_char_needed) {\n                        if (dist[r][c] + move_cost < dist[nr][nc]) {\n                            dist[nr][nc] = dist[r][c] + move_cost;\n                            layer_pred[nr][nc] = {r, c}; // Store predecessor for path reconstruction\n                            pq.push({dist[nr][nc], nr, nc});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Update DP table for step p\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (grid[r][c] == current_char_needed && dist[r][c] != INF) {\n                    dp[p][r][c] = dist[r][c];\n                    pred[p][r][c] = layer_pred[r][c]; // Store predecessor for path reconstruction\n                }\n            }\n        }\n    }\n\n    // Find the minimum cost to type the whole string (length 5)\n    long long min_total_cost = INF;\n    int final_r = -1, final_c = -1;\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[5][r][c] < min_total_cost) {\n                min_total_cost = dp[5][r][c];\n                final_r = r;\n                final_c = c;\n            }\n        }\n    }\n\n    // Reconstruct path\n    vector<pair<int, int>> path_ops;\n    if (final_r != -1) {\n        int curr_r = final_r;\n        int curr_c = final_c;\n        for (int p = 5; p >= 1; --p) {\n            path_ops.push_back({curr_r, curr_c});\n            if (p > 1) { // For p=1, pred is {-1,-1}\n                pair<int, int> prev_pos = pred[p][curr_r][curr_c];\n                curr_r = prev_pos.first;\n                curr_c = prev_pos.second;\n            }\n        }\n        reverse(path_ops.begin(), path_ops.end());\n    }\n    \n    return {min_total_cost, final_r, final_c, path_ops};\n}\n\n// Helper to check if string 'needle' is a substring of 'haystack'\nbool contains(const string& haystack, const string& needle) {\n    return haystack.find(needle) != string::npos;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M >> start_r >> start_c;\n    --start_r; --start_c; // 0-indexed\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    t.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> t[i];\n    }\n\n    vector<pair<int, int>> operations;\n    set<int> uncovered_indices;\n    for (int i = 0; i < M; ++i) {\n        uncovered_indices.insert(i);\n    }\n\n    int current_r = start_r;\n    int current_c = start_c;\n    long long total_cost = 0;\n    \n    // We can perform at most 5000 operations.\n    // Our strategy is to greedily type the cheapest full string that is not yet covered.\n    // Each typed string requires 5 operations.\n    // We continue this until we have typed 1000 strings (total 5000 operations)\n    // or until all strings are covered.\n\n    int max_strings_to_type = 1000; \n\n    for (int iter = 0; iter < max_strings_to_type; ++iter) {\n        if (uncovered_indices.empty()) break; // All strings are covered\n\n        long long min_iter_cost = INF;\n        int best_t_idx = -1;\n        int best_end_r = -1, best_end_c = -1;\n        vector<pair<int, int>> ops_for_best_t;\n\n        // Find the cheapest string to type among the currently uncovered ones\n        for (int idx : uncovered_indices) {\n            auto [cost, end_r, end_c, current_ops] = compute_path(t[idx], current_r, current_c);\n            \n            if (cost < min_iter_cost) {\n                min_iter_cost = cost;\n                best_t_idx = idx;\n                best_end_r = end_r;\n                best_end_c = end_c;\n                ops_for_best_t = current_ops;\n            }\n        }\n\n        // If no string can be typed (e.g., required chars not on grid, which is guaranteed not to happen)\n        if (best_t_idx == -1) { \n            break;\n        }\n\n        // Append operations for the chosen string\n        operations.insert(operations.end(), ops_for_best_t.begin(), ops_for_best_t.end());\n        current_r = best_end_r;\n        current_c = best_end_c;\n        total_cost += min_iter_cost;\n        \n        // Remove the typed string from the set of uncovered indices\n        uncovered_indices.erase(best_t_idx);\n    }\n\n    // Output the operations\n    cout << operations.size() << endl;\n    for (const auto& op : operations) {\n        cout << op.first + 1 << \" \" << op.second + 1 << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath> // Included for completeness, though not directly used in the final strategy.\n#include <iomanip> // Included for completeness, though not directly used in the final strategy.\n#include <utility> // Required for std::pair.\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // This can significantly speed up input/output operations, which is crucial\n    // for problems with large I/O or strict time limits.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // The size of the island grid (N x N). Constraints: 10 <= N <= 20.\n    int m; // The number of unexplored oil fields. Constraints: 2 <= M <= 20.\n    double epsilon; // The error parameter for the noisy divine query operation. Constraints: 0.01 <= epsilon <= 0.2.\n\n    // Read the initial problem parameters from standard input.\n    std::cin >> n >> m >> epsilon;\n\n    // Read the shapes of the M oil fields.\n    // Each shape is defined by its area (d) and a list of relative coordinates\n    // for the squares it occupies.\n    // For the chosen strategy (drilling every square), this information is not directly used.\n    // A more complex heuristic or optimization strategy might leverage these shapes\n    // to infer potential locations or prune search spaces.\n    for (int k = 0; k < m; ++k) {\n        int d; // The number of squares in the k-th oil field (area).\n        std::cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int r, c; // Relative coordinates (row, column) of a square within the k-th oil field shape.\n            std::cin >> r >> c;\n            // The current strategy ignores these shapes.\n        }\n    }\n\n    // This vector will store the coordinates (row, column) of all squares\n    // that are found to contain oil reserves (i.e., v(i,j) > 0).\n    // This list will form the basis of our final \"guess\" operation.\n    std::vector<std::pair<int, int>> positive_oil_squares;\n\n    // --- Chosen Strategy: Drill every square on the island ---\n    //\n    // This is a deterministic, brute-force approach. It queries each of the N*N squares\n    // individually to reveal its exact oil reserve value v(i,j).\n    //\n    // Cost Analysis:\n    // - Operation Type: \"Drill\" (q 1 i j). Cost per operation: 1.\n    // - Total number of squares on the island: N*N.\n    // - Total cost for performing N*N drill operations: N*N.\n    //\n    // Operation Limit Analysis:\n    // - The problem statement allows a maximum of 2*N*N operations in total.\n    // - For the maximum island size N=20, N*N = 400 operations, and 2*N*N = 800 operations.\n    // - The N*N cost of this strategy is well within the allowed operation limit.\n    //\n    // Correctness Guarantee:\n    // - By drilling every square, we obtain the exact value of v(i,j) for every cell.\n    // - This guarantees that we can precisely identify *all* squares where v(i,j) > 0.\n    // - The final \"guess\" operation will therefore be 100% accurate, leading to a successful completion.\n    //\n    // Justification for ignoring the \"divine\" operation:\n    // - The \"divine\" operation (querying a set S of k squares) has a cost of 1/sqrt(k) but returns a noisy sum.\n    // - The noise (variance) increases with k, making it difficult to obtain precise information about individual v(i,j) values,\n    //   especially small values or distinguishing v(i,j)=0 from v(i,j)=1.\n    // - To guarantee identifying *all* squares with v(i,j) > 0, definitive information is required. Drilling provides this.\n    // - Given the small constraints on N (N <= 20), the total cost of N*N is sufficiently low. The guaranteed correctness\n    //   and simplicity of the drilling strategy make it a robust choice for achieving a high score. More complex strategies\n    //   involving divine queries might offer marginal benefits only for much larger grid sizes.\n    //\n    // Implementation Loop:\n    // - We iterate through each row 'i' from 0 to N-1.\n    // - Within each row, we iterate through each column 'j' from 0 to N-1.\n    // - For every square (i, j), we issue a \"drill\" query.\n    // - We then read the revealed oil reserves for that square.\n    // - If the reserves are positive, we record the square's coordinates.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            // Output the drill query command: \"q 1 <row> <column>\"\n            // std::endl automatically flushes the output buffer.\n            std::cout << \"q 1 \" << i << \" \" << j << std::endl;\n\n            int reserves; // The value v(i, j) revealed for the current square.\n            std::cin >> reserves; // Read the result from standard input.\n\n            // If the square contains oil (reserves > 0), store its coordinates.\n            if (reserves > 0) {\n                positive_oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // --- Output the Final Guess ---\n    //\n    // Once all squares have been drilled, the 'positive_oil_squares' vector contains\n    // the exact set of squares that have oil reserves. We now form the final \"guess\" operation.\n    //\n    // The format for the guess operation is: \"a <d> <i1> <j1> <i2> <j2> ...\"\n    // where 'd' is the total number of squares guessed to have oil.\n    std::cout << \"a \" << positive_oil_squares.size();\n    for (const auto& p : positive_oil_squares) {\n        std::cout << \" \" << p.first << \" \" << p.second;\n    }\n    std::cout << std::endl; // Flush the output buffer to ensure the guess is sent.\n\n    // --- Read Confirmation from Judge ---\n    //\n    // The judge will respond with '1' if our guess is correct and '0' if it is incorrect.\n    // Given the deterministic nature of the drilling strategy, we expect this to always be '1'.\n    int correct;\n    std::cin >> correct;\n\n    // If the guess was correct, the program has successfully completed its task.\n    if (correct == 1) {\n        return 0; // Exit with a success code.\n    } else {\n        // If the guess was incorrect (correct == 0), this indicates an unexpected issue.\n        // The N^2 drilling strategy is designed to be infallible for this problem.\n        // If this branch is reached, it might point to a subtle problem interpretation error\n        // or an extremely rare edge case. We exit with a non-zero code to signal abnormal termination.\n        return 1; \n    }\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n\nusing namespace std;\n\nlong long W;\nint D, N;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    long long area;\n};\n\nvector<Rect> base_rects;\nvector<vector<pair<int, int>>> a_d_k; // stores {area, original_k} for each day\nvector<pair<Rect, int>> sorted_base_rects_with_idx; // stores {Rect, original_idx}\nvector<vector<int>> day_assignment_map; // day_assignment_map[d][sorted_input_idx] = sorted_base_idx\n\n// Hungarian algorithm implementation to find minimum weight perfect matching\n// n: number of tasks (reservations after sorting by area)\n// m: number of workers (base rectangles after sorting by area)\n// cost_matrix[i][j]: cost of assigning task i to worker j\n// Returns assignment[i] = j, meaning task i is assigned to worker j\nvector<int> hungarian(const vector<vector<long long>>& cost_matrix) {\n    int n = cost_matrix.size(); // Number of tasks\n    int m = cost_matrix[0].size(); // Number of workers\n    int dim = max(n, m);\n\n    // Pad cost matrix to be square with high costs for non-existent assignments\n    vector<vector<long long>> cost(dim, vector<long long>(dim, 1e18));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < m; ++j) {\n            cost[i][j] = cost_matrix[i][j];\n        }\n    }\n\n    vector<long long> u(dim, 0), v(dim, 0); // Potentials for tasks and workers\n    vector<int> p(dim, -1); // p[j] = task assigned to worker j\n    vector<int> way(dim, -1); // way[j] = predecessor task for worker j in augmenting path\n\n    for (int i = 0; i < dim; ++i) { // For each task i\n        vector<long long> minv(dim, 1e18); // min slack for each worker j\n        vector<bool> used_workers(dim, false); // visited workers in current BFS\n        int current_task = i; // task to be assigned\n\n        // Find augmenting path using BFS-like approach\n        while (true) {\n            used_workers[current_task] = true; // Mark current task as visited (conceptually, as part of path from current task i)\n                                               // This is actually `p` in many implementations for worker assignment, used here as task for path.\n                                               // Let's use `p` for worker->task assignment and `way` for path reconstruction.\n                                               // `match_to[j]` stores task index for worker j. `way[j]` stores task index that led to worker j.\n\n            int j0 = -1; // worker with minimum slack\n            long long delta = 1e18;\n\n            // Update slacks and find minimum delta\n            for (int j = 0; j < dim; ++j) {\n                if (!used_workers[j]) {\n                    long long current_slack = cost[current_task][j] - u[current_task] - v[j];\n                    if (current_slack < minv[j]) {\n                        minv[j] = current_slack;\n                        way[j] = current_task; // task `current_task` is predecessor for worker `j`\n                    }\n                    if (minv[j] < delta) {\n                        delta = minv[j];\n                        j0 = j; // worker `j0` has the minimum slack\n                    }\n                }\n            }\n\n            // Update potentials\n            for (int j = 0; j < dim; ++j) {\n                if (used_workers[j]) {\n                    u[p[j]] += delta; // For tasks already in path (assigned to visited workers)\n                    v[j] -= delta;    // For visited workers\n                } else {\n                    minv[j] -= delta; // Update slack for unvisited workers\n                }\n            }\n            u[current_task] += delta; // Potential for the current task\n\n            // Augment path: update assignments\n            // `p[j0]` is the task previously assigned to worker `j0`.\n            // `way[j0]` is the task that led to worker `j0` (i.e., `current_task` in previous iteration if `j0` was chosen then).\n            int prev_task = way[j0]; // Task that led to worker j0\n            int next_task = p[j0];   // Task that worker j0 was previously assigned to\n            p[j0] = prev_task;       // Assign worker j0 to task prev_task\n            current_task = next_task; // Continue augmenting path from the task previously assigned to j0\n\n            if (current_task == -1) break; // Path augmented fully\n        }\n    }\n\n    // Extract assignment\n    vector<int> assignment(n); // assignment[task_idx] = worker_idx\n    for (int j = 0; j < dim; ++j) {\n        if (p[j] != -1 && p[j] < n) { // If worker j is assigned to task p[j] and task p[j] is valid\n            assignment[p[j]] = j;\n        }\n    }\n    return assignment;\n}\n\n// Recursive function to generate base rectangles\nvoid generate_base_rects(int x0, int y0, int x1, int y1, int count_needed) {\n    if (count_needed == 0) return;\n\n    if (count_needed == 1) {\n        base_rects.push_back({x0, y0, x1, y1, (long long)(x1 - x0) * (y1 - y0)});\n        return;\n    }\n\n    long long total_width = x1 - x0;\n    long long total_height = y1 - y0;\n\n    int num_left = count_needed / 2;\n    int num_right = count_needed - num_left;\n\n    if (total_width >= total_height) { // Split vertically (along X-axis)\n        // Calculate mid_x to make areas proportional to num_left/num_right\n        long long mid_x = x0 + total_width * num_left / count_needed;\n        generate_base_rects(x0, y0, mid_x, y1, num_left);\n        generate_base_rects(mid_x, y0, x1, y1, num_right);\n    } else { // Split horizontally (along Y-axis)\n        // Calculate mid_y to make areas proportional to num_left/num_right\n        long long mid_y = y0 + total_height * num_left / count_needed;\n        generate_base_rects(x0, y0, x1, mid_y, num_left);\n        generate_base_rects(x0, mid_y, x1, y1, num_right);\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> W >> D >> N;\n\n    a_d_k.resize(D);\n    for (int d = 0; d < D; ++d) {\n        a_d_k[d].resize(N);\n        for (int k = 0; k < N; ++k) {\n            cin >> a_d_k[d][k].first;\n            a_d_k[d][k].second = k; // Store original index\n        }\n        // Sort areas for the current day in descending order\n        sort(a_d_k[d].rbegin(), a_d_k[d].rend());\n    }\n\n    // Generate N base rectangles that tile WxW\n    generate_base_rects(0, 0, W, W, N);\n\n    // Store base rectangles with their original indices (0 to N-1)\n    sorted_base_rects_with_idx.resize(N);\n    for (int i = 0; i < N; ++i) {\n        sorted_base_rects_with_idx[i] = {base_rects[i], i};\n    }\n    // Sort base rectangles by area in descending order\n    sort(sorted_base_rects_with_idx.rbegin(), sorted_base_rects_with_idx.rend(), \n         [](const auto& a, const auto& b) {\n             return a.first.area < b.first.area;\n         });\n\n    // Calculate the fixed partition cost L_base\n    long long L_base = 0;\n    for (int i = 0; i < N; ++i) {\n        const Rect& r = sorted_base_rects_with_idx[i].first;\n        long long h = r.x1 - r.x0;\n        long long w = r.y1 - r.y0;\n        if (r.x0 > 0) L_base += w; // Left boundary\n        if (r.x1 < W) L_base += w; // Right boundary\n        if (r.y0 > 0) L_base += h; // Top boundary\n        if (r.y1 < W) L_base += h; // Bottom boundary\n    }\n\n    // Prepare assignment maps\n    day_assignment_map.resize(D, vector<int>(N));\n    long long total_area_cost = 0;\n\n    // For each day, solve the assignment problem\n    for (int d = 0; d < D; ++d) {\n        // Cost matrix for day d: task (sorted reservation) -> worker (sorted base rectangle)\n        vector<vector<long long>> cost_matrix(N, vector<long long>(N));\n        for (int i = 0; i < N; ++i) { // For each sorted reservation (task i)\n            for (int j = 0; j < N; ++j) { // For each sorted base rectangle (worker j)\n                long long required_area = a_d_k[d][i].first;\n                long long available_area = sorted_base_rects_with_idx[j].first.area;\n                cost_matrix[i][j] = 100LL * max(0LL, required_area - available_area);\n            }\n        }\n\n        // Solve assignment problem\n        vector<int> assignment_for_day = hungarian(cost_matrix); // assignment_for_day[i] = j means sorted task i is assigned to sorted worker j\n\n        // Store assignment and calculate area cost for this day\n        vector<int> current_day_final_assignment(N); // current_day_final_assignment[original_k] = original_base_rect_idx\n        for (int i = 0; i < N; ++i) { // i is sorted_input_idx\n            int sorted_base_idx = assignment_for_day[i];\n            int original_k = a_d_k[d][i].second; // original reservation index for sorted task i\n            int original_base_rect_idx = sorted_base_rects_with_idx[sorted_base_idx].second; // original base rectangle index for sorted worker j\n\n            current_day_final_assignment[original_k] = original_base_rect_idx;\n\n            // Add area cost for this reservation\n            long long required_area = a_d_k[d][i].first;\n            long long assigned_area = sorted_base_rects_with_idx[sorted_base_idx].first.area;\n            total_area_cost += 100LL * max(0LL, required_area - assigned_area);\n        }\n        day_assignment_map[d] = current_day_final_assignment;\n    }\n\n    // Total cost = sum of area costs + sum of partition costs\n    // Partition cost is (D-1) * L_base because layout is fixed daily.\n    long long total_cost = total_area_cost + (long long)(D - 1) * L_base;\n\n    // Output the rectangles\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) { // k is original reservation index\n            int base_rect_idx = day_assignment_map[d][k];\n            const Rect& r = base_rects[base_rect_idx]; // Use base_rects directly via original index\n            cout << r.x0 << \" \" << r.y0 << \" \" << r.x1 << \" \" << r.y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n// Use long long for N, M, K to be safe, though they are small in constraints.\n// Renamed to avoid potential conflicts or confusion with problem-defined variables if problem used N, M, K directly in context.\nlong long N_val, M_val, K_val; \nlong long MOD = 998244353;\n\n// The board values can grow large, so use long long.\nvector<vector<long long>> board;\n// Stamp values are given and used, also use long long for consistency.\nvector<vector<vector<long long>>> stamps;\n// Stores the chosen operations: {stamp_index, row_p, col_q}\nvector<tuple<int, int, int>> operations;\n\n// Function to calculate the gain of applying a specific stamp at a specific position.\n// Gain is defined as the total increase in the sum of (cell_value mod MOD) over all affected cells.\n// This sum can be negative if applying the stamp decreases the total score modulo MOD.\nlong long calculate_gain(int stamp_idx, int p, int q) {\n    long long current_gain_sum = 0; // This sum can be negative.\n    \n    // Iterate over the 3x3 area of the stamp.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int r = p + i; // Row on the board\n            int c = q + j; // Column on the board\n\n            // Current score contribution of the cell (r, c)\n            // This is board[r][c] modulo MOD.\n            long long current_score_contrib = board[r][c] % MOD;\n            \n            // Value from the stamp at (i, j)\n            long long stamp_val = stamps[stamp_idx][i][j];\n            \n            // New score contribution of the cell (r, c) after adding the stamp value.\n            // (board[r][c] + stamp_val) can be large, but % MOD brings it to the score range.\n            long long new_score_contrib = (board[r][c] + stamp_val) % MOD;\n            \n            // The change in score for this specific cell.\n            // This difference can be negative if new_score_contrib < current_score_contrib (due to modulo wrap-around).\n            long long delta = new_score_contrib - current_score_contrib;\n            \n            // Add the cell's score change to the total gain for this stamp operation.\n            current_gain_sum += delta;\n        }\n    }\n    return current_gain_sum;\n}\n\n// Applies a chosen stamp to the board and records the operation.\nvoid apply_stamp(int stamp_idx, int p, int q) {\n    operations.emplace_back(stamp_idx, p, q);\n    \n    // Update the board values by adding the stamp values.\n    // Note: board[r][c] stores the accumulated sum, not modulo MOD.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] += stamps[stamp_idx][i][j];\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input values for N, M, K.\n    cin >> N_val >> M_val >> K_val;\n\n    // Initialize the board with given values.\n    board.resize(N_val, vector<long long>(N_val));\n    for (int i = 0; i < N_val; ++i) {\n        for (int j = 0; j < N_val; ++j) {\n            cin >> board[i][j];\n        }\n    }\n\n    // Read stamp definitions.\n    stamps.resize(M_val, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M_val; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n\n    // Greedy strategy:\n    // In each step, select the stamp operation that yields the maximum immediate score increase.\n    // We can perform AT MOST K_val operations.\n    // If the best operation provides a non-positive gain (i.e., zero or negative),\n    // it means no further score improvement is possible with this greedy approach, so we stop.\n    for (int k = 0; k < K_val; ++k) {\n        // Initialize max_gain to a very small value. A sufficiently small negative number\n        // guarantees that any actual gain (positive, zero, or negative) will be greater.\n        long long max_gain = -4e18; // Using a very small number to ensure any gain is larger.\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        // Iterate over all possible stamp types (M_val).\n        for (int m = 0; m < M_val; ++m) {\n            // Iterate over all possible top-left positions (p, q) for the stamp.\n            // A 3x3 stamp can be placed with its top-left corner at (p, q)\n            // such that p ranges from 0 to N_val-3, and q ranges from 0 to N_val-3.\n            for (int p = 0; p <= N_val - 3; ++p) {\n                for (int q = 0; q <= N_val - 3; ++q) {\n                    // Calculate the score gain if we apply stamp 'm' at position (p, q).\n                    long long current_gain = calculate_gain(m, p, q);\n                    \n                    // If this operation gives a better gain than any seen so far, update our best choice.\n                    if (current_gain > max_gain) {\n                        max_gain = current_gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // After checking all possible operations, if the maximum gain found is strictly positive,\n        // apply the best operation. Otherwise, stop.\n        if (max_gain > 0) {\n            apply_stamp(best_m, best_p, best_q);\n        } else {\n            // No operation yields a positive score increase.\n            // Adhering to \"at most K times\" and aiming to maximize score, we terminate.\n            break; \n        }\n    }\n\n    // Output the number of operations performed.\n    cout << operations.size() << endl;\n    // Output each operation: stamp index, board row, board column.\n    for (const auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << endl;\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int MAX_TURNS = 10000;\nint N;\n\n// Grid state\nvector<vector<int>> grid; // container ID, -1 if empty\nvector<vector<int>> crane_id_at; // crane ID, -1 if empty\n\n// Crane state\nstruct Crane {\n    int id;\n    pair<int, int> pos;\n    int holding_container_id; // -1 if not holding\n    bool is_large;\n    int base_priority; // For task assignment logic\n};\nvector<Crane> cranes;\n\n// Container state is implicitly managed by grid and crane_holding_id\n\n// Receiving Gate state\nvector<int> receiving_gate_next_container_idx; // For each receiving gate i, index into A[i]\n\n// Dispatch Gate state\nvector<int> dispatch_gate_expected_container; // For each dispatch gate i, the ID of the next container to be dispatched. -1 if all dispatched.\n\n// Container to Target Gate mapping\nvector<int> container_target_gate;\n\n// Temporary storage cells\nvector<pair<int, int>> temp_storage_cells;\n\n// Helper to check if a cell is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Helper to get target dispatch gate for a container\nint get_target_gate(int container_id) {\n    if (container_id < 0) return -1; // Should not happen for valid containers\n    return container_id / N;\n}\n\n// BFS for pathfinding (single step calculation)\npair<int, int> get_next_step(pair<int, int> current_pos, pair<int, int> target_pos) {\n    if (current_pos == target_pos) return current_pos;\n\n    int r = current_pos.first;\n    int c = current_pos.second;\n    int tr = target_pos.first;\n    int tc = target_pos.second;\n\n    int dr = tr - r;\n    int dc = tc - c;\n\n    pair<int, int> next_pos = current_pos;\n\n    // Prioritize axis with larger distance\n    if (abs(dr) >= abs(dc)) {\n        if (dr > 0) next_pos = {r + 1, c}; // D\n        else if (dr < 0) next_pos = {r - 1, c}; // U\n    } else { // abs(dc) > abs(dr)\n        if (dc > 0) next_pos = {r, c + 1}; // R\n        else if (dc < 0) next_pos = {r, c - 1}; // L\n    }\n    \n    // If the calculated next_pos is the same as current_pos, it means no move in the prioritized direction.\n    // This can happen if dr or dc is 0, and the other is also 0 (already at target), or if the step is somehow invalid.\n    // For simplicity, we assume it will always calculate a valid adjacent step if not already at target.\n    return next_pos;\n}\n\n// Crane Task types for priority\nenum TaskType {\n    WAIT,\n    PICKUP_REC,       // Pickup from Receiving Gate\n    PICKUP_TEMP,      // Pickup from Temporary Storage\n    STORE_CONTAINER,  // Store container in Temporary Storage\n    DELIVER_TO_GATE   // Deliver container to Dispatch Gate\n};\n\n// Structure to hold a crane's task and its priority\nstruct CraneTask {\n    TaskType type;\n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n};\n\n// Function to determine the crane's highest priority task\nCraneTask determine_crane_task(int crane_idx) {\n    Crane& crane = cranes[crane_idx];\n    pair<int, int> current_pos = crane.pos;\n\n    int base_priority = crane.base_priority;\n\n    // Task 4: DELIVER_TO_GATE\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n        \n        if (target_gate >= 0 && target_gate < N && container_id == dispatch_gate_expected_container[target_gate]) {\n            pair<int, int> deliver_pos = {target_gate, N - 1};\n            // Priority: DELIVER_TO_GATE > PICKUP_REQ > STORE > PICKUP_PROACTIVE > WAIT\n            return {DELIVER_TO_GATE, deliver_pos, base_priority + 10};\n        }\n    }\n\n    // Task 1 & 2: PICKUP_REQ (from Receiving Gate or Temp Storage)\n    if (crane.holding_container_id == -1) {\n        // Check for required containers at dispatch gates\n        for (int i = 0; i < N; ++i) { // Iterate through dispatch gates\n            int expected_container = dispatch_gate_expected_container[i];\n            if (expected_container != -1) { // If a container is still expected for this gate\n                // Check if this container belongs to gate i\n                if (get_target_gate(expected_container) == i) {\n                    // Find its current location\n                    // Check Receiving Gates (Task 1: PICKUP_REC)\n                    if (grid[i][0] == expected_container) {\n                        return {PICKUP_REC, {i, 0}, base_priority + 8};\n                    }\n                    // Check Temporary Storage Cells (Task 2: PICKUP_TEMP)\n                    for (const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == expected_container) {\n                            return {PICKUP_TEMP, cell, base_priority + 7};\n                        }\n                    }\n                }\n            }\n        }\n\n        // Task 1 (low priority): Proactive fetch from Receiving Gates\n        for (int i = 0; i < N; ++i) { // Iterate through receiving gates\n            if (receiving_gate_next_container_idx[i] < N) { // If containers are still arriving\n                // Check if cell (i,0) has an arrived container and is not occupied by a crane\n                if (grid[i][0] != -1 && crane_id_at[i][0] == -1) { \n                    // Check if there's an available temporary storage cell to move it to\n                    pair<int, int> temp_storage_target = {-1, -1};\n                    for(const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                            temp_storage_target = cell;\n                            break;\n                        }\n                    }\n                    if (temp_storage_target != make_pair(-1, -1)) {\n                        return {PICKUP_REC, {i, 0}, base_priority + 2}; // PICKUP_REC, low priority\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 3: STORE_CONTAINER\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n\n        // If the container is NOT the next one needed for its dispatch gate\n        if (!(target_gate >= 0 && target_gate < N && container_id == dispatch_gate_expected_container[target_gate])) {\n            // Find an available temp storage cell\n            pair<int, int> temp_storage_target = {-1, -1};\n            for (const auto& cell : temp_storage_cells) {\n                if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                    temp_storage_target = cell;\n                    break;\n                }\n            }\n            if (temp_storage_target != make_pair(-1, -1)) {\n                return {STORE_CONTAINER, temp_storage_target, base_priority + 5}; // STORE, medium priority\n            }\n        }\n    }\n\n    // Task 0: WAIT\n    return {WAIT, current_pos, base_priority}; // Default to WAIT\n}\n\n// Structure to hold a crane's requested move for collision resolution\nstruct MoveRequest {\n    int crane_idx;\n    TaskType task_type;\n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n\n    bool operator<(const MoveRequest& other) const {\n        return priority > other.priority; // Sort by priority descending\n    }\n};\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    grid.assign(N, vector<int>(N, -1));\n    crane_id_at.assign(N, vector<int>(N, -1));\n    receiving_gate_next_container_idx.assign(N, 0);\n    dispatch_gate_expected_container.assign(N, -1); // Initialize with -1\n\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n        }\n    }\n\n    // Initialize container_target_gate mapping\n    container_target_gate.resize(N * N);\n    for (int i = 0; i < N * N; ++i) {\n        container_target_gate[i] = get_target_gate(i);\n    }\n\n    // Initialize dispatch gate expected containers\n    for (int i = 0; i < N; ++i) {\n        dispatch_gate_expected_container[i] = N * i;\n    }\n\n    // Initialize cranes\n    cranes.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].id = i;\n        cranes[i].pos = {i, 0};\n        cranes[i].holding_container_id = -1;\n        cranes[i].is_large = (i == 0);\n        cranes[i].base_priority = (i == 0) ? 100 : 10 - i; // LC has highest priority, SCs have decreasing priority\n\n        crane_id_at[i][0] = i; // Place cranes on grid\n    }\n\n    // Initialize temporary storage cells. Aim for inner cells, away from edges.\n    for (int r = 1; r < N - 1; ++r) {\n        for (int c = 1; c < N - 1; ++c) {\n            temp_storage_cells.push_back({r, c});\n        }\n    }\n    // If N is small (e.g., N=1, N=2), the inner grid might not exist. Add cells from other rows/columns if available.\n    if (temp_storage_cells.empty() && N > 1) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 1; c < N - 1; ++c) { // Cells not on the left edge (receiving gates)\n                temp_storage_cells.push_back({r, c});\n            }\n        }\n    }\n     // Ensure we have some temp cells, if N=1 this loop might add nothing.\n    if (temp_storage_cells.empty() && N==1) { /* special case for N=1 if needed */ }\n\n\n    vector<string> output_ops(N, \"\");\n\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        // Step 1: Container Arrival\n        for (int i = 0; i < N; ++i) {\n            if (receiving_gate_next_container_idx[i] < N) {\n                // Place container if receiving gate cell is empty (no container, no crane)\n                if (grid[i][0] == -1 && crane_id_at[i][0] == -1) {\n                    int container_id = A[i][receiving_gate_next_container_idx[i]];\n                    grid[i][0] = container_id;\n                    receiving_gate_next_container_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        vector<MoveRequest> requests;\n        \n        // Determine desired tasks for all cranes\n        for (int i = 0; i < N; ++i) {\n            CraneTask task = determine_crane_task(i);\n            requests.push_back({i, task.type, task.target_pos, task.priority});\n        }\n\n        // Sort requests by priority (highest first)\n        sort(requests.begin(), requests.end());\n\n        // Execute moves and resolve conflicts\n        vector<vector<int>> next_crane_id_at = crane_id_at; // Crane positions for the *next* state\n        vector<char> current_turn_actions(N, '.');\n        vector<bool> crane_moved_this_turn(N, false); // Track if a crane has successfully performed an action\n\n        for (const auto& req : requests) {\n            int k = req.crane_idx;\n            if (crane_moved_this_turn[k]) continue; // Already processed this crane successfully\n\n            Crane& crane = cranes[k];\n            pair<int, int> current_pos = crane.pos;\n            pair<int, int> target_pos = req.target_pos;\n            TaskType task_type = req.type;\n            \n            pair<int, int> next_pos = current_pos;\n            char action_char = '.';\n            bool move_is_possible = true;\n\n            // Determine the intended next position and action character\n            if (task_type == DELIVER_TO_GATE || task_type == STORE_CONTAINER) { // Tasks involving releasing a container\n                if (current_pos == target_pos) { // Already at target\n                    action_char = (task_type == DELIVER_TO_GATE) ? 'Q' : 'Q'; // Release container\n                    next_pos = current_pos; // Stay put\n                } else { // Need to move towards target\n                    next_pos = get_next_step(current_pos, target_pos);\n                    if (next_pos.first > current_pos.first) action_char = 'D';\n                    else if (next_pos.first < current_pos.first) action_char = 'U';\n                    else if (next_pos.second > current_pos.second) action_char = 'R';\n                    else if (next_pos.second < current_pos.second) action_char = 'L';\n                    else { // Cannot move towards target, maybe blocked or target is current pos\n                        action_char = '.'; // Stay put\n                        next_pos = current_pos;\n                    }\n                }\n            } else if (task_type == PICKUP_REC || task_type == PICKUP_TEMP) { // Tasks involving picking up a container\n                if (current_pos == target_pos) { // Already at target\n                    action_char = 'P'; // Pick up container\n                    next_pos = current_pos; // Stay put\n                } else { // Need to move towards target\n                    next_pos = get_next_step(current_pos, target_pos);\n                    if (next_pos.first > current_pos.first) action_char = 'D';\n                    else if (next_pos.first < current_pos.first) action_char = 'U';\n                    else if (next_pos.second > current_pos.second) action_char = 'R';\n                    else if (next_pos.second < current_pos.second) action_char = 'L';\n                    else {\n                        action_char = '.'; // Stay put\n                        next_pos = current_pos;\n                    }\n                }\n            } else { // WAIT or other task not requiring specific movement now\n                action_char = '.';\n                next_pos = current_pos;\n            }\n\n            // --- Collision and Constraint Checking ---\n            \n            // 1. Check if destination cell is valid\n            if (!is_valid(next_pos.first, next_pos.second)) {\n                move_is_possible = false;\n            }\n\n            // 2. Check for crane-crane conflicts at destination (next_pos)\n            if (move_is_possible && next_crane_id_at[next_pos.first][next_pos.second] != -1) {\n                // Destination cell will be occupied by another crane (or current crane if next_pos == current_pos)\n                int occupying_crane_id = next_crane_id_at[next_pos.first][next_pos.second];\n                \n                if (occupying_crane_id != k) { // If destination occupied by a DIFFERENT crane\n                    // Check if that occupying crane is moving OUT of the cell AND its target is current_pos (swap conflict)\n                    bool swap_conflict = false;\n                    for (const auto& other_req : requests) { // Check all other requests\n                        if (other_req.crane_idx == occupying_crane_id) {\n                            if (other_req.target_pos == current_pos) { // Occupying crane wants to swap\n                                swap_conflict = true;\n                                break;\n                            }\n                        }\n                    }\n\n                    if (swap_conflict) {\n                        // Swap conflict: current crane k vs occupying_crane_id.\n                        // Since requests are sorted by priority, if we are here, k's priority is lower or equal.\n                        // So, k must wait.\n                        move_is_possible = false;\n                    } else {\n                        // Destination occupied by a crane that's static or moving elsewhere.\n                        // Current crane k cannot move there.\n                        move_is_possible = false;\n                    }\n                } else { // Destination is the current position (crane wants to stay put, potentially to P/Q)\n                    // This is fine if action is P/Q. If action is move, it shouldn't have target_pos == current_pos.\n                    // If action is '.', it's fine.\n                }\n            }\n\n            // 3. Check SC carrying container to a cell with a container (not allowed)\n            if (move_is_possible && !crane.is_large && crane.holding_container_id != -1 && grid[next_pos.first][next_pos.second] != -1) {\n                move_is_possible = false; // Small crane carrying cannot move to cell with a container\n            }\n            \n            // 4. Check if crane is trying to move to a cell occupied by a static container\n            // (This rule applies if the crane is NOT carrying and NOT a large crane carrying)\n            if (move_is_possible && grid[next_pos.first][next_pos.second] != -1) {\n                 // If the cell has a container, can only move there if:\n                 // a) It's the large crane AND it's carrying a container (handled by rule 3 already: this check would pass)\n                 // b) The crane is not carrying anything, AND it's not a large crane carrying something.\n                 // If current crane is NOT large crane carrying a container, and destination has a container, it's blocked.\n                 if (!(!crane.is_large && crane.holding_container_id != -1)) { // If NOT (LC and carrying)\n                     move_is_possible = false;\n                 }\n            }\n            \n            // If crane wants to pick up or drop, and is at target, but target is occupied by another crane.\n            if (move_is_possible && (action_char == 'P' || action_char == 'Q')) {\n                if (next_crane_id_at[next_pos.first][next_pos.second] != -1 && next_crane_id_at[next_pos.first][next_pos.second] != k) {\n                     move_is_possible = false; // Cannot P/Q if destination cell occupied by other crane\n                }\n            }\n\n\n            if (move_is_possible) {\n                // Execute the move\n                current_turn_actions[k] = action_char; // Assign the determined action\n                \n                // Update crane's state for the NEXT turn's grid\n                crane.pos = next_pos;\n                next_crane_id_at[next_pos.first][next_pos.second] = k; // Mark destination as occupied by crane k\n                next_crane_id_at[current_pos.first][current_pos.second] = -1; // Mark old position as empty of crane k\n                crane_moved_this_turn[k] = true;\n\n                // Update container state if P or Q action is performed\n                if (action_char == 'P') {\n                    int container_id = grid[current_pos.first][current_pos.second];\n                    grid[current_pos.first][current_pos.second] = -1; // Container removed from cell\n                    crane.holding_container_id = container_id; // Crane holds container\n                } else if (action_char == 'Q') {\n                    int container_id = crane.holding_container_id;\n                    grid[next_pos.first][next_pos.second] = container_id; // Container placed in cell\n                    crane.holding_container_id = -1; // Crane no longer holds container\n                }\n            } else {\n                // Crane is blocked, stays put\n                current_turn_actions[k] = '.';\n                // crane_moved_this_turn[k] remains false, its pos and holding status don't change\n            }\n        }\n        \n        // Update crane_id_at to reflect the final state after all moves and blocks for this turn\n        crane_id_at = next_crane_id_at;\n\n        // Append actions to output strings\n        for (int i = 0; i < N; ++i) {\n            output_ops[i] += current_turn_actions[i];\n        }\n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; ++i) { // For each dispatch gate i\n            if (dispatch_gate_expected_container[i] != -1 && grid[i][N - 1] != -1) {\n                if (grid[i][N - 1] == dispatch_gate_expected_container[i]) {\n                    // Dispatch container\n                    grid[i][N - 1] = -1; // Remove from dispatch gate\n                    \n                    // Update expected container for this dispatch gate\n                    dispatch_gate_expected_container[i]++;\n                    if (dispatch_gate_expected_container[i] >= N * (i + 1)) {\n                        dispatch_gate_expected_container[i] = -1; // All containers for this gate dispatched\n                    }\n                }\n            }\n        }\n    }\n\n    // Pad output strings with '.' if they are shorter than MAX_TURNS\n    for (int i = 0; i < N; ++i) {\n        while (output_ops[i].length() < MAX_TURNS) {\n            output_ops[i] += '.';\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << output_ops[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n\nusing namespace std;\n\nint N;\nvector<vector<int>> current_height;\npair<int, int> current_pos;\nlong long truck_load;\nvector<string> operations;\n\n// Helper to add an operation to the list.\nvoid add_op(const string& op) {\n    operations.push_back(op);\n}\n\n// Helper to add a load ('+') or unload ('-') operation with a specified amount 'd'.\nvoid add_load_unload(char type, long long d) {\n    // The problem statement specifies d > 0 for load/unload.\n    // Our logic derives d from height differences, which are at most 100, so d will always be > 0 if called.\n    add_op(string(1, type) + to_string(d));\n}\n\n// Helper function to move the truck from its current position to a target cell.\n// It generates the sequence of move operations ('U', 'D', 'L', 'R') and updates current_pos.\nvoid move_to(int target_r, int target_c) {\n    // Move vertically: Up or Down\n    while (current_pos.first < target_r) {\n        add_op(\"D\");\n        current_pos.first++;\n    }\n    while (current_pos.first > target_r) {\n        add_op(\"U\");\n        current_pos.first--;\n    }\n    // Move horizontally: Left or Right\n    while (current_pos.second < target_c) {\n        add_op(\"R\");\n        current_pos.second++;\n    }\n    while (current_pos.second > target_c) {\n        add_op(\"L\");\n        current_pos.second--;\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output, crucial for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the grid size N.\n    cin >> N;\n\n    // Initialize the current_height grid with input heights. This grid will be modified as soil is moved.\n    current_height.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> current_height[i][j];\n        }\n    }\n\n    // Initialize truck state: starting at (0,0) with an empty load.\n    current_pos = {0, 0};\n    truck_load = 0;\n\n    // --- Define a systematic traversal path (Snake Pattern) ---\n    // This path visits every cell in the grid exactly once. It's chosen as a heuristic\n    // to ensure all cells are processed and to provide a structured, deterministic movement.\n    // The path order is (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> (1,N-2) -> ... -> (1,0) -> (2,0) -> ...\n    vector<pair<int, int>> snake_path;\n    snake_path.reserve(N * N); // Reserve memory to avoid reallocations for efficiency.\n    for (int r = 0; r < N; ++r) {\n        if (r % 2 == 0) { // Even rows: traverse from left to right.\n            for (int c = 0; c < N; ++c) {\n                snake_path.push_back({r, c});\n            }\n        } else { // Odd rows: traverse from right to left.\n            for (int c = N - 1; c >= 0; --c) {\n                snake_path.push_back({r, c});\n            }\n        }\n    }\n\n    // --- Pass 1: Collect all positive soil ---\n    // The goal of this pass is to visit all cells that initially have positive height\n    // and load all of their soil onto the truck. This ensures all soil that needs to be\n    // moved out of positive cells is gathered before distribution.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell in the snake path.\n\n        // If the cell has excess soil (positive height), load it onto the truck.\n        if (current_height[r][c] > 0) {\n            long long amount_to_load = current_height[r][c]; // The amount to load is the entire positive height.\n            add_load_unload('+', amount_to_load); // Add the load operation.\n            truck_load += amount_to_load; // Update truck's current load.\n            current_height[r][c] = 0; // The cell's height becomes zero after its excess soil is loaded.\n        }\n    }\n\n    // --- Pass 2: Distribute soil to negative cells ---\n    // After collecting all available soil in Pass 1, this pass aims to unload soil\n    // into cells that need it (have negative height).\n    // The truck's position `current_pos` is already at the end of the last move from Pass 1,\n    // allowing for continuous movement through the grid for this pass.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If the cell needs soil (has negative height).\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c]; // Calculate how much soil is needed (absolute value of negative height).\n            // Unload the minimum of what's needed for this cell and what's currently available on the truck.\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) { // If we can unload any soil (i.e., truck has soil and cell needs it).\n                add_load_unload('-', to_unload); // Add the unload operation.\n                truck_load -= to_unload; // Update truck's load.\n                current_height[r][c] += to_unload; // Add soil to the cell, reducing its deficit.\n            }\n        }\n    }\n\n    // --- Pass 3: Deliver any remaining truck load ---\n    // This is a crucial cleanup pass designed to resolve any remaining imbalances.\n    // It addresses two potential scenarios:\n    // 1. If `truck_load` is still positive after Pass 2, it means there's soil left on the truck\n    //    that needs to be delivered to some cell.\n    // 2. If some cells still have negative height after Pass 2, they still require soil.\n    // The snake path is traversed for a third time. This ensures that any remaining soil on the truck\n    // is delivered to cells that still have a deficit, thereby bringing all cell heights to zero.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If this cell still needs soil, unload from the truck.\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c];\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) {\n                add_load_unload('-', to_unload);\n                truck_load -= to_unload;\n                current_height[r][c] += to_unload;\n            }\n        }\n    }\n\n    // The problem statement guarantees that the sum of initial heights across the grid is exactly 0.\n    // This fundamental property ensures that the total amount of soil loaded in Pass 1 will be\n    // exactly equal to the total amount of soil that needs to be unloaded into negative-height cells.\n    // Therefore, after these three passes, `truck_load` is guaranteed to be 0, and all `current_height` values\n    // are guaranteed to be 0. No further loops or checks are needed to ensure all cells are leveled.\n    // The `min(needed, truck_load)` logic in Passes 2 and 3 handles the distribution correctly.\n\n    // Output all the generated operations, one per line.\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <numeric> // Not strictly necessary as sum is manual, but good practice to include if using numeric algorithms.\n#include <algorithm> // For std::sort\n\n// Use long long for sums to avoid potential overflow.\n// With M=15 and max value 100 per component, the max sum for a single seed is 15*100 = 1500,\n// which fits in a 32-bit integer. However, using `long long` is safer practice and has no performance penalty here.\nusing ll = long long;\n\n// Structure to hold seed information: its identifier, evaluation vector, and sum of values.\nstruct Seed {\n    int id; // Identifier of the seed within the current generation (0 to seed_count-1).\n    std::vector<int> evaluation_vector;\n    ll sum_v;\n\n    // Custom comparison operator for sorting seeds by sum_v in descending order.\n    // std::sort uses operator< to sort in ascending order. By defining it such that\n    // `a < b` if `a.sum_v > b.sum_v`, we achieve descending order sorting.\n    bool operator<(const Seed& other) const {\n        return sum_v > other.sum_v;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // Disables synchronization with C stdio and unties cin from cout for faster I/O.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, T;\n    std::cin >> N >> M >> T;\n\n    // Total number of seeds in each generation.\n    // For N=6, this is 2 * 6 * (6 - 1) = 2 * 6 * 5 = 60 seeds.\n    int seed_count = 2 * N * (N - 1);\n\n    // Vector to hold the current generation of seeds.\n    std::vector<Seed> current_seeds(seed_count);\n\n    // Read initial seeds. Their initial indices are implicitly 0, 1, ..., seed_count-1.\n    for (int i = 0; i < seed_count; ++i) {\n        current_seeds[i].id = i; // Assign initial ID for this seed.\n        current_seeds[i].evaluation_vector.resize(M);\n        ll current_sum = 0;\n        for (int j = 0; j < M; ++j) {\n            std::cin >> current_seeds[i].evaluation_vector[j];\n            current_sum += current_seeds[i].evaluation_vector[j];\n        }\n        current_seeds[i].sum_v = current_sum;\n    }\n\n    // Main loop for T turns of the operation.\n    for (int t = 0; t < T; ++t) {\n        // 1. Sort the current seeds based on their sum_v in descending order.\n        // The `std::sort` function uses the `operator<` defined in the `Seed` struct.\n        std::sort(current_seeds.begin(), current_seeds.end());\n\n        // 2. Select the top N*N seeds for planting.\n        // These are the first N*N seeds in the sorted `current_seeds` vector.\n        // We need to output their `id`s arranged in the N*N grid.\n        std::vector<std::vector<int>> A(N, std::vector<int>(N));\n        \n        // Assign selected seeds to grid cells in row-major order.\n        // The seed placed at A[i][j] is the (i*N + j)-th best seed from the sorted list.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                // `current_seeds[i * N + j]` refers to the Seed struct which is the (i*N + j)-th best.\n                // Its `id` field holds the identifier of this seed within the current generation.\n                A[i][j] = current_seeds[i * N + j].id;\n            }\n        }\n\n        // 3. Output the grid assignment to standard output.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                std::cout << A[i][j] << (j == N - 1 ? \"\" : \" \"); // Space separated values, no space after last element in a row.\n            }\n            std::cout << std::endl; // Newline after each row.\n        }\n        std::cout.flush(); // Ensure the output is sent immediately to the judge.\n\n        // 4. Read the evaluation vectors of the newly generated seeds for the next generation.\n        std::vector<Seed> next_seeds(seed_count);\n        for (int i = 0; i < seed_count; ++i) {\n            // Assign new sequential IDs (0 to seed_count-1) for the seeds in the next generation.\n            next_seeds[i].id = i; \n            next_seeds[i].evaluation_vector.resize(M);\n            ll current_sum = 0;\n            for (int j = 0; j < M; ++j) {\n                std::cin >> next_seeds[i].evaluation_vector[j];\n                current_sum += next_seeds[i].evaluation_vector[j];\n            }\n            next_seeds[i].sum_v = current_sum;\n        }\n\n        // 5. Replace the current seeds with the newly generated ones.\n        // `std::move` is used for efficiency, as it transfers ownership of the\n        // `next_seeds` vector's internal buffer to `current_seeds` without copying elements.\n        current_seeds = std::move(next_seeds);\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <numeric> // For std::iota\n\n// Global variables for grid and arm parameters\nint N_GRID, M_TAKOYAKI, V_ARM;\n\n// Structure for 2D points\nstruct Point {\n    int r, c;\n    // Equality operators for comparisons\n    bool operator==(const Point& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Manhattan distance for grid movement cost\nint manhattan_distance(Point p1, Point p2) {\n    return std::abs(p1.r - p2.r) + std::abs(p1.c - p2.c);\n}\n\n// --- Arm Design Parameters ---\nint V_prime; // Actual number of vertices in the arm (<= V_ARM)\nstd::vector<int> parent_map; // parent_map[i] is parent of vertex i+1 (0-indexed for edge array)\nstd::vector<int> edge_lengths; // edge_lengths[i] is length of edge connected to vertex i+1\nstd::vector<int> edge_orientations; // Current orientation of edges: 0:R(0,+1), 1:D(+1,0), 2:L(0,-1), 3:U(-1,0)\n\nPoint root_pos; // Current position of the arm's root\nstd::vector<Point> vertex_pos; // Stores current positions of all arm vertices\nstd::vector<int> fingertip_vertex_ids; // Vertex IDs that are fingertips\nstd::vector<int> joint_vertex_ids; // Vertex IDs that are joints (internal nodes, can rotate subtrees)\n\n// Direction vectors for R, D, L, U\nint dr[] = {0, 1, 0, -1}; // Corresponds to orientations 0, 1, 2, 3\nint dc[] = {1, 0, -1, 0}; // Corresponds to orientations 0, 1, 2, 3\n\n// Function to calculate the positions of all vertices based on root_pos and edge_orientations\nvoid calculate_vertex_positions() {\n    vertex_pos.assign(V_prime, {0, 0});\n    vertex_pos[0] = root_pos;\n\n    // Use BFS-like approach to calculate positions layer by layer\n    // For a tree, we can use a queue or simply iterate based on parent-child relationships.\n    // Let's build adjacency list for easier traversal.\n    std::vector<std::vector<std::pair<int, int>>> adj(V_prime); // {child_vertex_id, edge_index}\n    std::vector<int> edge_idx_for_child(V_prime, -1); // edge_idx_for_child[v] gives index for edge (p,v)\n\n    for (int i = 0; i < V_prime - 1; ++i) {\n        int p = parent_map[i];\n        int child = i + 1; // Vertex ID of child in path graph\n        adj[p].push_back({child, i});\n        edge_idx_for_child[child] = i;\n    }\n\n    std::vector<int> q;\n    q.push_back(0);\n    std::vector<bool> visited(V_prime, false);\n    visited[0] = true;\n\n    int head = 0;\n    while(head < q.size()) {\n        int u = q[head++];\n        \n        // Iterate through children of u\n        for (auto& edge_info : adj[u]) {\n            int v = edge_info.first;\n            int edge_idx = edge_info.second;\n\n            if (!visited[v]) {\n                int orientation = edge_orientations[edge_idx];\n                int length = edge_lengths[edge_idx];\n                \n                vertex_pos[v].r = vertex_pos[u].r + dr[orientation] * length;\n                vertex_pos[v].c = vertex_pos[u].c + dc[orientation] * length;\n                \n                q.push_back(v);\n                visited[v] = true;\n            }\n        }\n    }\n}\n\n// --- Takoyaki and Target Management ---\nstruct Takoyaki {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_taken; // Whether this takoyaki is currently held by a fingertip\n};\nstruct Target {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_filled; // Whether this target square is occupied by a takoyaki\n};\n\nstd::vector<Takoyaki> takoyaki_list;\nstd::vector<Target> target_list;\n\n// --- Fingertip State Management ---\nstruct Fingertip {\n    int vertex_id; // The vertex ID of this fingertip in the arm\n    bool is_holding; // True if currently holding a takoyaki\n    int holding_takoyaki_idx; // Index in takoyaki_list if holding, -1 otherwise\n    int assigned_pickup_source_idx; // Index in takoyaki_list for planned pickup, -1 if none\n    int assigned_drop_target_idx; // Index in target_list for planned drop, -1 if none\n};\nstd::vector<Fingertip> fingertips;\n\n// --- Operation String Generation ---\n// Generates the operation string for the current turn.\nstd::string generate_operation_string(int current_turn) {\n    std::string S(2 * V_prime, '.'); // Initialize with no operations\n\n    // 1. Update Arm Positions: Calculate current positions of all vertices.\n    calculate_vertex_positions();\n\n    // 2. Task Assignment: Assign takoyaki to free fingertips and targets to holding fingertips.\n    // Reset previous assignments for this turn.\n    for (auto& ft : fingertips) {\n        ft.assigned_pickup_source_idx = -1;\n        ft.assigned_drop_target_idx = -1;\n    }\n    \n    // Greedily assign pickups to fingertips that are not holding anything.\n    std::vector<bool> source_assigned_for_pickup(takoyaki_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (!ft.is_holding) { // If fingertip is empty\n            int best_takoyaki_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2; // Initialize with a large distance\n\n            // Find the closest available takoyaki\n            for (size_t j = 0; j < takoyaki_list.size(); ++j) {\n                if (!takoyaki_list[j].is_taken && !source_assigned_for_pickup[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], takoyaki_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_takoyaki_idx = j;\n                    }\n                }\n            }\n            // Assign the best takoyaki if found\n            if (best_takoyaki_idx != -1) {\n                ft.assigned_pickup_source_idx = best_takoyaki_idx;\n                source_assigned_for_pickup[best_takoyaki_idx] = true;\n            }\n        }\n    }\n\n    // Greedily assign drops to fingertips that are holding a takoyaki.\n    std::vector<bool> target_assigned_for_drop(target_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (ft.is_holding) { // If fingertip is holding\n            int best_target_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2;\n\n            // Find the closest available target\n            for (size_t j = 0; j < target_list.size(); ++j) {\n                if (!target_list[j].is_filled && !target_assigned_for_drop[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], target_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_target_idx = j;\n                    }\n                }\n            }\n            // Assign the best target if found\n            if (best_target_idx != -1) {\n                ft.assigned_drop_target_idx = best_target_idx;\n                target_assigned_for_drop[best_target_idx] = true;\n            }\n        }\n    }\n    \n    // 3. Determine Root Move (S[0])\n    int total_delta_r = 0;\n    int total_delta_c = 0;\n    int num_tasks_with_goal = 0;\n\n    // Calculate the aggregated movement required by all fingertips towards their goals\n    for (auto& ft : fingertips) {\n        Point current_pos = vertex_pos[ft.vertex_id];\n        Point goal_pos = {-1, -1}; // Sentinel value indicating no assigned goal\n\n        if (ft.is_holding) { // If holding, the goal is to reach its assigned drop target\n            if (ft.assigned_drop_target_idx != -1) {\n                goal_pos = target_list[ft.assigned_drop_target_idx].pos;\n            }\n        } else { // If not holding, the goal is to reach its assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1) {\n                goal_pos = takoyaki_list[ft.assigned_pickup_source_idx].pos;\n            }\n        }\n\n        // If a goal is assigned, contribute its delta to the total\n        if (goal_pos.r != -1) {\n            total_delta_r += (goal_pos.r - current_pos.r);\n            total_delta_c += (goal_pos.c - current_pos.c);\n            num_tasks_with_goal++;\n        }\n    }\n\n    // Determine the dominant direction for root movement\n    char root_move = '.'; // Default to no movement\n    if (num_tasks_with_goal > 0) {\n        int abs_delta_r = std::abs(total_delta_r);\n        int abs_delta_c = std::abs(total_delta_c);\n\n        // Prioritize movement in the direction with larger displacement sum\n        if (abs_delta_r > abs_delta_c) {\n            if (total_delta_r > 0) root_move = 'D'; // Move Down if total delta_r is positive\n            else if (total_delta_r < 0) root_move = 'U'; // Move Up if total delta_r is negative\n        } else if (abs_delta_c > abs_delta_r) {\n            if (total_delta_c > 0) root_move = 'R'; // Move Right if total delta_c is positive\n            else if (total_delta_c < 0) root_move = 'L'; // Move Left if total delta_c is negative\n        } else { // If tied, pick one direction, e.g., prefer vertical then horizontal\n            if (total_delta_r > 0) root_move = 'D';\n            else if (total_delta_r < 0) root_move = 'U';\n            else if (total_delta_c > 0) root_move = 'R';\n            else if (total_delta_c < 0) root_move = 'L';\n        }\n    }\n    S[0] = root_move; // Set the root movement character\n\n    // 4. Rotations (S[1] to S[V_prime-1])\n    // Currently, this strategy does NOT implement rotations for simplicity and speed.\n    // All rotation characters remain '.'\n    // If performance is insufficient, rotations for joints (vertices 1 to V_prime-2) could be added.\n\n    // 5. Fingertip Actions (S[V_prime] to S[2*V_prime-1])\n    // The action for vertex `vid` is at index `V_prime + vid` in string S.\n    for (const auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = '.'; // Default to no action\n        Point current_pos = vertex_pos[vid];\n        \n        if (ft.is_holding) { // If currently holding a takoyaki\n            // Check if at the assigned drop target\n            if (ft.assigned_drop_target_idx != -1 && current_pos == target_list[ft.assigned_drop_target_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        } else { // If not holding any takoyaki\n            // Check if at the assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1 && current_pos == takoyaki_list[ft.assigned_pickup_source_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        }\n        S[V_prime + vid] = action; // Set the action character for this vertex\n    }\n\n    return S;\n}\n\n// --- State Update Function ---\n// Applies the operations from the generated string and updates the game state.\nvoid apply_operation(const std::string& op_string) {\n    // Update root position based on the first character (root move)\n    char root_move = op_string[0];\n    if (root_move == 'U') root_pos.r--;\n    else if (root_move == 'D') root_pos.r++;\n    else if (root_move == 'L') root_pos.c--;\n    else if (root_move == 'R') root_pos.c++;\n\n    // Update rotations - THIS PART IS NOT IMPLEMENTED FOR NOW.\n    // The logic would go here if rotations were to be used.\n\n    // Apply fingertip actions ('P' for pickup/drop)\n    for (auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = op_string[V_prime + vid]; // Action character for this vertex\n        \n        if (action == 'P') {\n            if (ft.is_holding) { // Finger was holding, attempting to drop\n                int target_idx = ft.assigned_drop_target_idx;\n                // Check if the fingertip is at the assigned target location\n                if (target_idx != -1 && target_list[target_idx].pos == vertex_pos[vid]) {\n                    // Successfully dropped takoyaki\n                    target_list[target_idx].is_filled = true; // Mark target as filled\n                    takoyaki_list[ft.holding_takoyaki_idx].is_taken = false; // Release the takoyaki from being \"taken\"\n                    \n                    ft.is_holding = false; // Fingertip is now empty\n                    ft.holding_takoyaki_idx = -1; // No longer holding a takoyaki\n                    ft.assigned_drop_target_idx = -1; // Clear the drop assignment\n                } else {\n                    // If 'P' action occurs but not at target, it's an invalid/ineffective action.\n                    // This indicates a potential issue in assignment or movement logic.\n                }\n            } else { // Finger was not holding, attempting to pick up\n                int source_idx = ft.assigned_pickup_source_idx;\n                // Check if the fingertip is at the assigned source location\n                if (source_idx != -1 && takoyaki_list[source_idx].pos == vertex_pos[vid]) {\n                    // Successfully picked up takoyaki\n                    takoyaki_list[source_idx].is_taken = true; // Mark takoyaki as taken\n                    ft.is_holding = true; // Fingertip is now holding\n                    ft.holding_takoyaki_idx = source_idx; // Record which takoyaki is held\n                    ft.assigned_pickup_source_idx = -1; // Clear the pickup assignment\n                } else {\n                    // If 'P' action occurs but not at source, it's an invalid/ineffective action.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Read input parameters\n    std::cin >> N_GRID >> M_TAKOYAKI >> V_ARM;\n\n    // Read initial takoyaki positions\n    takoyaki_list.resize(M_TAKOYAKI);\n    int current_takoyaki_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store takoyaki: {position, initial_index, is_taken=false}\n                takoyaki_list[current_takoyaki_idx] = {{i, j}, current_takoyaki_idx, false};\n                current_takoyaki_idx++;\n            }\n        }\n    }\n\n    // Read target positions\n    target_list.resize(M_TAKOYAKI);\n    int current_target_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store target: {position, initial_index, is_filled=false}\n                target_list[current_target_idx] = {{i, j}, current_target_idx, false};\n                current_target_idx++;\n            }\n        }\n    }\n\n    // --- Design the Robotic Arm ---\n    V_prime = V_ARM; // Use the maximum available vertices\n    parent_map.resize(V_prime - 1);\n    edge_lengths.resize(V_prime - 1);\n    edge_orientations.resize(V_prime - 1);\n    vertex_pos.resize(V_prime); // Pre-allocate space for vertex positions\n    fingertips.clear();\n    joint_vertex_ids.clear();\n\n    // Arm Design: Path graph 0-1-2-...-V-1\n    // Parent of vertex i+1 is vertex i.\n    // Edge lengths are uniformly 1.\n    // Initial edge orientations are all 0 (Right).\n    for (int i = 0; i < V_prime - 1; ++i) {\n        parent_map[i] = i;          // Parent of vertex i+1 is vertex i\n        edge_lengths[i] = 1;        // Edge length is 1\n        edge_orientations[i] = 0;   // Initial orientation is Right (0)\n    }\n\n    // Initial root position: Center of the grid.\n    root_pos = {N_GRID / 2, N_GRID / 2};\n\n    // Identify fingertips and joints based on the path graph structure.\n    if (V_prime == 1) {\n        // If only one vertex, it's the root and also a fingertip. No joints.\n        fingertip_vertex_ids.push_back(0);\n    } else {\n        // For V' > 1, vertices 0 and V'-1 are leaves (fingertips).\n        fingertip_vertex_ids.push_back(0);\n        fingertip_vertex_ids.push_back(V_prime - 1);\n        // Vertices 1 to V'-2 are internal nodes (joints) where rotations can occur.\n        for (int i = 1; i < V_prime - 1; ++i) {\n            joint_vertex_ids.push_back(i);\n        }\n    }\n\n    // Initialize fingertip state trackers.\n    fingertips.resize(fingertip_vertex_ids.size());\n    for (size_t i = 0; i < fingertip_vertex_ids.size(); ++i) {\n        fingertips[i].vertex_id = fingertip_vertex_ids[i];\n        fingertips[i].is_holding = false;\n        fingertips[i].holding_takoyaki_idx = -1; // Tracks index in takoyaki_list IF holding\n        fingertips[i].assigned_pickup_source_idx = -1; // Tracks index in takoyaki_list for planned pickup\n        fingertips[i].assigned_drop_target_idx = -1; // Tracks index in target_list for planned drop\n    }\n\n    // Output the designed robotic arm structure.\n    std::cout << V_prime << std::endl;\n    for (int i = 0; i < V_prime - 1; ++i) {\n        std::cout << parent_map[i] << \" \" << edge_lengths[i] << std::endl;\n    }\n    std::cout << root_pos.r << \" \" << root_pos.c << std::endl;\n\n    // --- Operation Phase ---\n    int delivered_count = 0;\n    int max_turns = 100000; // Set a limit to prevent TLE.\n\n    // Main loop for executing turns.\n    for (int turn = 0; turn < max_turns; ++turn) {\n        // If all takoyaki are delivered, stop early.\n        if (delivered_count == M_TAKOYAKI) {\n            break;\n        }\n\n        // Generate the operation string for the current turn.\n        std::string op_string = generate_operation_string(turn);\n        \n        // Output the operation string.\n        std::cout << op_string << std::endl;\n        \n        // Apply the generated operations to update the game state.\n        apply_operation(op_string);\n\n        // Recalculate the number of delivered takoyaki after applying operations.\n        delivered_count = 0;\n        for(const auto& target : target_list) {\n            if (target.is_filled) {\n                delivered_count++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <map>\n\nstruct Point {\n    int x, y;\n    int type; // 0 for mackerel, 1 for sardine\n};\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n;\n    std::cin >> n;\n\n    std::vector<Point> points(2 * n);\n    std::vector<int> x_coords_all, y_coords_all;\n    x_coords_all.reserve(2 * n);\n    y_coords_all.reserve(2 * n);\n\n    for (int i = 0; i < 2 * n; ++i) {\n        points[i].type = (i < n) ? 0 : 1;\n        std::cin >> points[i].x >> points[i].y;\n        x_coords_all.push_back(points[i].x);\n        y_coords_all.push_back(points[i].y);\n    }\n\n    std::sort(x_coords_all.begin(), x_coords_all.end());\n    x_coords_all.erase(std::unique(x_coords_all.begin(), x_coords_all.end()), x_coords_all.end());\n    std::sort(y_coords_all.begin(), y_coords_all.end());\n    y_coords_all.erase(std::unique(y_coords_all.begin(), y_coords_all.end()), y_coords_all.end());\n\n    // Strategy: Select a limited number of candidate x and y coordinates.\n    // These form a grid. Find the best rectangular subgrid within this grid.\n    // The number of vertices in a rectangle is 4.\n    // Total length constraint is 4 * 10^5.\n    // A rectangle [x1, x2] x [y1, y2] has perimeter 2*((x2-x1) + (y2-y1)).\n    // We select K_cand x-coordinates and K_cand y-coordinates.\n    // This implies (K_cand-1) x (K_cand-1) grid cells.\n    // We iterate through O(K_cand^4) possible rectangles.\n    // Point counting for each rectangle can be O(N), leading to O(K_cand^4 * N).\n    // With coordinate compression and 2D prefix sums, point counting is O(1).\n    // Total time becomes O(N log K_cand + K_cand^4).\n    // With N=5000 and K_cand=100, this is approx 5000*log(100) + 100^4 = 35000 + 10^8. This should be acceptable.\n\n    int K_cand = 100; // Number of candidate coordinates to pick along each axis.\n\n    std::vector<int> sx, sy;\n    sx.reserve(K_cand);\n    sy.reserve(K_cand);\n\n    // Add boundary coordinates 0 and 100000\n    sx.push_back(0);\n    sx.push_back(100000);\n    sy.push_back(0);\n    sy.push_back(100000);\n\n    // Select K_cand-2 points from all unique x-coordinates, evenly spaced\n    if (x_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            // Select index: (i * (total_unique - 1)) / (num_points_to_select - 1)\n            sx.push_back(x_coords_all[(i * (x_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    }\n    // Select K_cand-2 points from all unique y-coordinates, evenly spaced\n    if (y_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            sy.push_back(y_coords_all[(i * (y_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    }\n\n    std::sort(sx.begin(), sx.end());\n    sx.erase(std::unique(sx.begin(), sx.end()), sx.end());\n    std::sort(sy.begin(), sy.end());\n    sy.erase(std::unique(sy.begin(), sy.end()), sy.end());\n\n    int num_sx = sx.size();\n    int num_sy = sy.size();\n\n    // Helper to get index in sx/sy vectors.\n    // `lower_bound` gives `idx` such that `sx[idx] <= x`.\n    // This `idx` is the starting index of the interval `[sx[idx], sx[idx+1])` that `x` falls into.\n    auto get_sx_idx = [&](int x) {\n        return std::lower_bound(sx.begin(), sx.end(), x) - sx.begin();\n    };\n    auto get_sy_idx = [&](int y) {\n        return std::lower_bound(sy.begin(), sy.end(), y) - sy.begin();\n    };\n\n    // `grid_diff` is a 2D difference array.\n    // `grid_diff[i][j]` stores the value that starts contributing to cells `[sx[i], sx[i+1]) x [sy[j], sy[j+1])`.\n    // `grid_diff` will be of size (num_sx) x (num_sy) to handle contributions correctly.\n    std::vector<std::vector<int>> grid_diff(num_sx, std::vector<int>(num_sy, 0));\n\n    for (const auto& p : points) {\n        int ix = get_sx_idx(p.x);\n        int iy = get_sy_idx(p.y);\n        int val = (p.type == 0 ? 1 : -1);\n\n        // Point (x,y) contributes `val` to all grid cells [sx[i], sx[i+1]) x [sy[j], sy[j+1])\n        // where sx[i] <= x < sx[i+1] and sy[j] <= y < sy[j+1].\n        // The `ix` obtained from `lower_bound` for `p.x` means `sx[ix] <= p.x`.\n        // If `p.x < sx.back()`, then `sx[ix] <= p.x < sx[ix+1]`. So `ix` is correct cell start index.\n        // If `p.x == sx.back()`, `ix` becomes `num_sx-1`. This point is on the boundary and doesn't start a new cell interval.\n        // For difference array: Add `val` at `(ix, iy)`. Subtract at `(ix+1, iy)`, `(ix, iy+1)`, add at `(ix+1, iy+1)`.\n        // These indices must be within bounds of `grid_diff`.\n        \n        if (ix < num_sx && iy < num_sy) {\n            grid_diff[ix][iy] += val;\n            if (ix + 1 < num_sx) grid_diff[ix + 1][iy] -= val;\n            if (iy + 1 < num_sy) grid_diff[ix][iy + 1] -= val;\n            if (ix + 1 < num_sx && iy + 1 < num_sy) grid_diff[ix + 1][iy + 1] += val;\n        }\n    }\n    \n    // `grid_ps[i][j]` will store the sum of values in the rectangle [sx[0], sx[i+1]) x [sy[0], sy[j+1]).\n    std::vector<std::vector<int>> grid_ps(num_sx, std::vector<int>(num_sy, 0));\n    for (int i = 0; i < num_sx; ++i) {\n        for (int j = 0; j < num_sy; ++j) {\n            grid_ps[i][j] = grid_diff[i][j];\n            if (i > 0) grid_ps[i][j] += grid_ps[i-1][j];\n            if (j > 0) grid_ps[i][j] += grid_ps[i][j-1];\n            if (i > 0 && j > 0) grid_ps[i][j] -= grid_ps[i-1][j-1];\n        }\n    }\n\n    long long max_score_diff = -2e18; // Initialize with a very small value\n    int best_x1_idx = -1, best_x2_idx = -1, best_y1_idx = -1, best_y2_idx = -1;\n\n    // Iterate through all possible rectangles defined by candidate coordinates\n    // A rectangle is defined by [sx[i1], sx[i2]] x [sy[j1], sy[j2]]\n    for (int i1 = 0; i1 < num_sx; ++i1) {\n        for (int i2 = i1; i2 < num_sx; ++i2) { // i2 is the END index in sx for the rectangle boundary\n            for (int j1 = 0; j1 < num_sy; ++j1) {\n                for (int j2 = j1; j2 < num_sy; ++j2) { // j2 is the END index in sy for the rectangle boundary\n                    \n                    // The rectangle spans from sx[i1] to sx[i2] and sy[j1] to sy[j2].\n                    // Points (x,y) are included if sx[i1] <= x <= sx[i2] and sy[j1] <= y <= sy[j2].\n                    // The `grid_ps[i][j]` stores sum for [sx[0], sx[i+1]) x [sy[0], sy[j+1]).\n                    // To get sum for [sx[i1], sx[i2]] x [sy[j1], sy[j2]]:\n                    // We need to sum cells [sx[i], sx[i+1]) where i1 <= i < i2.\n                    // And cells [sy[j], sy[j+1]) where j1 <= j < j2.\n                    // The range of indices for prefix sum query on `grid_ps` is:\n                    // row indices: `i1` to `i2-1`\n                    // col indices: `j1` to `j2-1`\n                    \n                    int r1 = i1, c1 = j1;\n                    int r2 = i2 - 1, c2 = j2 - 1; // Inclusive range for grid cells\n\n                    if (r1 > r2 || c1 > c2) { // Rectangle has zero width/height in terms of cells\n                        // This can happen if i1=i2 or j1=j2. The rectangle is a line or point.\n                        // For scoring, we need actual points inside.\n                        // If i1=i2, rectangle is a vertical line sx[i1]. Need to count points on this line segment.\n                        // If j1=j2, horizontal line sy[j1]. Count points on segment.\n                        // If i1=i2 and j1=j2, point sx[i1], sy[j1]. Count points at this exact location.\n                        // Our cell-based sum will be 0 if r1>r2 or c1>c2.\n                        // For simplicity, we handle only rectangles with positive area in grid cells.\n                        // Points on the boundary are handled by the coordinate selection and inclusive checks later.\n                        // A rectangle [sx[i1], sx[i2]] x [sy[j1], sy[j2]] always contains points on its boundary.\n                        // Minimal rectangle with positive area would have i2=i1+1, j2=j1+1.\n                        // The score calculation needs to be robust.\n                        // If the rectangle is just a line, it might have points on it.\n                        // For this problem, the simplest rectangles are what we check.\n                        // If score_diff is 0 for a line/point, it's still a valid candidate.\n                        // We can potentially refine score calculation for lines/points if needed.\n                        // For now, only rectangles with >0 cell area will contribute to grid_ps sum.\n                        // A rectangle needs to have actual area to contain many points.\n                        // If i1=i2, it means sx[i1] is the only x-coordinate. The width is 0. Perimeter check might fail.\n                        // We are looking for areas, so cells are essential. r1<=r2 and c1<=c2 must hold for cell contribution.\n                        // If i1 = i2, the interval is empty so r1 > r2.\n                        // If i1 == i2, then the rectangle is a vertical line. We need to count points on this line.\n                        // This simplified PS approach might miss points on boundaries not starting new cells.\n                        // To be fully correct, we'd need to sum up points on segment [sx[i1], sx[i2]] and [sy[j1], sy[j2]].\n                        // For now, assume regions of positive area (many cells) are more important.\n                        // The problem says points on edges are inside.\n                        // A simple rectangle [x1, x2] x [y1, y2] covers all points (x,y) where x1<=x<=x2 and y1<=y<=y2.\n                        // Let's calculate score based on ALL points.\n                        // Iterate all points, check if in rectangle [sx[i1], sx[i2]] x [sy[j1], sy[j2]]. O(N). Total O(K^4 * N).\n                        // This is too slow. The PS approach is necessary.\n\n                        // Correctness of PS for rectangle sum [x1, x2] x [y1, y2]\n                        // `grid_ps[i][j]` = sum in `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n                        // To get sum in `[sx[i1], sx[i2]] x [sy[j1], sy[j2]]`:\n                        // This rectangle covers cells from `sx[i1]` up to `sx[i2-1]` for x-intervals, and `sy[j1]` up to `sy[j2-1]` for y-intervals.\n                        // The corresponding indices for `grid_ps` are `i1` to `i2-1` and `j1` to `j2-1`.\n                        // Let `R1=i1, R2=i2-1, C1=j1, C2=j2-1`.\n                        // If `R1 > R2` or `C1 > C2`, the rectangle doesn't cover any full cells.\n                        // The score might come from points on the boundary lines only.\n                        // For a rectangle [sx[i1], sx[i2]] x [sy[j1], sy[j2]], actual points inside:\n                        // We need to sum over ALL points `p` where `sx[i1] <= p.x <= sx[i2]` and `sy[j1] <= p.y <= sy[j2]`.\n                        // This calculation is O(N). For K^4 rectangles, it is O(K^4 * N).\n                        // To keep it O(K^4 + N log K): PS sum must be correct.\n                        // `grid_ps[i][j]` covers `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n                        // The query for `[sx[i1], sx[i2]] x [sy[j1], sy[j2]]` needs to sum points `p` where `sx[i1] <= p.x <= sx[i2]` etc.\n                        // `lower_bound(sx.begin(), sx.end(), p.x) - sx.begin()` gives index `ix` s.t. `sx[ix] <= p.x`.\n                        // If `p.x = sx[k]`, `ix = k`. If `sx[k] <= p.x < sx[k+1]`, `ix=k`.\n                        // Sum for `[sx[i1], sx[i2]] x [sy[j1], sy[j2]]`:\n                        // Use indices `i1` to `i2` for starting points. `j1` to `j2` for starting points.\n                        // The cells are intervals [sx[i], sx[i+1]).\n                        // For rectangle [sx[i1], sx[i2]] x [sy[j1], sy[j2]], the cell indices are:\n                        // x: from `i1` up to `i2-1` (if `i2` is exclusive end). But `i2` is inclusive coordinate.\n                        // Let the rectangle coordinates be X1=sx[i1], X2=sx[i2], Y1=sy[j1], Y2=sy[j2].\n                        // We need sum of points p where X1 <= p.x <= X2 and Y1 <= p.y <= Y2.\n                        // The PS sum `grid_ps[i][j]` is sum of points `p` s.t. `sx[0] <= p.x < sx[i+1]` and `sy[0] <= p.y < sy[j+1]`.\n                        // Sum in `[X1, X2] x [Y1, Y2]` is `Query(X1, X2, Y1, Y2)`.\n                        // `Query(x_min, x_max, y_min, y_max)` = `PS_sum(x_max, y_max) - PS_sum(x_min-eps, y_max) - PS_sum(x_max, y_min-eps) + PS_sum(x_min-eps, y_min-eps)`.\n                        // This requires mapping coordinates to PS grid indices.\n                        // `x_max` corresponds to `sx[i2]`. `x_min` to `sx[i1]`.\n                        // `grid_ps[i][j]` covers `sx[0]` up to `sx[i+1]`. So `sx[i+1]` is exclusive upper bound.\n                        // To query sum up to `sx[k]`, we need to query up to index `k-1`.\n                        // The rectangle is [sx[i1], sx[i2]] x [sy[j1], sy[j2]].\n                        // Query `grid_ps[i2-1][j2-1]` (sum up to `sx[i2]`, `sy[j2]`).\n                        // Subtract `grid_ps[i1-1][j2-1]` (sum up to `sx[i1]`, `sy[j2]`).\n                        // Subtract `grid_ps[i2-1][j1-1]` (sum up to `sx[i2]`, `sy[j1]`).\n                        // Add `grid_ps[i1-1][j1-1]` (sum up to `sx[i1]`, `sy[j1]`).\n                        // Indices for PS query are `R1=i1-1, R2=i2-1, C1=j1-1, C2=j2-1`.\n                        // Need helper function to query `grid_ps` safely with indices potentially -1.\n                        \n                        auto get_ps_val = [&](int r_idx, int c_idx) {\n                            if (r_idx < 0 || c_idx < 0) return 0;\n                            return grid_ps[r_idx][c_idx];\n                        };\n                        \n                        int r_max_idx = i2 - 1; // Max interval index for x-span [sx[i1], sx[i2]]\n                        int c_max_idx = j2 - 1; // Max interval index for y-span [sy[j1], sy[j2]]\n                        \n                        if (r_max_idx < r1 || c_max_idx < c1) { // The rectangle has no cell area, might only contain points on boundaries.\n                            // This case needs careful handling. The current PS calculation might miss boundary points.\n                            // If i1=i2, r_max_idx = i1-1, so r1 > r_max_idx. The sum will be 0 from PS.\n                            // For now, we proceed. The score diff will be 0.\n                        } else {\n                            current_score_diff = get_ps_val(r_max_idx, c_max_idx) \n                                               - get_ps_val(r1 - 1, c_max_idx) \n                                               - get_ps_val(r_max_idx, c1 - 1) \n                                               + get_ps_val(r1 - 1, c1 - 1);\n                        }\n                    } else { // Rectangle has cell area, r1 <= r2 and c1 <= c2\n                        current_score_diff = grid_ps[r2][c2] \n                                           - get_ps_val(r1 - 1, c2) \n                                           - get_ps_val(r2, c1 - 1) \n                                           + get_ps_val(r1 - 1, c1 - 1);\n                    }\n                    \n                    // Calculate perimeter and check constraints\n                    long long current_perimeter = 2LL * ((long long)(sx[i2] - sx[i1]) + (long long)(sy[j2] - sy[j1]));\n\n                    if (current_perimeter <= 400000LL) {\n                        if (current_score_diff > max_score_diff) {\n                            max_score_diff = current_score_diff;\n                            best_x1_idx = i1;\n                            best_x2_idx = i2;\n                            best_y1_idx = j1;\n                            best_y2_idx = j2;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the best rectangle found.\n    // If no valid rectangle was found (e.g., all too long, or no points inside),\n    // we should output a default valid polygon. The problem guarantees points exist.\n    // A minimal rectangle like [0,0]x[0,0] is valid and has perimeter 0.\n    // If best_x1_idx is still -1, it means no rectangle satisfied perimeter constraint AND had points,\n    // or all points resulted in score_diff <= 0.\n    // A default rectangle [0,1]x[0,1] or similar will have score_diff=0 or small, but valid perimeter.\n    // If max_score_diff is still negative, score is 0. So we want max(0, score_diff+1).\n    // If best_x1_idx is -1, it means no valid perimeter rectangle was found OR all had score_diff <= -2e18.\n    // Let's ensure we always find a valid rectangle. Smallest possible: [0,0] x [0,0].\n    // Its perimeter is 0. If no points, score_diff is 0. Score is max(0, 0+1)=1.\n    // This suggests if best_x1_idx = -1, we should pick a default minimal rectangle.\n    // The coordinates sx, sy are guaranteed to have at least 0 and 100000.\n    // So indices exist. Let's pick the first one if no better is found.\n    if (best_x1_idx == -1) {\n        best_x1_idx = 0;\n        best_x2_idx = 0;\n        best_y1_idx = 0;\n        best_y2_idx = 0;\n        // This selects a single point [sx[0], sx[0]] x [sy[0], sy[0]] = [0,0] x [0,0].\n        // If there are points at (0,0), score_diff will be calculated.\n        // If no points at (0,0), score_diff will be 0.\n        // Perimeter is 0. Score = max(0, 0+1) = 1. This is a safe default.\n    }\n    \n    std::cout << 4 << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y2_idx] << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y2_idx] << std::endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <utility> // for std::pair\n\n// Structure to hold noisy dimensions for a rectangle\nstruct Rect {\n    long long w_prime, h_prime;\n};\n\n// Structure to hold information about a rectangle after placement\nstruct PlacedRect {\n    int id; // original index of the rectangle\n    long long x, y, w, h; // position (top-left) and dimensions\n};\n\n// Structure to represent an entry in the output placement sequence for a turn\nstruct OutputEntry {\n    int p; // rectangle index\n    int r; // rotation (0: original, 1: 90 deg rotated)\n    char d; // direction ('U' for Up, 'L' for Left)\n    int b; // reference rectangle index (-1 for origin, or index in current_placed_rects)\n};\n\nint main() {\n    // Improve I/O performance\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N; // Number of rectangles\n    int T; // Number of turns\n    long long sigma; // Standard deviation of measurement error\n    std::cin >> N >> T >> sigma;\n\n    // Read noisy dimensions for each rectangle\n    std::vector<Rect> rects(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> rects[i].w_prime >> rects[i].h_prime;\n    }\n\n    // Pre-calculate the sum of (w'_i + h'_i) for all suffixes of rectangles.\n    // penalty_sum[k] will store sum_{i=k to N-1} (rects[i].w_prime + rects[i].h_prime).\n    // This is used to quickly calculate the penalty for unused rectangles.\n    std::vector<long long> penalty_sum(N + 1, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        penalty_sum[i] = penalty_sum[i + 1] + rects[i].w_prime + rects[i].h_prime;\n    }\n\n    // Main loop for each turn\n    for (int t = 0; t < T; ++t) {\n        // Variables to store the best placement strategy found for the current turn\n        std::vector<OutputEntry> best_output_sequence;\n        int best_n = 0; // Number of rectangles to place in this turn\n        long long best_turn_score = -1; // Score for the best strategy in this turn\n\n        // Iterate through all possible numbers of rectangles to place, from N down to 0.\n        // We try to place `num_to_place` rectangles, specifically indices 0, 1, ..., num_to_place - 1.\n        // This is because rectangles must be placed in ascending order of their original indices.\n        for (int num_to_place = N; num_to_place >= 0; --num_to_place) {\n            // Case: placing 0 rectangles.\n            if (num_to_place == 0) {\n                // The score is 0 (W+H) + penalty for all N unused rectangles.\n                long long current_score = 0 + 0 + penalty_sum[0];\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = 0;\n                    best_output_sequence.clear(); // Empty sequence\n                }\n                continue; // Move to the next iteration of `num_to_place`\n            }\n\n            // State for placing `num_to_place` rectangles:\n            std::vector<PlacedRect> current_placed_rects; // Stores info about rectangles placed so far in this attempt.\n            std::vector<OutputEntry> current_output_sequence; // Stores the placement instructions for this attempt.\n            bool possible_to_place_all = true; // Flag to check if all `num_to_place` can be placed validly.\n\n            long long current_max_W = 0; // Current bounding box width after placing rectangles so far.\n            long long current_max_H = 0; // Current bounding box height after placing rectangles so far.\n\n            // Attempt to place rectangles 0, 1, ..., num_to_place - 1 in order.\n            for (int i = 0; i < num_to_place; ++i) {\n                int current_rect_idx = i; // The original index of the rectangle being considered for placement.\n\n                // Define the two possible dimensions (original and rotated) for the current rectangle.\n                std::pair<long long, long long> dims[2];\n                dims[0] = {rects[current_rect_idx].w_prime, rects[current_rect_idx].h_prime}; // r = 0 (no rotation)\n                dims[1] = {rects[current_rect_idx].h_prime, rects[current_rect_idx].w_prime}; // r = 1 (rotated 90 degrees)\n\n                // Variables to track the best placement found for the current rectangle `i`.\n                long long best_x = -1, best_y = -1; // Best position (top-left corner)\n                int best_r = -1; // Best rotation option (0 or 1)\n                char best_d_char = ' '; // Best direction ('U' or 'L')\n                int best_b_idx_in_placed = -1; // Index of the reference rectangle in `current_placed_rects` (-1 if origin).\n                long long min_placement_cost = -1; // The cost (W+H) of the best found placement for this rectangle.\n\n                // Iterate through all possible reference rectangles.\n                // `b_place_idx` is the index in `current_placed_rects`. -1 refers to the origin (0,0).\n                for (int b_place_idx = -1; b_place_idx < current_placed_rects.size(); ++b_place_idx) {\n                    // Get reference rectangle's properties if b_place_idx is valid.\n                    long long ref_x = 0, ref_y = 0, ref_w = 0, ref_h = 0;\n                    if (b_place_idx != -1) {\n                        ref_x = current_placed_rects[b_place_idx].x;\n                        ref_y = current_placed_rects[b_place_idx].y;\n                        ref_w = current_placed_rects[b_place_idx].w;\n                        ref_h = current_placed_rects[b_place_idx].h;\n                    }\n\n                    // Iterate through rotation options (0 or 1).\n                    for (int r_opt = 0; r_opt < 2; ++r_opt) {\n                        long long W = dims[r_opt].first; // Width of the rectangle in this orientation.\n                        long long H = dims[r_opt].second; // Height of the rectangle in this orientation.\n\n                        // Iterate through placement directions ('U' or 'L').\n                        for (char d_char : {'U', 'L'}) {\n                            long long cur_x, cur_y; // Proposed position for the top-left corner.\n\n                            if (d_char == 'U') {\n                                // Place upwards: align left edge with ref's right edge, top edge with ref's bottom edge.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x + ref_w);\n                                cur_y = (b_place_idx == -1) ? 0 : (ref_y + ref_h);\n                            } else { // d_char == 'L'\n                                // Place leftwards: align right edge with ref's left edge, top edge with ref's top edge.\n                                // The resulting x-coordinate must be non-negative.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x - W);\n                                cur_y = (b_place_idx == -1) ? 0 : ref_y;\n                                \n                                // Constraint: rectangles must be placed in x >= 0 and y >= 0.\n                                // For 'L' placement, if `ref_x - W` results in a negative x-coordinate,\n                                // this specific alignment with `ref_x` is not possible without going left of the origin.\n                                // The rule implies stopping at x=0. If `ref_x < W`, the rectangle cannot be placed \n                                // such that its right edge is at `ref_x` AND its left edge is >= 0.\n                                // Thus, `ref_x` must be at least `W` for this alignment to be possible.\n                                if (cur_x < 0) { \n                                    continue; // This placement combination is invalid.\n                                }\n                            }\n\n                            // Calculate the resulting bounding box dimensions if this rectangle is placed at (cur_x, cur_y).\n                            // `current_max_W` and `current_max_H` store the bounding box of already placed rectangles.\n                            long long candidate_W = std::max(current_max_W, cur_x + W);\n                            long long candidate_H = std::max(current_max_H, cur_y + H);\n                            \n                            // The cost for this placement is the sum of the bounding box dimensions.\n                            long long current_placement_cost = candidate_W + candidate_H;\n\n                            // If this is the first valid placement found, or if it yields a better (smaller) cost, update best found.\n                            if (min_placement_cost == -1 || current_placement_cost < min_placement_cost) {\n                                min_placement_cost = current_placement_cost;\n                                best_x = cur_x;\n                                best_y = cur_y;\n                                best_r = r_opt;\n                                best_d_char = d_char;\n                                best_b_idx_in_placed = b_place_idx;\n                            }\n                        } // End of loop for `d_char`\n                    } // End of loop for `r_opt`\n                } // End of loop for `b_place_idx`\n\n                // If no valid placement was found for the current rectangle `i` with the current `num_to_place` setting.\n                if (best_x == -1) {\n                    possible_to_place_all = false; // This `num_to_place` strategy is not feasible.\n                    break; // Stop trying to place more rectangles for this `num_to_place` value.\n                }\n\n                // Record the best placement found for rectangle `i`.\n                current_placed_rects.push_back({current_rect_idx, best_x, best_y, dims[best_r].first, dims[best_r].second});\n                current_output_sequence.push_back({current_rect_idx, best_r, best_d_char, best_b_idx_in_placed});\n                \n                // Update the overall bounding box dimensions with the newly placed rectangle.\n                current_max_W = std::max(current_max_W, best_x + dims[best_r].first);\n                current_max_H = std::max(current_max_H, best_y + dims[best_r].second);\n\n            } // End of loop for `i` (placing rectangles 0 to num_to_place - 1)\n\n            // If we successfully placed all `num_to_place` rectangles:\n            if (possible_to_place_all) {\n                // Calculate the total score for this specific `num_to_place` strategy.\n                // Score = (final W + final H of placed rectangles) + (penalty sum of unused rectangles).\n                long long current_score = current_max_W + current_max_H + penalty_sum[num_to_place];\n                \n                // If this score is better than the best score found so far for this turn, update bests.\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = num_to_place;\n                    best_output_sequence = current_output_sequence;\n                }\n            }\n        } // End of loop for `num_to_place` (trying different counts of rectangles to place)\n\n        // Output the chosen placement strategy for the current turn.\n        std::cout << best_n << std::endl;\n        for (const auto& p : best_output_sequence) {\n            std::cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << std::endl;\n        }\n        std::cout << std::flush; // Ensure output is sent immediately.\n\n        // Read the measured bounding box dimensions for this turn.\n        // These are not used by the current strategy, but are required by the problem protocol.\n        long long measured_W_prime, measured_H_prime;\n        std::cin >> measured_W_prime >> measured_H_prime;\n    } // End of loop for turns `t`\n\n    return 0; // Program finished successfully.\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\n// Structure to store information about a representative of a DSU set.\n// Each representative corresponds to the root of a tree in our problem.\nstruct DSU_Rep_Info {\n    int root_vertex;    // The actual vertex ID that is the root of this tree.\n    int max_height;     // The maximum height among all vertices in this tree.\n    long long sum_beauty; // The sum of beauty values of all vertices in this tree.\n};\n\nvector<int> dsu_parent; // Standard DSU parent array. dsu_parent[i] stores the parent of vertex i in the DSU structure.\nvector<DSU_Rep_Info> rep_info; // Stores information about each representative. Indexed by the representative's vertex ID.\n\n// Finds the representative of the set containing vertex v.\n// Implements path compression for efficiency.\nint find_set(int v) {\n    if (v == dsu_parent[v])\n        return v;\n    return dsu_parent[v] = find_set(dsu_parent[v]);\n}\n\n// Merges the set represented by root_c_repr into the set represented by root_p_repr.\n// This function is called when we decide to make the tree rooted at root_c_vertex a child\n// of the tree rooted at root_p_vertex.\n// root_p_repr: DSU representative of the parent tree.\n// root_c_repr: DSU representative of the child tree.\n// root_p_vertex: Actual vertex ID that is the root of the parent tree.\n// root_c_vertex: Actual vertex ID that is the root of the child tree.\n// H: Maximum allowed height for any vertex in any tree.\n// adj: Adjacency list of the graph.\n// p: The final parent array to be constructed. p[v] will store the parent of vertex v, or -1 if v is a root.\n// rep_info: Reference to the vector storing DSU representative information.\n// dsu_parent: Reference to the DSU parent array.\nvoid union_sets(int root_p_repr, int root_c_repr, int root_p_vertex, int root_c_vertex, int H, const vector<vector<int>>& adj, vector<int>& p, vector<DSU_Rep_Info>& rep_info, vector<int>& dsu_parent) {\n    \n    // If they are already in the same set (i.e., same representative), do nothing.\n    if (root_p_repr == root_c_repr) return;\n\n    // Verify that an edge exists between the actual roots of the two trees.\n    // This check is somewhat redundant if PQ population is correct, but serves as a safeguard.\n    bool edge_exists = false;\n    for (int neighbor : adj[root_p_vertex]) {\n        if (neighbor == root_c_vertex) {\n            edge_exists = true;\n            break;\n        }\n    }\n    if (!edge_exists) return;\n\n    // Check the height constraint: if the child tree's max height plus one (for the new edge)\n    // exceeds the limit H, this merge is invalid.\n    if (rep_info[root_c_repr].max_height + 1 > H) return;\n\n    // Perform the union: make root_c_repr's DSU tree point to root_p_repr.\n    dsu_parent[root_c_repr] = root_p_repr;\n    \n    // Update the parent pointer for the actual root of the child tree.\n    // The root of the child tree (root_c_vertex) now becomes a child of the root of the parent tree (root_p_vertex).\n    p[root_c_vertex] = root_p_vertex;\n\n    // Update the information for the new representative (root_p_repr).\n    // The sum of beauties is the sum of beauties of both trees.\n    rep_info[root_p_repr].sum_beauty += rep_info[root_c_repr].sum_beauty;\n    // The new maximum height is the maximum of the parent tree's height and the child tree's height increased by 1.\n    rep_info[root_p_repr].max_height = max(rep_info[root_p_repr].max_height, rep_info[root_c_repr].max_height + 1);\n    \n    // No need to explicitly clear info for root_c_repr; it's no longer a representative.\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, h_limit;\n    cin >> n >> m >> h_limit;\n\n    vector<long long> a(n); // Beauty values of vertices\n    for (int i = 0; i < n; ++i) {\n        cin >> a[i];\n    }\n\n    vector<vector<int>> adj(n); // Adjacency list for the graph\n    vector<pair<int, int>> edges; // List of all edges\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        edges.push_back({u, v});\n    }\n\n    // Initialize DSU structure. Initially, each vertex is in its own set.\n    dsu_parent.resize(n);\n    iota(dsu_parent.begin(), dsu_parent.end(), 0); // dsu_parent[i] = i for all i\n    \n    rep_info.resize(n);\n    for (int i = 0; i < n; ++i) {\n        // Initially, each vertex is a root of its own tree:\n        // root_vertex is itself, max_height is 0, sum_beauty is its own beauty value.\n        rep_info[i] = {i, 0, a[i]}; \n    }\n\n    // Priority queue to store potential merges.\n    // Stores tuples: {gain, root_parent_vertex, root_child_vertex}.\n    // Gain is the sum of beauties of the child tree, which is the increase in total attractiveness.\n    // We want to process merges with higher gain first.\n    priority_queue<tuple<long long, int, int>> pq;\n\n    // Populate the priority queue with initial merge candidates.\n    // For each edge (u, v), consider merging the tree rooted at v into the tree rooted at u,\n    // and vice versa, provided the height constraint is met.\n    for (const auto& edge : edges) {\n        int u = edge.first;\n        int v = edge.second;\n\n        // Get current representatives for u and v\n        int root_u_repr = find_set(u);\n        int root_v_repr = find_set(v);\n\n        // Try merging v's tree into u's tree (making v child of u)\n        // Condition: max height of v's tree + 1 <= H\n        if (rep_info[root_v_repr].max_height + 1 <= h_limit) {\n            // The gain is the sum of beauties of v's entire tree.\n            pq.push({rep_info[root_v_repr].sum_beauty, u, v});\n        }\n        // Try merging u's tree into v's tree (making u child of v)\n        // Condition: max height of u's tree + 1 <= H\n        if (rep_info[root_u_repr].max_height + 1 <= h_limit) {\n            // The gain is the sum of beauties of u's entire tree.\n            pq.push({rep_info[root_u_repr].sum_beauty, v, u});\n        }\n    }\n\n    // Initialize the final parent array. -1 indicates a root vertex.\n    vector<int> p(n, -1); \n\n    // Greedily process merges from the priority queue.\n    while (!pq.empty()) {\n        auto [gain, u_vtx, v_vtx] = pq.top(); // Get the merge with the highest gain.\n        pq.pop();\n\n        // Find current representatives for u_vtx and v_vtx.\n        int root_u_repr = find_set(u_vtx);\n        int root_v_repr = find_set(v_vtx);\n        \n        // If u_vtx and v_vtx are already in the same tree, this merge is redundant. Skip.\n        if (root_u_repr == root_v_repr) continue;\n\n        // Re-check height constraint using current representatives' info.\n        // The representative of the tree to be merged (child tree) is root_v_repr.\n        if (rep_info[root_v_repr].max_height + 1 > h_limit) continue;\n\n        // The edge (u_vtx, v_vtx) is guaranteed to exist because it was added to PQ.\n        // Perform the union: merge the tree represented by root_v_repr into the tree represented by root_u_repr.\n        // u_vtx becomes the parent root, v_vtx becomes the child root.\n        union_sets(root_u_repr, root_v_repr, u_vtx, v_vtx, h_limit, adj, p, rep_info, dsu_parent);\n    }\n\n    // Output the resulting parent array.\n    for (int i = 0; i < n; ++i) {\n        cout << p[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    cin >> n;\n\n    // Read the initial board configuration.\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> board[i];\n    }\n\n    // Precompute safety information for each cell.\n    // has_fuku_above[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k < r.\n    // has_fuku_below[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k > r.\n    // has_fuku_left[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k < c.\n    // has_fuku_right[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k > c.\n    // These precomputed values allow O(1) safety checks for each direction.\n    vector<vector<bool>> has_fuku_above(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_below(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_left(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_right(n, vector<bool>(n, false));\n\n    // Compute has_fuku_above and has_fuku_below for all columns.\n    for (int c = 0; c < n; ++c) {\n        bool found_fuku_in_col = false;\n        // Scan downwards: for each cell (r, c), check if any Fuku was found in previous rows (k < r).\n        for (int r = 0; r < n; ++r) {\n            has_fuku_above[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column above current row.\n            }\n        }\n        \n        found_fuku_in_col = false; // Reset for scanning downwards to compute has_fuku_below.\n        // Scan upwards: for each cell (r, c), check if any Fuku was found in subsequent rows (k > r).\n        for (int r = n - 1; r >= 0; --r) {\n            has_fuku_below[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column below current row.\n            }\n        }\n    }\n\n    // Compute has_fuku_left and has_fuku_right for all rows.\n    for (int r = 0; r < n; ++r) {\n        bool found_fuku_in_row = false;\n        // Scan rightwards: for each cell (r, c), check if any Fuku was found in previous columns (k < c).\n        for (int c = 0; c < n; ++c) {\n            has_fuku_left[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the left of current column.\n            }\n        }\n        \n        found_fuku_in_row = false; // Reset for scanning rightwards to compute has_fuku_right.\n        // Scan leftwards: for each cell (r, c), check if any Fuku was found in subsequent columns (k > c).\n        for (int c = n - 1; c >= 0; --c) {\n            has_fuku_right[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the right of current column.\n            }\n        }\n    }\n\n    // Stores the sequence of operations to be performed.\n    vector<pair<char, int>> operations;\n    const int INF = 1e9; // A large enough value to represent infinity for costs.\n\n    // Iterate through each cell of the board.\n    for (int r = 0; r < n; ++r) {\n        for (int c = 0; c < n; ++c) {\n            // If the cell contains an Oni ('x').\n            if (board[r][c] == 'x') {\n                // Find the safest and cheapest direction to remove this specific Oni.\n                // The goal is to minimize operations (T) for the score 8N^2 - T.\n                int min_cost = INF;\n                char best_op_char = ' ';\n                int best_op_idx = -1;\n\n                // --- Evaluate Upward push ---\n                // Cost: r + 1 operations. An Oni at (r,c) moves up to (0,c) in 'r' steps, and then is removed by the (r+1)th UP shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k < r. This is checked by !has_fuku_above[r][c].\n                if (!has_fuku_above[r][c]) {\n                    int cost = r + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'U'; // Upward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Downward push ---\n                // Cost: N - r operations. An Oni at (r,c) moves down to (N-1,c) in (N-1)-r steps, and then is removed by the (N-r)th DOWN shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k > r. This is checked by !has_fuku_below[r][c].\n                if (!has_fuku_below[r][c]) {\n                    int cost = n - r;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'D'; // Downward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Leftward push ---\n                // Cost: c + 1 operations. An Oni at (r,c) moves left to (r,0) in 'c' steps, and then is removed by the (c+1)th LEFT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k < c. This is checked by !has_fuku_left[r][c].\n                if (!has_fuku_left[r][c]) {\n                    int cost = c + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'L'; // Leftward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // --- Evaluate Rightward push ---\n                // Cost: N - c operations. An Oni at (r,c) moves right to (r,N-1) in (N-1)-c steps, and then is removed by the (N-c)th RIGHT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k > c. This is checked by !has_fuku_right[r][c].\n                if (!has_fuku_right[r][c]) {\n                    int cost = n - c;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'R'; // Rightward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // The problem guarantees that for every Oni, at least one direction is safe.\n                // Thus, min_cost will be less than INF and greater than or equal to 1.\n                // We add 'min_cost' operations of the chosen type. This ensures each Oni is removed.\n                // The total number of operations T will be the sum of these minimum costs for each Oni.\n                // This greedy strategy aims to minimize T by making the locally optimal choice for each Oni.\n                for (int k = 0; k < min_cost; ++k) {\n                    operations.push_back({best_op_char, best_op_idx});\n                }\n            }\n        }\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output each operation in the specified format.\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N; // Number of employees\nlong long L; // Total number of weeks\nvector<long long> T; // Target counts for each employee\n\n// l_counts[i] = ceil(T[i] / 2.0)\n// r_counts[i] = floor(T[i] / 2.0)\n// These represent the number of times employee i directs the process\n// to a_i (if its count becomes odd) or b_i (if its count becomes even).\nvector<long long> l_counts; \nvector<long long> r_counts; \n\n// current_O[j] stores the total count of \"odd-parity\" assignments directed to employee j.\n// This sum comes from all i such that a_i = j, contributing l_counts[i].\nvector<long long> current_O; \n// current_E[j] stores the total count of \"even-parity\" assignments directed to employee j.\n// This sum comes from all i such that b_i = j, contributing r_counts[i].\nvector<long long> current_E; \n\n// a[i] and b[i] store the chosen successors for employee i.\nvector<int> a;\nvector<int> b;\n\n// Calculates the total error based on current O and E counts.\n// Error is sum of absolute differences between target T_j and actual assignments (O_j + E_j).\nlong long calculate_total_error() {\n    long long error = 0;\n    for (int j = 0; j < N; ++j) {\n        error += abs((current_O[j] + current_E[j]) - T[j]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Precompute l_counts and r_counts for each employee\n    l_counts.resize(N);\n    r_counts.resize(N);\n    for (int i = 0; i < N; ++i) {\n        l_counts[i] = (T[i] + 1) / 2; // Equivalent to ceil(T[i] / 2.0)\n        r_counts[i] = T[i] / 2;      // Equivalent to floor(T[i] / 2.0)\n    }\n\n    current_O.resize(N, 0);\n    current_E.resize(N, 0);\n    a.resize(N);\n    b.resize(N);\n\n    // Initialize: each employee i initially directs assignments to itself.\n    // a[i] = i, b[i] = i.\n    // Update current_O and current_E based on this initial assignment.\n    for (int i = 0; i < N; ++i) {\n        a[i] = i;\n        b[i] = i;\n        current_O[i] += l_counts[i];\n        current_E[i] += r_counts[i];\n    }\n\n    // Calculate initial total error\n    long long current_total_error = calculate_total_error();\n\n    // The core of the solution is a local search heuristic.\n    // We iterate a fixed number of times. In each iteration, for each employee i,\n    // we try to find the best pair (u, v) for (a[i], b[i]) that minimizes the total error.\n    // The total number of iterations is a hyperparameter. For N=100, N^3 complexity per iteration\n    // implies a limit around 1000-2000 iterations to stay within time limits.\n    // We chose 1500 iterations as a balance between exploration and performance.\n    int num_iterations = 1500; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        bool improved_in_iter = false; // Flag to check if any improvement was made in this iteration\n\n        // Iterate through each employee i to potentially change their a[i] and b[i]\n        for (int i = 0; i < N; ++i) {\n            int old_a = a[i]; // Store old assignment for a[i]\n            int old_b = b[i]; // Store old assignment for b[i]\n            \n            // Keep track of the best assignment found so far for employee i in this iteration\n            int best_new_a = old_a;\n            int best_new_b = old_b;\n            long long min_err_for_i = current_total_error; // Minimum error achievable by changing a[i], b[i]\n\n            // Try all possible pairs (u, v) for (a[i], b[i])\n            for (int u = 0; u < N; ++u) { // New target for a[i]\n                for (int v = 0; v < N; ++v) { // New target for b[i]\n                    \n                    // Store current counts before modification for backtracking\n                    long long temp_O_old_a = current_O[old_a];\n                    long long temp_O_u = current_O[u];\n                    long long temp_E_old_b = current_E[old_b];\n                    long long temp_E_v = current_E[v];\n\n                    // --- Calculate potential new total error if a[i] becomes u and b[i] becomes v ---\n                    // We need to efficiently update current_O and current_E.\n                    // If old_a != u, the contribution of l_counts[i] shifts from old_a to u.\n                    // If old_b != v, the contribution of r_counts[i] shifts from old_b to v.\n                    \n                    // Revert contributions of old assignments\n                    if (old_a != u) {\n                        current_O[old_a] -= l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] -= r_counts[i];\n                    }\n                    \n                    // Apply new contributions\n                    if (old_a != u) {\n                        current_O[u] += l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[v] += r_counts[i];\n                    }\n\n                    // Handle cases where u == old_a or v == old_b.\n                    // If u == old_a, the l_counts[i] contribution remains at old_a, so current_O[old_a] and current_O[u] are unchanged relative to each other for THIS i's contribution.\n                    // The logic above handles this correctly: if old_a == u, we do not subtract from old_a and do not add to u, keeping them as they were.\n                    // Same applies for b[i] and v.\n                    // If u == v == old_a == old_b, no changes happen.\n\n                    // Calculate the new total error with these tentative assignments\n                    long long temp_error = calculate_total_error();\n\n                    // If this new assignment (u, v) results in a lower total error, update best found for i\n                    if (temp_error < min_err_for_i) {\n                        min_err_for_i = temp_error;\n                        best_new_a = u;\n                        best_new_b = v;\n                        improved_in_iter = true; // Mark that an improvement has been made\n                    }\n                    \n                    // --- Backtrack: restore counts to their state before trying this (u,v) pair ---\n                    // This is crucial because current_O and current_E are global and used for next (u,v) pair.\n                    if (old_a != u) {\n                        current_O[old_a] = temp_O_old_a; // Restore old_a's count\n                        current_O[u] = temp_O_u;         // Restore u's count\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] = temp_E_old_b; // Restore old_b's count\n                        current_E[v] = temp_E_v;         // Restore v's count\n                    }\n                }\n            }\n            \n            // After trying all (u,v) for employee i, apply the best found assignment\n            if (min_err_for_i < current_total_error) {\n                // Update the global counts based on the best move for employee i\n                // First, remove the contribution of the old assignment\n                if (old_a != best_new_a) {\n                    current_O[old_a] -= l_counts[i];\n                    current_O[best_new_a] += l_counts[i];\n                }\n                if (old_b != best_new_b) {\n                    current_E[old_b] -= r_counts[i];\n                    current_E[best_new_b] += r_counts[i];\n                }\n                \n                // Update a[i] and b[i] to the best choice\n                a[i] = best_new_a;\n                b[i] = best_new_b;\n                current_total_error = min_err_for_i; // Update the global minimum error\n            }\n        }\n        // If no improvement was made in this iteration for any employee, we can stop early.\n        if (!improved_in_iter) {\n            break;\n        }\n    }\n\n    // Output the resulting a[i] and b[i] values\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n#include <numeric>\n#include <set>\n\n// Structure to hold city information\nstruct City {\n    int id;\n    long long lx, rx, ly, ry;\n    double est_x, est_y; // Estimated coordinates (center of bounding box)\n};\n\n// Structure to represent an edge with estimated weight for sorting\nstruct Edge {\n    int u, v;\n    long long weight; // Use estimated distance as weight\n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) {\n            return weight < other.weight;\n        }\n        if (u != other.u) {\n            return u < other.u;\n        }\n        return v < other.v;\n    }\n};\n\n// Disjoint Set Union (DSU) data structure for Kruskal's algorithm\nstruct DSU {\n    std::vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        std::iota(parent.begin(), parent.end(), 0); // Initialize each node as its own parent\n    }\n    // Find the root of the set containing element i\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n    // Unite the sets containing elements i and j\n    void unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j; // Union by rank/size can be added for optimization, but N is not extremely large\n        }\n    }\n};\n\n// Function to query MST for a subset of cities\n// Returns a vector of pairs (u, v) representing MST edges, sorted lexicographically.\nstd::vector<std::pair<int, int>> query_mst(const std::vector<int>& cities) {\n    std::cout << \"? \" << cities.size();\n    for (int city_idx : cities) {\n        std::cout << \" \" << city_idx;\n    }\n    std::cout << std::endl;\n\n    std::vector<std::pair<int, int>> mst_edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; ++i) {\n        int u, v;\n        std::cin >> u >> v;\n        if (u > v) std::swap(u, v); // Ensure lexicographical order (u < v)\n        mst_edges.push_back({u, v});\n    }\n    // The problem states response is sorted lexicographically by (u,v) pair.\n    // No need to sort here.\n    return mst_edges;\n}\n\n// Calculate estimated Euclidean distance between two cities using their estimated coordinates\nlong long estimated_dist(const City& c1, const City& c2) {\n    long long dx = static_cast<long long>(std::round(c1.est_x)) - static_cast<long long>(std::round(c2.est_x));\n    long long dy = static_cast<long long>(std::round(c1.est_y)) - static_cast<long long>(std::round(c2.est_y));\n    return static_cast<long long>(std::sqrt(dx * dx + dy * dy));\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    std::cin >> N >> M >> Q >> L >> W;\n\n    std::vector<int> G(M); // Target sizes for each group\n    for (int i = 0; i < M; ++i) {\n        std::cin >> G[i];\n    }\n\n    std::vector<City> cities(N);\n    std::vector<int> p(N); // Permutation for sorting cities by estimated position\n    for (int i = 0; i < N; ++i) {\n        cities[i].id = i;\n        std::cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        // Estimate city coordinates as the center of its bounding box\n        cities[i].est_x = (cities[i].lx + cities[i].rx) / 2.0;\n        cities[i].est_y = (cities[i].ly + cities[i].ry) / 2.0;\n        p[i] = i; // Initialize permutation with city indices\n    }\n\n    // Sort cities based on their estimated coordinates (lexicographically by x, then y)\n    std::sort(p.begin(), p.end(), [&](int i, int j) {\n        if (cities[i].est_x != cities[j].est_x) {\n            return cities[i].est_x < cities[j].est_x;\n        }\n        return cities[i].est_y < cities[j].est_y;\n    });\n\n    // Initial grouping: Assign cities greedily to groups based on sorted estimated positions\n    // This is a heuristic and may not be optimal, but provides a starting point.\n    std::vector<std::vector<int>> final_groups(M); // Stores city IDs for each group\n    std::vector<int> city_to_group_idx(N); // Maps city ID to its group index\n    int current_city_p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < G[k]; ++i) {\n            int city_id = p[current_city_p_idx++];\n            final_groups[k].push_back(city_id);\n            city_to_group_idx[city_id] = k;\n        }\n    }\n\n    // Store all discovered edges from queries. We don't get true weights, only pairs.\n    // We use estimated distance as a proxy weight for sorting and prioritization.\n    std::vector<Edge> collected_queried_edges;\n    std::set<std::pair<int, int>> queried_edge_pairs_set; // To efficiently check if an edge was queried\n\n    int queries_used = 0;\n\n    // Phase 1: Query groups that are small enough (size <= L) to get their exact MST edges.\n    // This uses one query per such group.\n    for (int k = 0; k < M; ++k) {\n        if (final_groups[k].size() <= L && queries_used < Q) {\n            std::vector<std::pair<int, int>> mst_edges = query_mst(final_groups[k]);\n            for (const auto& edge_pair : mst_edges) {\n                int u = edge_pair.first;\n                int v = edge_pair.second;\n                collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n                queried_edge_pairs_set.insert({u, v});\n            }\n            queries_used++;\n        }\n    }\n\n    // Phase 2: Use remaining queries to get more edges by querying overlapping windows.\n    // This strategy aims to cover all cities and discover relationships.\n    int num_windows_to_query = Q - queries_used;\n    for (int i = 0; i < num_windows_to_query; ++i) {\n        std::vector<int> subset;\n        // Create a subset of size L by taking L consecutive cities from the sorted list 'p'.\n        // Use modulo arithmetic for cyclic access to 'p' to ensure all cities can be part of some subset.\n        for (int j = 0; j < L; ++j) {\n            subset.push_back(p[(i + j) % N]);\n        }\n        // Ensure subset size is at least 2 for a valid query\n        if (subset.size() < 2) continue;\n        \n        std::vector<std::pair<int, int>> mst_edges = query_mst(subset);\n        for (const auto& edge_pair : mst_edges) {\n            int u = edge_pair.first;\n            int v = edge_pair.second;\n            collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n            queried_edge_pairs_set.insert({u, v});\n        }\n    }\n\n    // Sort all collected queried edges based on their estimated distances.\n    // This heuristic prioritizes queried edges that are likely to be shorter (and thus better for MST).\n    std::sort(collected_queried_edges.begin(), collected_queried_edges.end());\n\n    // Collect candidate edges for MST construction for each group.\n    // This includes all queried edges and all pairs not covered by queries, using estimated distances.\n    std::vector<Edge> all_candidate_edges;\n    for(const auto& edge : collected_queried_edges) {\n        all_candidate_edges.push_back(edge);\n    }\n\n    // Add edges based on estimated distances for pairs not covered by queries.\n    for(int i=0; i<N; ++i) {\n        for(int j=i+1; j<N; ++j) {\n            if(queried_edge_pairs_set.find({i, j}) == queried_edge_pairs_set.end()) {\n                 all_candidate_edges.push_back({i, j, static_cast<int>(estimated_dist(cities[i], cities[j]))});\n            }\n        }\n    }\n    // Sort all candidate edges by estimated weight\n    std::sort(all_candidate_edges.begin(), all_candidate_edges.end());\n\n    // Build the final MST for each group using the sorted candidate edges.\n    std::vector<std::vector<std::pair<int, int>>> final_group_edges(M);\n    for (int k = 0; k < M; ++k) {\n        DSU dsu(N); // Initialize DSU for all N cities to correctly track components across groups\n        \n        // Add edges greedily using Kruskal's algorithm\n        for (const auto& edge : all_candidate_edges) {\n            // We need G[k]-1 edges for group k. Stop if we have enough.\n            if (final_group_edges[k].size() >= G[k] - 1) break;\n\n            int u = edge.u;\n            int v = edge.v;\n\n            // Check if both cities belong to the current group k\n            if (city_to_group_idx[u] == k && city_to_group_idx[v] == k) {\n                // If adding this edge does not create a cycle within group k's MST\n                if (dsu.find(u) != dsu.find(v)) {\n                    dsu.unite(u, v);\n                    final_group_edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n\n    // Output the final answer: groups and their MST edges\n    std::cout << \"!\" << std::endl;\n    for (int k = 0; k < M; ++k) {\n        // Output cities in the group\n        for (int city_id : final_groups[k]) {\n            std::cout << city_id << \" \";\n        }\n        std::cout << std::endl;\n        // Output edges for the group's MST\n        for (const auto& edge : final_group_edges[k]) {\n            std::cout << edge.first << \" \" << edge.second << std::endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Global variables to store game state and parameters\nint N; // Size of the skating rink (N x N)\nint M; // Total number of points given in input (start position + M-1 targets)\nvector<pair<int, int>> all_points; // Stores all M points: start and targets\nset<pair<int, int>> blocks; // Stores coordinates of all placed blocks\npair<int, int> current_pos; // Current position of the player\n\n// --- Helper Functions ---\n\n// Checks if a given coordinate (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Returns the change in (row, column) for a given direction character.\npair<int, int> get_delta(char dir) {\n    if (dir == 'U') return {-1, 0}; // Up: decrease row\n    if (dir == 'D') return {1, 0};  // Down: increase row\n    if (dir == 'L') return {0, -1}; // Left: decrease column\n    if (dir == 'R') return {0, 1};  // Right: increase column\n    return {0, 0}; // Should not happen with valid input\n}\n\n// --- Game Simulation and Action Execution ---\n\n// Executes a chosen action and direction.\n// This function simulates the action's effect on the game state (current_pos, blocks)\n// and prints the action to standard output for the judge system.\nvoid execute_action(char action, char dir) {\n    pair<int, int> delta = get_delta(dir);\n    int dx = delta.first;\n    int dy = delta.second;\n\n    if (action == 'M') { // Move action\n        // Update current position by one step in the given direction.\n        current_pos.first += dx;\n        current_pos.second += dy;\n        cout << action << ' ' << dir << endl;\n    } else if (action == 'A') { // Alter action\n        // Calculate the coordinates of the adjacent square to alter.\n        int alter_r = current_pos.first + dx;\n        int alter_c = current_pos.second + dy;\n        \n        // Ensure the target square for alteration is within bounds.\n        if (is_valid(alter_r, alter_c)) {\n            // If a block exists, remove it. Otherwise, place a new block.\n            if (blocks.count({alter_r, alter_c})) {\n                blocks.erase({alter_r, alter_c});\n            } else {\n                blocks.insert({alter_r, alter_c});\n            }\n        }\n        cout << action << ' ' << dir << endl;\n        // The player's position (current_pos) does not change during an Alter action.\n    } else if (action == 'S') { // Slide action\n        int cx = current_pos.first;\n        int cy = current_pos.second;\n        int slide_dist = 0;\n        \n        // Simulate the slide step-by-step to determine how far it goes.\n        // The slide stops just before hitting a block or going out of bounds.\n        for (int k = 1; ; ++k) {\n            int r = cx + k * dx;\n            int c = cy + k * dy;\n            \n            // Stop if the next square is out of bounds or contains a block.\n            if (!is_valid(r, c) || blocks.count({r, c})) {\n                slide_dist = k - 1; // The actual distance slid is k-1 squares.\n                break;\n            }\n            // Note: The problem states \"If you slide over a target square without stopping on it, it is not considered visited.\"\n            // This means the slide continues until a block/boundary, even if it passes targets.\n            // Our simulation accurately finds the stopping point.\n        }\n        \n        // Update current position by the calculated slide distance.\n        current_pos.first += slide_dist * dx;\n        current_pos.second += slide_dist * dy;\n        cout << action << ' ' << dir << endl;\n    }\n}\n\n// --- Main Logic ---\n\nint main() {\n    // Optimize standard I/O operations.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input parameters: grid size N and number of points M.\n    cin >> N >> M; \n    // M points are provided: (i_0, j_0) is the starting position,\n    // and (i_1, j_1) through (i_{M-1}, j_{M-1}) are the M-1 targets to visit in sequence.\n    all_points.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> all_points[i].first >> all_points[i].second;\n    }\n\n    // Initialize the player's current position to the starting point.\n    current_pos = all_points[0]; \n\n    // Iterate through each target point that needs to be visited.\n    // The targets are all_points[1] up to all_points[M-1].\n    for (int target_idx = 1; target_idx < M; ++target_idx) {\n        pair<int, int> target_pos = all_points[target_idx]; // The current target to reach.\n\n        // Keep planning and executing actions until the current position matches the target position.\n        while (current_pos != target_pos) {\n            int cx = current_pos.first;\n            int cy = current_pos.second;\n            int tx = target_pos.first;\n            int ty = target_pos.second;\n\n            // --- Determine Primary Direction to Move ---\n            char dir_char = ' ';\n            int dr = tx - cx; // Row difference\n            int dc = ty - cy; // Column difference\n\n            // Decide the primary direction:\n            // If the row difference is larger, prioritize vertical movement (Up/Down).\n            // Otherwise, prioritize horizontal movement (Left/Right).\n            // If row and column differences are equal, prioritize horizontal movement.\n            if (abs(dr) > abs(dc)) {\n                if (dr > 0) dir_char = 'D'; // Target is below\n                else dir_char = 'U';        // Target is above\n            } else { \n                if (dc > 0) dir_char = 'R'; // Target is to the right\n                else dir_char = 'L';        // Target is to the left\n            }\n\n            pair<int, int> delta = get_delta(dir_char);\n            int dx = delta.first;\n            int dy = delta.second;\n\n            // Calculate the position of the immediate next square in the chosen direction.\n            int next_r = cx + dx;\n            int next_c = cy + dy;\n\n            // Check if the target square itself contains a block.\n            bool is_target_blocked = blocks.count({tx, ty});\n            char action_to_take = ' '; // Variable to store the determined action.\n\n            // --- Decision Logic for Choosing Action ---\n\n            // Case 1: The target square is blocked AND we are exactly one step away from it.\n            // To visit the target, we must first remove the block.\n            if ((next_r == tx && next_c == ty) && is_target_blocked) {\n                action_to_take = 'A'; // Use Alter to remove the block at the target.\n            }\n            // Case 2: The very next square in our primary direction is blocked.\n            // This means there's an intermediate obstacle. We must clear it to proceed.\n            else if (blocks.count({next_r, next_c})) {\n                action_to_take = 'A'; // Use Alter to remove the intermediate block.\n            }\n            // Case 3: The next square is clear.\n            else {\n                // Calculate the Manhattan distance to the target.\n                int distance_to_target = abs(tx - cx) + abs(ty - cy);\n\n                // Heuristic strategy:\n                // For longer distances (heuristic threshold of 4), and if the target is clear,\n                // using Slide is more efficient for covering ground quickly.\n                // For shorter distances, or if the target is blocked (and we are not adjacent),\n                // using Move provides better precision and control.\n                if (distance_to_target > 4 && !is_target_blocked) {\n                    action_to_take = 'S'; // Prefer Slide for longer distances.\n                } else {\n                    action_to_take = 'M'; // Prefer Move for shorter distances or when target is blocked.\n                }\n            }\n            \n            // Execute the chosen action. This prints the action/direction and updates the game state.\n            execute_action(action_to_take, dir_char);\n        }\n    }\n\n    return 0; // Program finishes after all targets are visited.\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\n// Use long long for area and large coordinates if needed.\n// For this problem, coordinates are up to 10000, area up to 10^8.\n// int is fine for coordinates. long long for area.\nusing ll = long long;\n\n// Represents an axis-aligned rectangle. Coordinates are [x1, x2) x [y1, y2).\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const { return (ll)(x2 - x1) * (y2 - y1); }\n    int width() const { return x2 - x1; }\n    int height() const { return y2 - y1; }\n};\n\n// Represents a company with its desired location and area.\nstruct Company {\n    int id;\n    int x, y; // Desired point is (x+0.5, y+0.5)\n    ll r;     // Desired area\n};\n\n// Global random number generators for reproducibility and better distribution.\n// Seeded with current time for different runs.\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> dist_01(0.0, 1.0);\n\n// Function to calculate satisfaction for a single company.\n// p_i = 1 - (1 - min(r_i, s_i) / max(r_i, s_i))^2\ndouble calculate_satisfaction(ll r_i, ll s_i) {\n    if (s_i == 0) return 0.0; // Should not happen with positive area constraint\n    double ratio = (double)min(r_i, s_i) / max(r_i, s_i);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Function to find all divisors of a number n.\n// Returns divisors in ascending order.\nvector<ll> get_divisors(ll n) {\n    vector<ll> divisors;\n    for (ll i = 1; i * i <= n; ++i) {\n        if (n % i == 0) {\n            divisors.push_back(i);\n            if (i * i != n) {\n                divisors.push_back(n / i);\n            }\n        }\n    }\n    sort(divisors.begin(), divisors.end());\n    return divisors;\n}\n\n// Structure to hold the result of one complete assignment attempt (one iteration).\nstruct AssignmentResult {\n    // Stores (a, b, c, d) for each company's assigned rectangle.\n    vector<tuple<int, int, int, int>> assignments; \n    // Total satisfaction achieved in this assignment.\n    double total_satisfaction = -1.0; // Initialize to a value lower than any possible satisfaction (0.0).\n};\n\nint N; // Number of companies\nvector<Company> companies_data; // Stores input data for each company.\nvector<Rect> initial_available_regions; // The initial bounding box for space partitioning.\n\n// Number of random trials to perform. This is a key parameter for randomized algorithms.\n// More iterations generally lead to better results but take more time.\nconst int NUM_ITERATIONS = 200; \n\n// The main solver function implementing a randomized recursive partitioning strategy.\nAssignmentResult solve() {\n    AssignmentResult overall_best_result;\n    overall_best_result.assignments.resize(N); // Pre-size for N companies.\n\n    // Indices of companies, used for shuffling and tracking.\n    vector<int> company_indices(N);\n    iota(company_indices.begin(), company_indices.end(), 0); // Fill with 0, 1, ..., N-1.\n\n    // Perform multiple independent trials to explore different random choices.\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<Rect> available_regions = initial_available_regions; // Start with the full 10000x10000 area.\n        vector<int> current_unassigned_companies = company_indices; // Companies yet to be assigned in this iteration.\n        vector<tuple<int, int, int, int>> current_assignments(N); // Stores assignments for this iteration.\n        double current_total_satisfaction = 0.0;\n        bool iteration_failed = false; // Flag to mark if this iteration produced an invalid state.\n\n        // Shuffle companies to process them in a random order for this iteration.\n        shuffle(current_unassigned_companies.begin(), current_unassigned_companies.end(), rng);\n\n        // Assign companies one by one until all are assigned.\n        while (!current_unassigned_companies.empty()) {\n            // Pick the next company to assign. It's the last one in the shuffled list.\n            int company_idx = current_unassigned_companies.back();\n            current_unassigned_companies.pop_back();\n            \n            const Company& company = companies_data[company_idx];\n            ll r_i = company.r;\n\n            // Pick an available region to place this company's ad.\n            // Heuristic: Randomly choose an available region. Other heuristics could be min area, etc.\n            if (available_regions.empty()) {\n                 // This scenario implies an issue: unassigned companies but no space left.\n                 // It suggests the partitioning logic or previous choices were flawed.\n                 iteration_failed = true; \n                 break; // Abandon this iteration.\n            }\n            \n            uniform_int_distribution<int> region_dist(0, available_regions.size() - 1);\n            int region_to_use_idx = region_dist(rng);\n            Rect region = available_regions[region_to_use_idx];\n\n            // Find all possible integer (width, height) pairs that form the desired area r_i\n            // and fit within the chosen region.\n            vector<pair<int, int>> valid_dims;\n            vector<ll> r_i_divisors = get_divisors(r_i); // Get divisors of desired area.\n\n            // Check each divisor 'w' to see if corresponding 'h' fits.\n            for (ll w_ll : r_i_divisors) {\n                int w = static_cast<int>(w_ll); // Cast is safe as w is limited by region.width() <= 10000.\n                if (w > 0 && w <= region.width()) {\n                    ll h_ll = r_i / w;\n                    if (h_ll > 0 && h_ll <= region.height()) {\n                        // If both width and height fit, this is a valid dimension pair.\n                        valid_dims.push_back({w, static_cast<int>(h_ll)}); // Cast is safe as h is limited by region.height() <= 10000.\n                    }\n                }\n            }\n\n            if (valid_dims.empty()) {\n                // If no valid (w, h) pair can form area r_i and fit in the region,\n                // this indicates that the chosen region is too small or has incompatible dimensions for r_i.\n                // Since sum of r_i equals total area, an exact fit should ideally be possible with proper partitioning.\n                // This means the current random choices led to an unresolvable state for this iteration.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose dimensions (w, h) from the list of valid options.\n            // Heuristic: Pick a random pair from valid_dims to explore different shapes.\n            uniform_int_distribution<int> dims_dist(0, valid_dims.size() - 1);\n            pair<int, int> dim = valid_dims[dims_dist(rng)];\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Determine the valid range for the top-left corner (a, b) of the rectangle.\n            // The rectangle [a, a+w) x [b, b+h) must cover the point (company.x+0.5, company.y+0.5).\n            // This means: a <= company.x < a+w AND b <= company.y < b+h.\n            // With integer coordinates, this translates to:\n            // a <= company.x AND a+w >= company.x + 1  => a >= company.x + 1 - w\n            // b <= company.y AND b+h >= company.y + 1  => b >= company.y + 1 - h\n            // Additionally, the rectangle must be within the selected region:\n            // region.x1 <= a AND a+w <= region.x2  => a <= region.x2 - w\n            // region.y1 <= b AND b+h <= region.y2  => b <= region.y2 - h\n            \n            // Combining these constraints to find the valid range for 'a' and 'b'.\n            int min_a = max(region.x1, company.x + 1 - w);\n            int max_a = min(region.x2 - w, company.x);\n            int min_b = max(region.y1, company.y + 1 - h);\n            int max_b = min(region.y2 - h, company.y);\n\n            if (min_a > max_a || min_b > max_b) {\n                // If the valid ranges are empty, it means no position 'a' or 'b' exists\n                // to satisfy all conditions simultaneously. This should ideally not happen\n                // if previous steps (finding valid_dims) were correct and the point is indeed within the region.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose the placement (a, b).\n            // Heuristic: Push the rectangle to the top-left corner (min_a, min_b) of its valid placement range.\n            // This aims to leave larger contiguous areas in the remaining space, potentially aiding future assignments.\n            int a = min_a;\n            int b = min_b;\n            \n            // Assign the rectangle [a, a+w) x [b, b+h) to the company.\n            current_assignments[company_idx] = {a, b, a + w, b + h};\n            ll s_i = (ll)w * h; // Actual area assigned.\n            // Accumulate satisfaction for this company.\n            current_total_satisfaction += calculate_satisfaction(r_i, s_i);\n\n            // Update the list of available regions.\n            // Remove the region that was just used.\n            available_regions.erase(available_regions.begin() + region_to_use_idx);\n\n            // Add the new regions created by partitioning the used region R with the assigned rectangle R_idx.\n            Rect assigned_rect = {a, b, a + w, b + h};\n            \n            // Add region to the left of the assigned rectangle, if it has positive width.\n            if (region.x1 < assigned_rect.x1) {\n                available_regions.push_back({region.x1, region.y1, assigned_rect.x1, region.y2});\n            }\n            // Add region to the right, if it has positive width.\n            if (assigned_rect.x2 < region.x2) {\n                available_regions.push_back({assigned_rect.x2, region.y1, region.x2, region.y2});\n            }\n            // Add region below the assigned rectangle, if it has positive height.\n            if (region.y1 < assigned_rect.y1) {\n                available_regions.push_back({assigned_rect.x1, region.y1, assigned_rect.x2, assigned_rect.y1});\n            }\n            // Add region above the assigned rectangle, if it has positive height.\n            if (assigned_rect.y2 < region.y2) {\n                available_regions.push_back({assigned_rect.x1, assigned_rect.y2, assigned_rect.x2, region.y2});\n            }\n        } // End of while loop: assigning companies within one iteration.\n\n        // After assigning all companies for this iteration, check if it was successful and if it's better than the overall best found so far.\n        if (!iteration_failed && current_total_satisfaction > overall_best_result.total_satisfaction) {\n            overall_best_result.total_satisfaction = current_total_satisfaction;\n            overall_best_result.assignments = current_assignments;\n        }\n    } // End of loop: performing multiple iterations.\n\n    // The problem implies a valid solution is always achievable. If overall_best_result.total_satisfaction is still -1.0,\n    // it means all iterations failed, indicating a potential issue with the algorithm or heuristics.\n    // However, with enough iterations and a reasonable algorithm, at least one should yield a valid assignment.\n\n    return overall_best_result;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n    companies_data.resize(N);\n    ll total_r_sum = 0; // For verification, though problem guarantees sum r_i = 10^8.\n    for (int i = 0; i < N; ++i) {\n        companies_data[i].id = i;\n        cin >> companies_data[i].x >> companies_data[i].y >> companies_data[i].r;\n        total_r_sum += companies_data[i].r;\n    }\n\n    // The problem statement guarantees that the sum of desired areas equals the total area of the 10000x10000 space.\n    // This is a strong hint that an optimal solution involves no wasted space (sum of assigned areas = total area).\n\n    // Initialize the initial available region: the entire 10000x10000 canvas.\n    initial_available_regions.push_back({0, 0, 10000, 10000});\n\n    // Run the solver to get the best assignment found.\n    AssignmentResult final_assignment = solve();\n\n    // Output the resulting rectangle coordinates for each company.\n    for (int i = 0; i < N; ++i) {\n        cout << get<0>(final_assignment.assignments[i]) << \" \"\n             << get<1>(final_assignment.assignments[i]) << \" \"\n             << get<2>(final_assignment.assignments[i]) << \" \"\n             << get<3>(final_assignment.assignments[i]) << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <vector> // Included for general utility, though not strictly used by the final greedy logic\n#include <algorithm> // Included for general utility, e.g., std::fill could be used for initialization\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 50;\n\n// Global arrays for grid data and visited status.\n// Static allocation is used as the grid size is fixed and memory limits are generous.\nint grid[N][N]; // Stores the score p_ij for each square (0 <= p_ij <= 99)\nint tile_map[N][N]; // Stores the tile ID t_ij for each square (0 <= t_ij <= M-1)\nint max_tile_id_plus_1 = 0; // Tracks the total number of unique tiles (M). M is max_tile_id + 1.\n\nbool visited_squares[N][N]; // Boolean matrix to ensure path simplicity (no revisiting squares).\n// The maximum possible tile ID is N*N - 1 (e.g., if all tiles are 1x1 and N*N distinct tiles exist).\n// Thus, an array of size N*N is sufficient to cover all possible tile IDs from 0 to N*N-1.\nbool used_tiles[N * N]; \n\n// Movement directions: Up, Down, Left, Right.\n// These arrays define the change in row (dr) and column (dc) for each of the four cardinal directions.\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\n// Corresponding characters for outputting the path. 'U' for Up, 'D' for Down, 'L' for Left, 'R' for Right.\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize C++ standard streams for faster input/output operations, crucial in competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial position (si, sj) from standard input.\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read the grid scores p_ij for all 50x50 squares.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Read the tile map t_ij for all squares and determine the total number of unique tiles (M).\n    // The problem states that tile IDs range from 0 to M-1, so M is `max_tile_id + 1`.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile_map[i][j];\n            // Update `max_tile_id_plus_1` if a tile ID implies a larger total number of tiles.\n            if (tile_map[i][j] + 1 > max_tile_id_plus_1) {\n                max_tile_id_plus_1 = tile_map[i][j] + 1;\n            }\n        }\n    }\n\n    // Initialize `visited_squares` matrix. Initially, no squares have been visited.\n    // A simple nested loop is efficient for initializing fixed-size arrays.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_squares[i][j] = false;\n        }\n    }\n    \n    // Initialize `used_tiles` array. Initially, no tiles are considered used.\n    // We only need to initialize entries corresponding to actual tile IDs, from 0 up to M-1.\n    for(int i = 0; i < max_tile_id_plus_1; ++i) {\n        used_tiles[i] = false;\n    }\n\n    string path_string = \"\"; // This string will store the sequence of moves (e.g., \"UDLRU\").\n    int current_r = si;    // Initialize current row position to the starting row.\n    int current_c = sj;    // Initialize current column position to the starting column.\n\n    // Mark the starting square as visited and its corresponding tile as used.\n    // This is because Takahashi starts on this square, and it counts as being stepped on.\n    visited_squares[current_r][current_c] = true;\n    // The tile ID at the starting position is guaranteed to be a valid index into `used_tiles`.\n    used_tiles[tile_map[current_r][current_c]] = true;\n\n    // Main loop for constructing the path using a greedy strategy.\n    // The loop continues as long as there are valid moves to make.\n    while (true) {\n        int best_neighbor_score = -1; // Stores the score of the best valid neighbor found. Initialized to -1 to ensure any non-negative score is considered better.\n        int best_dr = -1, best_dc = -1; // Stores the row and column delta for the best move.\n        char best_move_char = ' ';      // Stores the character representation ('U', 'D', 'L', 'R') of the best move.\n\n        // Explore all 4 possible adjacent squares from the current position.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current_r + dr[i]; // Calculate the row of the neighboring square.\n            int nc = current_c + dc[i]; // Calculate the column of the neighboring square.\n\n            // Constraint 1: Boundary Check.\n            // Ensure the neighboring square is within the 50x50 grid limits.\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n                continue; // Skip this neighbor if it's out of bounds.\n            }\n\n            // Constraint 2: Path Simplicity Check.\n            // Ensure the neighboring square has not been visited before in the current path.\n            if (visited_squares[nr][nc]) {\n                continue; // Skip if the square is already visited.\n            }\n\n            // Constraint 3: Tile Usage Check.\n            // Ensure the tile covering this neighboring square has not been used yet.\n            // `tile_map[nr][nc]` is a valid index because `max_tile_id_plus_1` was determined from all tile IDs present in the input.\n            if (used_tiles[tile_map[nr][nc]]) {\n                continue; // Skip if the tile is already used.\n            }\n\n            // If the move to (nr, nc) is valid according to all constraints:\n            // Apply the greedy heuristic: Select the valid neighbor that offers the highest score (`grid[nr][nc]`).\n            if (grid[nr][nc] > best_neighbor_score) {\n                best_neighbor_score = grid[nr][nc]; // Update the highest score found so far.\n                best_dr = dr[i];                    // Record the direction of this best move.\n                best_dc = dc[i];\n                best_move_char = move_char[i];      // Record the character for this best move.\n            }\n        } // End of loop exploring neighbors.\n\n        // If `best_neighbor_score` remained -1, it means no valid moves were found from the current position.\n        // This signifies the end of the path.\n        if (best_neighbor_score == -1) {\n            break; // Exit the path construction loop.\n        }\n\n        // Execute the best move identified:\n        // Update the current position to the coordinates of the chosen neighbor.\n        current_r += best_dr;\n        current_c += best_dc;\n        // Mark the newly entered square as visited to maintain path simplicity.\n        visited_squares[current_r][current_c] = true; \n        // Mark the tile covering this new square as used, enforcing the tile constraint.\n        used_tiles[tile_map[current_r][current_c]] = true; \n        // Append the character representing this move to the output path string.\n        path_string += best_move_char; \n    }\n\n    // Output the generated path string to standard output.\n    cout << path_string << endl;\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cmath>\n#include <iomanip>\n#include <limits>\n#include <algorithm> // For std::reverse\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 30;\n// Represents infinity for distances\nconst double INF = numeric_limits<double>::infinity();\n\n// --- Edge Weights ---\n// h_weights[i][j] stores the weight of the horizontal edge between (i, j) and (i, j+1).\n// i: row index (0 to 29), j: column index (0 to 28).\ndouble h_weights[N][N - 1];\n// v_weights[i][j] stores the weight of the vertical edge between (i, j) and (i+1, j).\n// i: row index (0 to 28), j: column index (0 to 29).\ndouble v_weights[N - 1][N];\n\n// --- Dijkstra's Algorithm Data Structures ---\n// Stores the predecessor vertex for path reconstruction. pred[r][c] = {pr, pc}\npair<int, int> pred[N][N];\n// Stores the shortest estimated distance from the start node to (r, c).\ndouble dist[N][N];\n\n// --- Helper Functions ---\n\n// Gets the weight of the edge between two adjacent vertices (r1, c1) and (r2, c2).\n// Assumes (r1, c1) and (r2, c2) are indeed adjacent.\ndouble get_weight(int r1, int c1, int r2, int c2) {\n    if (r1 == r2) { // Horizontal edge: same row, different columns\n        // Ensure c_min is the smaller column index for array access\n        int c_min = min(c1, c2);\n        return h_weights[r1][c_min];\n    } else { // Vertical edge: same column, different rows\n        // Ensure r_min is the smaller row index for array access\n        int r_min = min(r1, r2);\n        return v_weights[r_min][c1]; // c1 == c2 for vertical edges\n    }\n}\n\n// Updates the weight of the edge between (r1, c1) and (r2, c2) by adding 'delta'.\n// Ensures the weight does not drop below 1.0.\nvoid update_weight(int r1, int c1, int r2, int c2, double delta) {\n    if (r1 == r2) { // Horizontal edge\n        int c_min = min(c1, c2);\n        h_weights[r1][c_min] = max(1.0, h_weights[r1][c_min] + delta);\n    } else { // Vertical edge\n        int r_min = min(r1, r2);\n        v_weights[r_min][c1] = max(1.0, v_weights[r_min][c1] + delta);\n    }\n}\n\n// Dijkstra's algorithm to find the shortest path from start_node to end_node\n// using the current estimated edge weights.\nvoid dijkstra(pair<int, int> start_node, pair<int, int> end_node) {\n    // Initialize distances to infinity and predecessors to an invalid state.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dist[i][j] = INF;\n            pred[i][j] = {-1, -1}; // Sentinel value indicating no predecessor\n        }\n    }\n\n    // Distance to the start node is 0.\n    dist[start_node.first][start_node.second] = 0;\n\n    // Priority queue stores {negative_distance, {row, col}}.\n    // Using negative distance simulates a min-priority queue with std::priority_queue.\n    priority_queue<pair<double, pair<int, int>>> pq;\n    pq.push({0.0, start_node});\n\n    // Possible moves: Up, Down, Left, Right.\n    int dr[] = {-1, 1, 0, 0}; \n    int dc[] = {0, 0, -1, 1};\n\n    while (!pq.empty()) {\n        // Get the node with the smallest distance from the priority queue.\n        auto [d, curr_node] = pq.top();\n        pq.pop();\n        d = -d; // Convert negative distance back to positive.\n\n        int r = curr_node.first;\n        int c = curr_node.second;\n\n        // If the extracted distance is greater than the known shortest distance, skip.\n        if (d > dist[r][c]) {\n            continue;\n        }\n        \n        // If we have reached the destination, we can break.\n        // Since edge weights are positive, this path is guaranteed to be the shortest.\n        if (curr_node == end_node) {\n            break; \n        }\n\n        // Explore neighbors.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid boundaries.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = get_weight(r, c, nr, nc);\n                // If a shorter path to the neighbor is found, update distance and predecessor.\n                if (dist[r][c] + weight < dist[nr][nc]) {\n                    dist[nr][nc] = dist[r][c] + weight;\n                    pred[nr][nc] = {r, c}; // Set current node as predecessor for neighbor.\n                    pq.push({-dist[nr][nc], {nr, nc}}); // Add neighbor to priority queue.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // --- Initialization ---\n    // Initialize all edge weights to a starting guess.\n    // Edge generation values are typically in the range [1000, 9000].\n    // 5000.0 is a reasonable midpoint.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) { // Horizontal edges\n            h_weights[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) { // Vertical edges\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = 5000.0;\n        }\n    }\n\n    // --- Learning Rate Configuration ---\n    // initial_lr determines the magnitude of weight updates.\n    // It decays over time using 1/k.\n    double initial_lr = 1.0; \n\n    // --- Process Queries ---\n    for (int k = 1; k <= 1000; ++k) {\n        // Read start and end nodes for the current query.\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        pair<int, int> start_node = {si, sj};\n        pair<int, int> end_node = {ti, tj};\n\n        // Find the shortest path using Dijkstra with current estimated weights.\n        dijkstra(start_node, end_node);\n\n        // --- Path Reconstruction and Output ---\n        string path_str = \"\";\n        double estimated_path_length = 0.0;\n        vector<pair<int, int>> path_vertices; // Stores the sequence of vertices in the path.\n\n        // Trace back from the end_node to the start_node using predecessor pointers.\n        pair<int, int> curr = end_node;\n        while (!(curr.first == -1 && curr.second == -1)) { // Stop if predecessor is invalid (-1,-1)\n            path_vertices.push_back(curr);\n            if (curr == start_node) break; // Reached the start node\n            curr = pred[curr.first][curr.second];\n        }\n        // The path_vertices are collected in reverse order (end to start). Reverse them.\n        reverse(path_vertices.begin(), path_vertices.end());\n        \n        // If start and end nodes are different, generate the path string and calculate estimated length.\n        if (path_vertices.size() > 1) { \n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i]; // Current vertex\n                pair<int, int> v = path_vertices[i+1]; // Next vertex\n\n                // Add the weight of the edge (u, v) to the estimated path length.\n                estimated_path_length += get_weight(u.first, u.second, v.first, v.second);\n\n                // Determine the move direction and append to the path string.\n                if (u.first < v.first) path_str += 'D'; // Moved Down (row index increased)\n                else if (u.first > v.first) path_str += 'U'; // Moved Up (row index decreased)\n                else if (u.second < v.second) path_str += 'R'; // Moved Right (column index increased)\n                else if (u.second > v.second) path_str += 'L'; // Moved Left (column index decreased)\n            }\n        }\n        \n        // Output the generated path string.\n        cout << path_str << endl;\n        // Flush the output buffer. This is crucial for the judge to receive the output promptly.\n        cout << flush;\n\n        // --- Feedback and Weight Update ---\n        // Read the feedback integer from the judge. This is a noisy measurement of the path's actual length.\n        long long feedback_k_ll; \n        cin >> feedback_k_ll;\n        double feedback_k = static_cast<double>(feedback_k_ll);\n\n        // Calculate the number of edges in the found path.\n        int num_edges = path_vertices.size() - 1;\n        \n        // Only update weights if the path consists of at least one edge (start != end).\n        if (num_edges > 0) { \n            // Calculate the error: difference between observed feedback and estimated length.\n            double error = feedback_k - estimated_path_length;\n            \n            // Calculate the learning rate, which decays with the query number k.\n            double learning_rate = initial_lr / k; \n            \n            // Calculate the update amount to be applied to each edge in the path.\n            // This distributes the total error proportionally across all edges, scaled by the learning rate.\n            double delta_per_edge = learning_rate * error / num_edges;\n            \n            // Update the weights of all edges that constitute the found path.\n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i];\n                pair<int, int> v = path_vertices[i+1];\n                update_weight(u.first, u.second, v.first, v.second, delta_per_edge);\n            }\n        }\n    }\n\n    return 0; // Program finished successfully.\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <set>\n#include <tuple>\n#include <numeric> // For iota\n#include <chrono> // For time-based seed\n\nusing namespace std;\n\nint N;\nint M;\nvector<string> s;\n\n// Matrix characters\nconst char EMPTY = '.';\nconst vector<char> ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nstruct Placement {\n    int string_idx;\n    int r, c, dir; // dir: 0 for horizontal, 1 for vertical\n    vector<pair<int, int>> cells; // List of (row, col) for this placement\n    int id_in_string; // Unique ID for this placement within string_idx\n};\n\nvector<vector<Placement>> all_placements_for_string;\nvector<vector<tuple<int, int, int>>> cell_users; // tuple: (string_idx, placement_id_in_string, pos_in_placement)\nvector<vector<bool>> placement_validity;\nvector<int> valid_placement_count;\nvector<bool> is_matched;\nint num_matched;\nlong long total_cells_filled; // Number of non-empty cells\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Helper for toroidal coordinates\nint mod(int a, int b) {\n    return (a % b + b) % b;\n}\n\n// Calculate score\nlong double calculate_score_value() {\n    if (num_matched < M) {\n        return 1e8 * (long double)num_matched / M;\n    } else {\n        // If c=M, score = round(10^8 * 2 N^2 / (2 N^2 - d))\n        // d = N*N - total_cells_filled\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) { // Avoid division by zero or very small numbers\n            return 2e8; // Effectively max score, or a very high value\n        }\n        return 1e8 * term_numerator / term_denominator;\n    }\n}\n\n// Check if a specific placement is valid in the current matrix A\nbool is_placement_valid(const Placement& p, const vector<string>& A) {\n    for (size_t i = 0; i < p.cells.size(); ++i) {\n        int r_cell = p.cells[i].first;\n        int c_cell = p.cells[i].second;\n        if (A[r_cell][c_cell] != EMPTY && A[r_cell][c_cell] != s[p.string_idx][i]) {\n            return false;\n        }\n    }\n    return true;\n}\n\n// Try to make a move and calculate its score change\n// Returns true if the move is accepted and applied\nbool try_move(vector<string>& A, int r, int c, char new_char) {\n    char old_char = A[r][c];\n    if (old_char == new_char) return false;\n\n    // --- State change calculation ---\n    int current_num_matched = num_matched;\n    long long current_total_cells_filled = total_cells_filled;\n    long double current_score_val = calculate_score_value();\n\n    // Store potential changes in counts for affected strings\n    vector<int> affected_string_indices;\n    if (!cell_users[r][c].empty()) {\n        for (const auto& user : cell_users[r][c]) {\n            affected_string_indices.push_back(get<0>(user));\n        }\n        sort(affected_string_indices.begin(), affected_string_indices.end());\n        affected_string_indices.erase(unique(affected_string_indices.begin(), affected_string_indices.end()), affected_string_indices.end());\n    }\n\n    // Store old validity counts before tentative changes\n    vector<pair<int, int>> old_valid_counts;\n    for(int s_idx : affected_string_indices) {\n        old_valid_counts.push_back({s_idx, valid_placement_count[s_idx]});\n    }\n    \n    // Tentatively apply the change to A\n    A[r][c] = new_char;\n    \n    // Calculate potential changes in num_matched and update placement_validity\n    int delta_num_matched = 0;\n    for (int s_idx : affected_string_indices) {\n        int potential_valid_count = 0;\n        for (const auto& user : cell_users[r][c]) { // Iterate through users of the changed cell\n            if (get<0>(user) == s_idx) {\n                int p_id = get<1>(user);\n                bool old_valid = placement_validity[s_idx][p_id];\n                bool new_valid = is_placement_valid(all_placements_for_string[s_idx][p_id], A);\n                \n                if (old_valid != new_valid) {\n                    placement_validity[s_idx][p_id] = new_valid; // Tentatively update validity\n                }\n            }\n        }\n        \n        // Recalculate the total valid count for s_idx based on updated placement_validity\n        // This needs to check ALL placements for s_idx, not just those using (r,c).\n        // So we must iterate through all placements for s_idx.\n        int current_total_valid_count = 0;\n        for(size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n            // If this placement uses (r,c), its validity was just updated.\n            // Otherwise, check its current validity.\n            bool placement_uses_changed_cell = false;\n            for(const auto& cell_in_p : all_placements_for_string[s_idx][p_id].cells) {\n                if (cell_in_p.first == r && cell_in_p.second == c) {\n                    placement_uses_changed_cell = true;\n                    break;\n                }\n            }\n            if (placement_uses_changed_cell) {\n                // Validity was already updated above. Use the updated value.\n                if(placement_validity[s_idx][p_id]) {\n                    current_total_valid_count++;\n                }\n            } else {\n                // Validity is unchanged. Check if it was valid before.\n                if (placement_validity[s_idx][p_id]) { // If it was valid and still is\n                    current_total_valid_count++;\n                }\n            }\n        }\n\n        // Compare old and new total valid counts to update num_matched\n        int old_count_for_s_idx = 0;\n        for(const auto& state : old_valid_counts) {\n            if (state.first == s_idx) {\n                old_count_for_s_idx = state.second;\n                break;\n            }\n        }\n\n        bool was_matched = (old_count_for_s_idx > 0);\n        bool now_matched = (current_total_valid_count > 0);\n\n        if (was_matched && !now_matched) {\n            delta_num_matched--;\n        } else if (!was_matched && now_matched) {\n            delta_num_matched++;\n        }\n        // Update the global valid_placement_count for s_idx\n        valid_placement_count[s_idx] = current_total_valid_count;\n    }\n\n    // Calculate potential new score\n    int potential_num_matched = current_num_matched + delta_num_matched;\n    long long potential_total_cells_filled = current_total_cells_filled;\n    if (old_char == EMPTY && new_char != EMPTY) potential_total_cells_filled++;\n    if (old_char != EMPTY && new_char == EMPTY) potential_total_cells_filled--;\n    \n    long double potential_score_val;\n    if (potential_num_matched < M) {\n        potential_score_val = 1e8 * (long double)potential_num_matched / M;\n    } else {\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - potential_total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) {\n            potential_score_val = 2e8; // Max score\n        } else {\n            potential_score_val = 1e8 * term_numerator / term_denominator;\n        }\n    }\n\n    // Acceptance criteria\n    bool accept = false;\n    if (potential_score_val > current_score_val) {\n        accept = true;\n    } else if (abs(potential_score_val - current_score_val) < 1e-9) { // Scores are approximately equal\n        // Tie-breaking: prefer filling more cells if c==M\n        if (potential_num_matched == M && current_num_matched == M) {\n            if (potential_total_cells_filled > current_total_cells_filled) { // Prefer fewer dots\n                accept = true;\n            }\n        }\n    }\n\n    if (accept) {\n        // Apply changes permanently\n        total_cells_filled = potential_total_cells_filled;\n        num_matched = potential_num_matched;\n        // The placement_validity has been tentatively updated. The valid_placement_count has also been updated.\n        // is_matched needs to be updated based on final valid_placement_count.\n        for(int s_idx : affected_string_indices) {\n            is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n        }\n        return true;\n    } else {\n        // Revert changes\n        A[r][c] = old_char;\n        // Revert placement validity and counts\n        for(const auto& state : old_valid_counts) {\n            int s_idx = state.first;\n            int old_count = state.second;\n            valid_placement_count[s_idx] = old_count; // Restore count\n        }\n        // Revert placement_validity for affected placements\n        for (int s_idx : affected_string_indices) {\n             for (const auto& user : cell_users[r][c]) {\n                if (get<0>(user) == s_idx) {\n                    int p_id = get<1>(user);\n                    // Find original validity for this placement\n                    bool original_validity_for_p = false;\n                    // We need to re-evaluate validity of this specific placement in the *original* grid A.\n                    // Or, store old validity status for each p_id.\n                    // Simpler: just re-evaluate based on the grid BEFORE the tentative change.\n                    // For now, rely on the fact that only the values for s_idx in affected_string_indices are relevant.\n                    // The state variables `placement_validity` are modified locally.\n                    // The current implementation modifies `placement_validity` directly. This needs careful revert.\n                    // A better way is to store old `placement_validity` values too.\n                    // For simplicity, let's re-evaluate validity in the reverted grid A.\n                    \n                    // For this move, if not accepted, the values calculated were never \"global\".\n                    // `placement_validity` should be restored to its state *before* this function call.\n                    // This requires storing old values for `placement_validity` as well.\n                    // To avoid complex state management, we can re-evaluate `placement_validity` for all affected strings.\n                    \n                    // The issue is that `placement_validity` is modified IN PLACE.\n                    // It needs to be reverted if the move is not accepted.\n                    // This implies we must record the old validity for each affected placement.\n                    // Given the complexity, let's assume the logic in `try_move` that re-calculates `valid_placement_count` and `delta_num_matched` is sufficient, and `placement_validity` modifications are temporary.\n                    // The `placement_validity` modifications are only made permanent if `accept` is true.\n                    // The issue is that the `placement_validity` gets modified even if `accept` is false.\n                    // This requires explicitly reverting `placement_validity`.\n\n                    // Re-evaluating original validity for placement p_id\n                    bool original_validity = is_placement_valid(all_placements_for_string[s_idx][p_id], A); // A is now reverted\n                    placement_validity[s_idx][p_id] = original_validity;\n                }\n            }\n        }\n        return false;\n    }\n}\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M;\n    s.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n    }\n\n    // Precomputation: Generate all possible placements\n    all_placements_for_string.resize(M);\n    cell_users.resize(N, vector<tuple<int, int, int>>(N));\n    \n    int current_placement_id = 0;\n    for (int i = 0; i < M; ++i) {\n        int k = s[i].length();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Horizontal placement\n                Placement p_h;\n                p_h.string_idx = i;\n                p_h.r = r; p_h.c = c; p_h.dir = 0;\n                p_h.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_h.cells[pi] = {r, mod(c + pi, N)};\n                }\n                p_h.id_in_string = all_placements_for_string[i].size(); // ID within string i\n                all_placements_for_string[i].push_back(p_h);\n\n                // Vertical placement\n                Placement p_v;\n                p_v.string_idx = i;\n                p_v.r = r; p_v.c = c; p_v.dir = 1;\n                p_v.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_v.cells[pi] = {mod(r + pi, N), c};\n                }\n                p_v.id_in_string = all_placements_for_string[i].size(); // ID within string i\n                all_placements_for_string[i].push_back(p_v);\n            }\n        }\n    }\n\n    // Populate cell_users: map each cell to which placements use it\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < all_placements_for_string[i].size(); ++j) {\n            const auto& p = all_placements_for_string[i][j];\n            for (size_t cell_idx = 0; cell_idx < p.cells.size(); ++cell_idx) {\n                int r_cell = p.cells[cell_idx].first;\n                int c_cell = p.cells[cell_idx].second;\n                cell_users[r_cell][c_cell].emplace_back(i, j, cell_idx); // string_idx, placement_id_in_string_i, pos_in_placement\n            }\n        }\n    }\n\n    // Initialize matrix and state tracking variables\n    vector<string> A(N, string(N, EMPTY));\n    total_cells_filled = 0;\n\n    placement_validity.resize(M);\n    valid_placement_count.resize(M, 0);\n    is_matched.resize(M, false);\n    num_matched = 0;\n\n    // Initial state: empty grid cannot satisfy specific character requirements.\n    // So, initially, no placement is valid, no string is matched.\n    for (int i = 0; i < M; ++i) {\n        placement_validity[i].resize(all_placements_for_string[i].size(), false);\n    }\n\n    // --- Greedy Seeding Phase ---\n    // Iteratively fill cells to match as many strings as possible.\n    // Repeat until no new strings are matched in a full pass.\n    int max_greedy_passes = 5; // Limit passes to prevent long execution if greedy gets stuck\n    for(int pass = 0; pass < max_greedy_passes; ++pass) {\n        bool new_match_made_in_pass = false;\n        \n        // Create an order of strings to process to break ties and avoid consistent bias\n        vector<int> string_order(M);\n        iota(string_order.begin(), string_order.end(), 0);\n        shuffle(string_order.begin(), string_order.end(), rng);\n\n        for (int s_idx : string_order) {\n            if (is_matched[s_idx]) continue;\n\n            int best_p_id = -1;\n            int min_dots_used_for_best_p = N*N + 1; // Initialize with a value larger than possible\n\n            // Find the best valid placement for s_idx\n            for (size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n                if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                    int current_dots_used = 0;\n                    for (const auto& cell : all_placements_for_string[s_idx][p_id].cells) {\n                        if (A[cell.first][cell.second] == EMPTY) {\n                            current_dots_used++;\n                        }\n                    }\n\n                    // Prioritize placement that uses fewer '.' cells.\n                    if (current_dots_used < min_dots_used_for_best_p) {\n                        min_dots_used_for_best_p = current_dots_used;\n                        best_p_id = p_id;\n                    }\n                }\n            }\n            \n            // If a valid placement was found, apply it\n            if (best_p_id != -1) {\n                const auto& p_to_apply = all_placements_for_string[s_idx][best_p_id];\n                for (const auto& cell : p_to_apply.cells) {\n                    if (A[cell.first][cell.second] == EMPTY) {\n                        // Find the character for this cell in the placement\n                        int cell_pos = -1;\n                        for(size_t pi = 0; pi < p_to_apply.cells.size(); ++pi) {\n                            if (p_to_apply.cells[pi] == cell) {\n                                cell_pos = pi;\n                                break;\n                            }\n                        }\n                        A[cell.first][cell.second] = s[s_idx][cell_pos];\n                        total_cells_filled++;\n                    }\n                }\n                \n                // Update match status for the current string s_idx\n                is_matched[s_idx] = true;\n                num_matched++;\n                new_match_made_in_pass = true;\n\n                // After filling cells, other strings' match statuses might change.\n                // Re-evaluate all strings affected by the newly filled cells.\n                set<int> newly_affected_strings;\n                for(const auto& cell : p_to_apply.cells) {\n                    // Only consider cells that were newly filled\n                    if (A[cell.first][cell.second] != EMPTY) { // Check if it's non-empty now\n                        // Determine if it was indeed newly filled by this placement\n                        bool was_empty_before_fill = false;\n                        for (const auto& user : cell_users[cell.first][cell.second]) {\n                           int user_s_idx = get<0>(user);\n                           int user_p_id = get<1>(user);\n                           const auto& user_p = all_placements_for_string[user_s_idx][user_p_id];\n                           bool cell_is_in_user_p = false;\n                           for(const auto& p_cell : user_p.cells) if(p_cell == cell) cell_is_in_user_p = true;\n\n                           if(cell_is_in_user_p) { // If this user placement uses this cell\n                               // Check if this user placement was valid *before* this current move was applied\n                               // This check is tricky because A has been modified.\n                               // For simplicity, assume any cell filled by this placement can affect others.\n                               newly_affected_strings.insert(get<0>(user));\n                           }\n                        }\n                    }\n                }\n                \n                // Propagate match status updates\n                for(int affected_s_idx : newly_affected_strings) {\n                    if (affected_s_idx == s_idx) continue; // Already handled\n\n                    // Re-evaluate validity for all placements of affected_s_idx\n                    valid_placement_count[affected_s_idx] = 0;\n                    for(size_t p_id_check = 0; p_id_check < all_placements_for_string[affected_s_idx].size(); ++p_id_check) {\n                        placement_validity[affected_s_idx][p_id_check] = is_placement_valid(all_placements_for_string[affected_s_idx][p_id_check], A);\n                        if (placement_validity[affected_s_idx][p_id_check]) {\n                            valid_placement_count[affected_s_idx]++;\n                        }\n                    }\n                    \n                    // Update global match status\n                    bool was_matched = is_matched[affected_s_idx];\n                    bool now_matched = (valid_placement_count[affected_s_idx] > 0);\n\n                    if (was_matched && !now_matched) {\n                        is_matched[affected_s_idx] = false;\n                        num_matched--;\n                        new_match_made_in_pass = true; // Status changed\n                    } else if (!was_matched && now_matched) {\n                        is_matched[affected_s_idx] = true;\n                        num_matched++;\n                        new_match_made_in_pass = true; // Status changed\n                    }\n                }\n            }\n        }\n        if (!new_match_made_in_pass) break; // Stop if no new strings were matched in a full pass\n    }\n\n    // --- Local Search Phase ---\n    // Adjusted ITER_COUNT based on M, to balance exploration and time limit\n    int ITER_COUNT = 100000;\n    if (M > 600) ITER_COUNT = 80000;\n    if (M > 700) ITER_COUNT = 60000;\n    if (M > 750) ITER_COUNT = 50000;\n\n\n    uniform_int_distribution<int> dist_N(0, N - 1);\n    uniform_int_distribution<int> dist_char_idx(0, ALPHABET.size() - 1);\n\n    for (int iter = 0; iter < ITER_COUNT; ++iter) {\n        int r = dist_N(rng);\n        int c = dist_N(rng);\n        char old_char = A[r][c];\n        \n        char new_char;\n        // Determine the target character for the move\n        if (num_matched == M) { \n            // If all strings are matched, focus on reducing dots (increasing filled cells).\n            // Only moves that change a character to EMPTY are beneficial.\n            if (old_char != EMPTY) {\n                new_char = EMPTY;\n            } else {\n                // If the cell is already EMPTY, changing it to a character will increase 'd', decreasing score.\n                // Skip this iteration as it's unlikely to improve score.\n                continue;\n            }\n        } else { \n            // If not all strings are matched, focus on increasing num_matched.\n            // We can try changing to any character or to EMPTY.\n            // Try changing to a random character first.\n            int char_or_empty = rng() % (ALPHABET.size() + 1);\n            if (char_or_empty < ALPHABET.size()) {\n                new_char = ALPHABET[char_or_empty];\n            } else {\n                new_char = EMPTY;\n            }\n        }\n        \n        // Attempt the move. try_move returns true if accepted.\n        try_move(A, r, c, new_char);\n    }\n\n    // Output the resulting matrix\n    for (int i = 0; i < N; ++i) {\n        cout << A[i] << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <utility>\n#include <algorithm>\n#include <cmath>\n#include <iomanip> // For potential debugging\n#include <tuple>   // For std::tuple\n\nusing namespace std;\n\n// Use a large enough value for infinity for Dijkstra distances\nconst long long INF = 1e18;\n\nint N; // Grid size\nint si, sj; // Starting row and column\nvector<string> grid; // Stores the grid characters ('#', '5'-'9')\nvector<vector<int>> cost_grid; // Stores the cost to enter a road square\nvector<pair<int, int>> road_coords; // Stores {row, col} for all road squares\nmap<pair<int, int>, int> coord_to_id; // Maps {row, col} to a unique ID for road squares\nvector<vector<vector<int>>> visible_from; // visible_from[r][c] stores IDs of road squares visible from (r, c)\nvector<vector<pair<int, int>>> adj_grid; // adj_grid[r][c] stores {neighbor_r, neighbor_c} for road squares adjacent to (r,c)\nvector<bool> is_road_covered; // Boolean vector, true if road square with that ID is covered\npair<int, int> current_pos; // Current position of the patrol car\nlong long total_time = 0; // Total travel time of the route\nvector<pair<int, int>> route_path; // Stores the sequence of positions (coordinates) in the route\n\n// Directions for movement: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Function to check if a coordinate is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Function to reconstruct path from Dijkstra's parent pointers\nvector<pair<int, int>> reconstruct_path(const vector<vector<pair<int, int>>>& parent, pair<int, int> start_node, pair<int, int> end_node) {\n    vector<pair<int, int>> path;\n    pair<int, int> curr = end_node;\n\n    // Trace back from end_node to start_node using parent pointers\n    while (!(curr.first == start_node.first && curr.second == start_node.second)) {\n        path.push_back(curr);\n        curr = parent[curr.first][curr.second];\n        // If curr.first is -1, it means we reached an invalid parent, implying no path was found\n        if (curr.first == -1) {\n            // This case should ideally not be reached if a path exists\n            // If start_node and end_node are the same, this loop is skipped\n            break; \n        }\n    }\n    \n    // Add the start node itself to the path\n    // If start_node is same as end_node, the loop above is skipped, path is empty.\n    // We push start_node so path becomes [{start_node}]. This is correct.\n    if (!path.empty() || start_node == end_node) {\n        path.push_back(start_node);\n    } else {\n        // If path is empty and start_node != end_node, it implies start_node was unreachable from end_node.\n        // This scenario should not occur given the problem constraints (connected road graph).\n        // For safety, return an empty path if no path is found.\n        return {};\n    }\n   \n    reverse(path.begin(), path.end()); // Reverse to get path from start to end\n    return path;\n}\n\nvoid solve() {\n    // 1. Read input and initialize data structures\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    cost_grid.resize(N, vector<int>(N));\n    adj_grid.resize(N, vector<pair<int, int>>(N)); // Stores neighbors for each grid cell (only road neighbors)\n    visible_from.resize(N, vector<vector<int>>(N));\n\n    int road_id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') { // If it's a road square\n                cost_grid[i][j] = grid[i][j] - '0'; // Store its travel cost\n                road_coords.push_back({i, j}); // Add its coordinates to the list\n                coord_to_id[{i, j}] = road_id_counter++; // Map its coordinates to a unique ID\n            }\n        }\n    }\n\n    is_road_covered.resize(road_coords.size(), false); // Initialize all roads as not covered\n    current_pos = {si, sj}; // Set current position to the start\n    route_path.push_back(current_pos); // Add start position to the route path\n\n    // 2. Precompute visibility and adjacency for each road square\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] != '#') { // Process only road squares\n                int current_road_id = coord_to_id.at({r, c});\n\n                // A square is always visible from itself\n                visible_from[r][c].push_back(current_road_id);\n\n                // Scan in four directions to find all visible road squares\n                // Left\n                for (int k = c - 1; k >= 0; --k) {\n                    if (grid[r][k] == '#') break; // Stop if an obstacle is encountered\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Right\n                for (int k = c + 1; k < N; ++k) {\n                    if (grid[r][k] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Up\n                for (int k = r - 1; k >= 0; --k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                // Down\n                for (int k = r + 1; k < N; ++k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                \n                // Build adjacency list for road squares: find adjacent road squares\n                for(int i=0; i<4; ++i) {\n                    int nr = r + dr[i];\n                    int nc = c + dc[i];\n                    if (is_valid(nr, nc) && grid[nr][nc] != '#') {\n                        adj_grid[r][c].push_back({nr, nc}); // Store neighbor coordinates\n                    }\n                }\n            }\n        }\n    }\n\n    // Mark initially covered roads based on the starting position\n    for (int visible_road_id : visible_from[si][sj]) {\n        is_road_covered[visible_road_id] = true;\n    }\n\n    // 3. Greedy phase: iteratively move to cover remaining roads\n    int covered_count = 0;\n    for(bool covered : is_road_covered) if(covered) covered_count++;\n\n    while (covered_count < road_coords.size()) {\n        // Find the best next move: one that maximizes coverage gain per unit cost\n        double best_score = -1.0;\n        int best_next_r = -1, best_next_c = -1;\n        \n        // Store candidates for the next move: (score, cost, next_r, next_c)\n        vector<tuple<double, long long, int, int>> candidates; \n\n        // Iterate through adjacent road squares of the current position\n        for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter this neighbor\n\n            int num_newly_covered = 0;\n            // Count how many currently uncovered roads are visible from this neighbor\n            for (int visible_road_id : visible_from[nr][nc]) {\n                if (!is_road_covered[visible_road_id]) {\n                    num_newly_covered++;\n                }\n            }\n\n            // If this move covers at least one new road, consider it as a candidate\n            if (num_newly_covered > 0) {\n                double current_score = (double)num_newly_covered / move_cost; // Coverage gain per unit cost\n                candidates.emplace_back(current_score, move_cost, nr, nc);\n            }\n        }\n\n        // Select the best candidate move\n        if (!candidates.empty()) {\n            // Sort candidates: primarily by score (descending), secondarily by cost (ascending)\n            sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b) {\n                if (abs(get<0>(a) - get<0>(b)) > 1e-9) { // Compare scores with tolerance\n                    return get<0>(a) > get<0>(b); // Higher score first\n                }\n                return get<1>(a) < get<1>(b); // Lower cost first for tie-breaking\n            });\n\n            best_next_r = get<2>(candidates[0]);\n            best_next_c = get<3>(candidates[0]);\n            \n        } else {\n            // Fallback strategy: If no adjacent road square offers new coverage,\n            // choose the cheapest move to any adjacent road square to explore.\n            long long min_fallback_cost = -1;\n            for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n                int nr = neighbor_pos.first;\n                int nc = neighbor_pos.second;\n                long long move_cost = cost_grid[nr][nc];\n\n                if (min_fallback_cost == -1 || move_cost < min_fallback_cost) {\n                    min_fallback_cost = move_cost;\n                    best_next_r = nr;\n                    best_next_c = nc;\n                }\n            }\n            // If best_next_r is still -1, it means current_pos has no road neighbors.\n            // This scenario is unlikely in a connected road graph as per problem statement.\n        }\n        \n        // Apply the chosen move\n        total_time += cost_grid[best_next_r][best_next_c]; // Add cost to enter the new square\n        current_pos = {best_next_r, best_next_c}; // Update current position\n        route_path.push_back(current_pos); // Add the new position to the route path\n\n        // Update the coverage status of roads\n        for (int visible_road_id : visible_from[best_next_r][best_next_c]) {\n            if (!is_road_covered[visible_road_id]) {\n                is_road_covered[visible_road_id] = true; // Mark as covered\n                covered_count++; // Increment total count of covered roads\n            }\n        }\n    }\n\n    // 4. Phase 2: Return to the starting position (si, sj) using Dijkstra's algorithm\n    vector<vector<long long>> dist(N, vector<long long>(N, INF)); // Distances\n    vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1})); // Parent pointers for path reconstruction\n    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq; // Priority queue for Dijkstra\n\n    dist[current_pos.first][current_pos.second] = 0; // Distance from current position to itself is 0\n    pq.push({0, current_pos}); // Push start node for Dijkstra\n\n    pair<int, int> dijkstra_target = {si, sj}; // Target is the original start position\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n\n        // If current distance is greater than recorded distance, skip (already found shorter path)\n        if (d > dist[pos.first][pos.second]) continue;\n        // If we reached the target, break (found shortest path)\n        if (pos == dijkstra_target) break; \n\n        // Explore neighbors\n        for (const auto& neighbor_pos : adj_grid[pos.first][pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter neighbor\n\n            // Relaxation step\n            if (dist[pos.first][pos.second] + move_cost < dist[nr][nc]) {\n                dist[nr][nc] = dist[pos.first][pos.second] + move_cost;\n                parent[nr][nc] = pos; // Set parent for path reconstruction\n                pq.push({dist[nr][nc], {nr, nc}}); // Push neighbor to priority queue\n            }\n        }\n    }\n\n    // Reconstruct and append the return path to the route_path\n    vector<pair<int, int>> return_path_coords = reconstruct_path(parent, current_pos, dijkstra_target);\n    \n    // Append the steps from the return path, starting from the second element\n    // (the first element would be the current_pos itself, which is already in route_path)\n    if (!return_path_coords.empty()) {\n        for (size_t i = 1; i < return_path_coords.size(); ++i) {\n            route_path.push_back(return_path_coords[i]);\n            total_time += cost_grid[return_path_coords[i].first][return_path_coords[i].second]; // Add cost to enter each step\n        }\n    }\n\n    // 5. Generate the output route string (sequence of moves)\n    string result_route = \"\";\n    for (size_t i = 0; i + 1 < route_path.size(); ++i) {\n        pair<int, int> p1 = route_path[i];\n        pair<int, int> p2 = route_path[i+1];\n        int dr_move = p2.first - p1.first;\n        int dc_move = p2.second - p1.second;\n\n        if (dr_move == -1 && dc_move == 0) result_route += 'U'; // Up\n        else if (dr_move == 1 && dc_move == 0) result_route += 'D'; // Down\n        else if (dr_move == 0 && dc_move == -1) result_route += 'L'; // Left\n        else if (dr_move == 0 && dc_move == 1) result_route += 'R'; // Right\n    }\n\n    // Output the generated route string\n    cout << result_route << endl;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main logic\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n// Enum for task status\nenum TaskStatus {\n    UNSTARTED,\n    READY,\n    IN_PROGRESS,\n    COMPLETED\n};\n\n// A large value representing an unknown or very large estimated skill deficit.\n// The maximum possible w_ij could be around K * max(d_ik) ~ 20 * 160 = 3200.\n// Using 3300.0 ensures it's larger than any realistic w_ij.\nconst double INF_ESTIMATED_W = 3300.0; \n\nint N, M, K, R;\nvector<vector<int>> d; // d[task_idx][skill_idx]: required skill levels for task i\nvector<vector<int>> adj; // adj[task_idx]: list of tasks that depend on this task (successors)\nvector<int> in_degree; // in_degree[task_idx]: number of prerequisites not yet met for this task\n\nvector<TaskStatus> task_status;\nvector<bool> member_free; // True if member is available to take a new task\nvector<int> member_current_task; // Stores task_idx if member is busy, -1 otherwise\nvector<int> task_start_day; // Stores the day a task was STARTED (1-indexed day)\n\n// Data for learning and estimation\n// estimated_w[member_idx][task_idx]: estimated skill deficit w_ij for member j on task i.\n// Initialized to INF_ESTIMATED_W. Updated when member j completes task i.\nvector<vector<double>> estimated_w; \n\n// Statistics for members: used for fallback estimation when specific (member, task) w is unknown\nvector<int> member_task_count; // Number of tasks completed by this member\nvector<double> sum_observed_times_member; // Sum of durations of tasks completed by this member\n\n// Global statistics: used as a fallback when member-specific info is also unavailable\ndouble global_average_observed_duration = INF_ESTIMATED_W;\nlong long global_total_tasks_completed = 0;\ndouble global_total_observed_time = 0.0;\n\n// Structure to represent a potential assignment (member, task) with its estimated duration.\n// Used for sorting to greedily pick the best assignments.\nstruct Assignment {\n    double estimated_duration;\n    int member_idx;\n    int task_idx;\n\n    // Custom comparison for sorting: primarily by estimated_duration (ascending).\n    // Smaller duration is better. Tie-breaking is done by member_idx then task_idx for determinism.\n    bool operator<(const Assignment& other) const {\n        // Use a small epsilon for floating point comparisons to avoid issues with precision.\n        if (abs(estimated_duration - other.estimated_duration) > 1e-9) {\n            return estimated_duration < other.estimated_duration;\n        }\n        // Tie-breaking: Prefer lower indexed member, then lower indexed task.\n        if (member_idx != other.member_idx) {\n            return member_idx < other.member_idx;\n        }\n        return task_idx < other.task_idx;\n    }\n};\n\n// Updates the estimated_w for a specific (member_idx, task_idx) pair based on observed time.\n// This function is called at most once for each (member, task) pair because a task\n// is assigned to at most one member, and a member is assigned at most one task at a time.\nvoid update_estimated_w(int member_idx, int task_idx, int observed_time) {\n    double w_val;\n    if (observed_time == 1) {\n        // If task took 1 day, according to the problem statement (w_ij=0 => t_ij=1), w_ij must be 0.\n        w_val = 0.0;\n    } else {\n        // If observed_time > 1, then observed_time = w_ij + r_i, where r_i is a random integer in [-3, 3].\n        // This implies w_ij is in the range [max(0, observed_time - 3), observed_time + 3].\n        // We use the midpoint of this range as our best estimate for w_ij.\n        double w_min = max(0, observed_time - 3);\n        double w_max = observed_time + 3;\n        w_val = (w_min + w_max) / 2.0; \n    }\n    // Store the estimated skill deficit.\n    estimated_w[member_idx][task_idx] = w_val;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial problem parameters.\n    cin >> N >> M >> K >> R;\n\n    // Read task difficulty levels (d_i,k).\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Read task dependencies, build adjacency list (successors) and in-degree array.\n    adj.resize(N);\n    in_degree.resize(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; // Dependency: u must be completed before v can start.\n        cin >> u >> v;\n        --u; --v; // Convert to 0-indexed: u is prerequisite for v.\n        adj[u].push_back(v); // Add v to the adjacency list of u.\n        in_degree[v]++; // Increment in-degree of v.\n    }\n\n    // Initialize state variables for tasks and members.\n    task_status.resize(N, UNSTARTED);\n    member_free.resize(M, true);\n    member_current_task.resize(M, -1);\n    task_start_day.resize(N, -1); // -1 indicates task has not started yet.\n\n    // Initialize data structures for learning and estimation.\n    estimated_w.resize(M, vector<double>(N, INF_ESTIMATED_W));\n    member_task_count.resize(M, 0);\n    sum_observed_times_member.resize(M, 0.0);\n\n    // Identify tasks that are initially ready (have an in-degree of 0).\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) {\n            task_status[i] = READY;\n        }\n    }\n\n    int current_day = 1; // Simulation starts from day 1.\n    int completed_tasks_count = 0; // Counter for total completed tasks.\n\n    // Main simulation loop, runs day by day until all tasks are completed or time limit is reached.\n    while (completed_tasks_count < N) {\n        // 1. Process tasks completed at the END of the previous day.\n        vector<int> completed_members_indices_today; // Store indices of members who finished tasks.\n        int n_completed_input;\n        cin >> n_completed_input;\n\n        // Check for termination signal (-1) from the judge.\n        if (n_completed_input == -1) {\n            break; // Exit simulation if signal is received.\n        }\n\n        for (int i = 0; i < n_completed_input; ++i) {\n            int f_idx_1based;\n            cin >> f_idx_1based;\n            int member_idx = f_idx_1based - 1; // Convert member ID to 0-indexed.\n\n            completed_members_indices_today.push_back(member_idx);\n\n            int task_idx = member_current_task[member_idx]; // Get the task this member was working on.\n            \n            // Calculate the time taken for the task.\n            // A task started on task_start_day[task_idx] and finished at the end of current_day\n            // took current_day - task_start_day[task_idx] days.\n            int observed_time = current_day - task_start_day[task_idx];\n\n            // Update global statistics for overall average performance.\n            global_total_observed_time += observed_time;\n            global_total_tasks_completed++;\n            // Re-calculate global average duration to be more accurate.\n            global_average_observed_duration = global_total_observed_time / global_total_tasks_completed;\n\n            // Learn from the completed task: update estimated_w for this specific (member, task) pair.\n            update_estimated_w(member_idx, task_idx, observed_time);\n            \n            // Update task status to COMPLETED.\n            task_status[task_idx] = COMPLETED;\n            completed_tasks_count++;\n\n            // Mark the member as free, ready for a new assignment.\n            member_free[member_idx] = true;\n            member_current_task[member_idx] = -1;\n            \n            // Update member-specific statistics for future estimations.\n            member_task_count[member_idx]++;\n            sum_observed_times_member[member_idx] += observed_time;\n\n            // Update dependencies: decrement in-degree of successor tasks.\n            // If a successor task's in-degree becomes 0, it becomes READY.\n            for (int dependent_task_idx : adj[task_idx]) {\n                in_degree[dependent_task_idx]--;\n                if (in_degree[dependent_task_idx] == 0) {\n                    task_status[dependent_task_idx] = READY;\n                }\n            }\n        }\n        \n        // 2. Generate potential assignments for the current day.\n        vector<Assignment> candidates; // List to store all possible assignments with their estimated durations.\n        vector<int> ready_tasks_indices;\n        // Collect indices of all tasks that are currently READY.\n        for(int i=0; i<N; ++i) {\n            if (task_status[i] == READY) {\n                ready_tasks_indices.push_back(i);\n            }\n        }\n\n        // For every free member and every ready task, calculate an estimated duration.\n        for (int j = 0; j < M; ++j) { // Iterate through all members\n            if (member_free[j]) { // If member j is available\n                for (int task_idx : ready_tasks_indices) { // Consider all ready tasks\n                    double estimated_duration;\n                    \n                    // Heuristic: Estimate task duration for this (member, task) pair.\n                    // We prioritize assignments with the shortest estimated duration.\n                    // The estimation logic follows a hierarchy of information availability:\n                    // 1. Specific (member, task) estimate: If we have observed member j doing task i before.\n                    // 2. Member's average performance: If member j has completed other tasks.\n                    // 3. Global average performance: If member j is new and no other info is available.\n                    // 4. A very large value: If no historical data exists globally.\n\n                    // 1. Check if `estimated_w[j][task_idx]` has been updated from its initial large value.\n                    // The check ` < INF_ESTIMATED_W - 1.0` is a robust way to see if it's been set.\n                    if (estimated_w[j][task_idx] < INF_ESTIMATED_W - 1.0) { \n                        // `estimated_w` is the estimated skill deficit.\n                        // The estimated time to complete is max(1, estimated_w). This assumes r_i=0 for expected time.\n                        estimated_duration = max(1.0, estimated_w[j][task_idx]);\n                    } else {\n                        // 2. Fallback: Member j has some history (completed other tasks). Use their average completion time.\n                        if (member_task_count[j] > 0) {\n                            estimated_duration = sum_observed_times_member[j] / member_task_count[j];\n                        } else {\n                            // 3. Truly global fallback: Member j is new. Use global average observed time if available.\n                            if (global_total_tasks_completed > 0) {\n                                estimated_duration = global_average_observed_duration;\n                            } else {\n                                // 4. If no tasks have been completed globally yet, use a default high value.\n                                estimated_duration = INF_ESTIMATED_W;\n                            }\n                        }\n                    }\n                    \n                    // Ensure minimum duration is 1 day, as per problem statement.\n                    estimated_duration = max(1.0, estimated_duration);\n                    candidates.push_back({estimated_duration, j, task_idx}); // Add this potential assignment to candidates.\n                }\n            }\n        }\n\n        // Sort all candidate assignments by their estimated duration (ascending).\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Make assignments for the current day.\n        vector<pair<int, int>> assignments_today; // Stores {member_idx, task_idx} for output.\n        vector<bool> task_assigned_today(N, false); // Helper to ensure each task is assigned at most once per day.\n        \n        // Iterate through sorted candidates and make assignments greedily.\n        for (const auto& assignment : candidates) {\n            // Stop if we have already assigned tasks to all M members.\n            if (assignments_today.size() == M) { \n                break;\n            }\n            \n            int member_idx = assignment.member_idx;\n            int task_idx = assignment.task_idx;\n\n            // Check if the member is still free, the task is still ready, and the task hasn't been assigned today.\n            if (member_free[member_idx] && task_status[task_idx] == READY && !task_assigned_today[task_idx]) {\n                // Make the assignment.\n                member_free[member_idx] = false; // Mark member as busy.\n                member_current_task[member_idx] = task_idx; // Assign task to member.\n                task_start_day[task_idx] = current_day; // Record the start day.\n                task_status[task_idx] = IN_PROGRESS; // Update task status.\n                \n                assignments_today.push_back({member_idx, task_idx}); // Record assignment for output.\n                task_assigned_today[task_idx] = true; // Mark task as assigned for today.\n            }\n        }\n\n        // 4. Output assignments for the current day.\n        cout << assignments_today.size(); // Number of assignments.\n        for (const auto& p : assignments_today) {\n            // Output member ID and task ID (1-based).\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1; \n        }\n        cout << endl;\n        cout.flush(); // Ensure output is sent immediately.\n\n        current_day++; // Advance to the next day.\n    }\n\n    return 0; // End of simulation.\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <iomanip> // For std::fixed and std::setprecision\n\n// Use long long for coordinates and distances to be safe, although int might suffice for coordinates\nusing coord_t = int;\nusing dist_t = long long;\n\nstruct Point {\n    coord_t x, y;\n    int id; // Original order ID, or special ID for office\n\n    // Equality operator for point comparisons\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Less than operator for potential use in sets/maps if needed (though not strictly required by this solution)\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// Calculate Manhattan distance between two points\ndist_t manhattan_distance(const Point& p1, const Point& p2) {\n    // Use static_cast to long long to prevent intermediate overflow in abs() if coordinates are large\n    return std::abs(static_cast<long long>(p1.x) - p2.x) + std::abs(static_cast<long long>(p1.y) - p2.y);\n}\n\n// Structure to hold information about a single delivery order\nstruct Order {\n    int id;\n    Point pickup;\n    Point delivery;\n    dist_t internal_dist; // Manhattan distance between pickup and delivery\n    dist_t dist_to_office_pickup; // Manhattan distance from office to pickup\n    dist_t dist_delivery_to_office; // Manhattan distance from delivery to office\n};\n\n// Structure for candidate points during route construction\n// Represents a point to visit next, along with its cost and type (pickup/delivery)\nstruct Candidate {\n    Point p;\n    dist_t cost; // Cost to reach this point from the current location\n    int type; // 0 for pickup, 1 for delivery\n    int order_id; // The ID of the order this point belongs to\n\n    // Custom comparison for sorting candidates by cost\n    bool operator<(const Candidate& other) const {\n        if (cost != other.cost) {\n            return cost < other.cost;\n        }\n        // Tie-breaking: prefer pickups over deliveries if costs are equal.\n        // This might help ensure pickups get visited sooner, enabling more deliveries.\n        return type < other.type; // 0 (pickup) < 1 (delivery)\n    }\n};\n\n// Function to perform 2-opt local search on a tour (vector of Points)\n// WARNING: Standard 2-opt CANNOT be applied directly to TSPPPC as it can violate precedence constraints.\n// This function is commented out due to the WA feedback indicating a problem.\nvoid two_opt(std::vector<Point>& route) {\n    // int n = route.size();\n    // if (n <= 3) return; \n\n    // bool improved = true;\n    // while (improved) {\n    //     improved = false;\n    //     for (int i = 0; i < n - 1; ++i) { \n    //         for (int j = i + 1; j < n; ++j) {\n    //             // Ensure indices are valid\n    //             if (i + 1 < n && j + 1 < n) {\n    //                 dist_t cost_change = manhattan_distance(route[i], route[j]) +\n    //                                       manhattan_distance(route[i+1], route[j+1]) -\n    //                                       manhattan_distance(route[i], route[i+1]) -\n    //                                       manhattan_distance(route[j], route[j+1]);\n\n    //                 if (cost_change < 0) {\n    //                     // Improvement found, reverse the segment from index i+1 to j (inclusive).\n    //                     std::reverse(route.begin() + i + 1, route.begin() + j + 1);\n    //                     improved = true;\n    //                 }\n    //             }\n    //         }\n    //     }\n    // }\n}\n\n// Helper function to determine the grid cell coordinates for a given point\nstd::pair<int, int> get_cell(const Point& p) {\n    return {p.x / 80, p.y / 80}; // 800 / 10 = 80\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::vector<Order> all_orders(1000);\n    Point office = {400, 400, -1}; // Office location, ID -1 signifies office\n\n    // Read input for all 1000 orders\n    for (int i = 0; i < 1000; ++i) {\n        all_orders[i].id = i + 1; // Order IDs are 1-based\n        std::cin >> all_orders[i].pickup.x >> all_orders[i].pickup.y >> all_orders[i].delivery.x >> all_orders[i].delivery.y;\n        \n        // Assign original order ID to Point objects\n        all_orders[i].pickup.id = i + 1;\n        all_orders[i].delivery.id = i + 1;\n\n        // Pre-calculate distances for scoring and route construction\n        all_orders[i].internal_dist = manhattan_distance(all_orders[i].pickup, all_orders[i].delivery);\n        all_orders[i].dist_to_office_pickup = manhattan_distance(office, all_orders[i].pickup);\n        all_orders[i].dist_delivery_to_office = manhattan_distance(all_orders[i].delivery, office);\n    }\n\n    // --- Order Selection Heuristic ---\n    // Strategy: Select orders that are spatially clustered and relatively close to the office.\n    // 1. Group orders by the cell their pickup point falls into.\n    // 2. Score cells based on the average distance from the office to pickup points within them.\n    // 3. Prioritize cells closest to the office.\n    // 4. Collect candidate orders from prioritized cells, sorting them by internal travel distance.\n    // 5. Further refine candidates by a combined score and select the top 50.\n\n    std::map<std::pair<int, int>, std::vector<Order*>> cell_to_orders_map;\n    for (auto& order : all_orders) {\n        cell_to_orders_map[get_cell(order.pickup)].push_back(&order);\n    }\n\n    // Use double for average distance for better precision in cell scoring\n    std::vector<std::pair<double, std::pair<int, int>>> cell_scores; \n    for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n        if (order_list.empty()) continue;\n        dist_t total_dist_to_cell_pickup = 0;\n        for (Order* order_ptr : order_list) {\n            total_dist_to_cell_pickup += manhattan_distance(office, order_ptr->pickup);\n        }\n        // Average distance = total distance / number of orders in cell\n        cell_scores.push_back({static_cast<double>(total_dist_to_cell_pickup) / order_list.size(), cell_coord});\n    }\n\n    // Sort cells based on their average distance score (ascending)\n    std::sort(cell_scores.begin(), cell_scores.end());\n\n    // Pool of candidate orders to choose from. We aim for more than 50 initially to allow for better final selection.\n    std::vector<Order*> candidate_orders_pool; \n    std::set<int> added_order_ids; // Keep track of added orders to avoid duplicates\n\n    // Collect orders from the best cells first (lowest average distance to office)\n    const int MAX_CANDIDATES_TO_CONSIDER = 150; // Aim for a pool larger than 50 for better selection\n    for (const auto& cell_score_pair : cell_scores) {\n        std::pair<int, int> cell_coord = cell_score_pair.second;\n        if (cell_to_orders_map.count(cell_coord)) {\n            std::vector<Order*>& orders_in_cell = cell_to_orders_map[cell_coord];\n            // Sort orders within this cell by their internal travel distance (shortest first)\n            std::sort(orders_in_cell.begin(), orders_in_cell.end(), [](Order* a, Order* b) {\n                return a->internal_dist < b->internal_dist;\n            });\n            \n            // Add orders from this cell to the candidate pool if not already added\n            for (Order* order_ptr : orders_in_cell) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n        }\n        // Stop collecting if we have enough candidates\n        if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break; \n    }\n    \n    // If still not enough candidates after processing all prioritized cells,\n    // fill up from any remaining orders not yet considered.\n    if (candidate_orders_pool.size() < MAX_CANDIDATES_TO_CONSIDER) {\n        for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n            for (Order* order_ptr : order_list) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n             if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break;\n        }\n    }\n    \n    // Sort the pool of candidates by a refined score: \n    // internal_dist + min(dist_to_office_pickup, dist_delivery_to_office).\n    // This score prioritizes orders that are short and/or have at least one endpoint near the office.\n    std::sort(candidate_orders_pool.begin(), candidate_orders_pool.end(), [](Order* a, Order* b) {\n        dist_t score_a = a->internal_dist + std::min(a->dist_to_office_pickup, a->dist_delivery_to_office);\n        dist_t score_b = b->internal_dist + std::min(b->dist_to_office_pickup, b->dist_delivery_to_office);\n        return score_a < score_b;\n    });\n\n    // Select the top 50 orders from the sorted candidate pool.\n    std::vector<int> selected_order_ids;\n    std::vector<Order*> selected_orders_ptr; // Pointers to the actual Order objects for selected orders\n    for (int i = 0; i < 50; ++i) {\n        selected_order_ids.push_back(candidate_orders_pool[i]->id);\n        selected_orders_ptr.push_back(candidate_orders_pool[i]);\n    }\n\n    // --- Route Optimization Heuristic ---\n    // Use a greedy construction that respects precedence.\n    // The problematic 2-opt optimization has been commented out.\n\n    std::vector<Point> route_points; // The sequence of points in the delivery route\n    // Map to quickly access selected order details by their ID\n    std::map<int, Order*> order_map; \n    // Track the visited status of pickups and completed deliveries for selected orders\n    std::map<int, bool> is_pickup_visited;\n    std::map<int, bool> is_delivery_done;\n    \n    // Populate data structures for selected orders\n    for (Order* order_ptr : selected_orders_ptr) {\n        order_map[order_ptr->id] = order_ptr;\n        is_pickup_visited[order_ptr->id] = false;\n        is_delivery_done[order_ptr->id] = false;\n    }\n\n    route_points.push_back(office); // Start the route at the office\n    Point current_location = office;\n    int orders_completed = 0; // Counter for the number of orders fully delivered\n\n    // Greedy construction of the route, ensuring precedence constraints\n    while (orders_completed < 50) {\n        std::vector<Candidate> candidates; // List of possible next points\n\n        // Consider all available pickup points for selected orders\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_pickup_visited[order_id]) {\n                // Add pickup point as a candidate if its order hasn't had pickup visited yet\n                candidates.push_back({order_ptr->pickup, manhattan_distance(current_location, order_ptr->pickup), 0, order_id});\n            }\n        }\n\n        // Consider all available delivery points IF their pickup has already been visited\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_delivery_done[order_id] && is_pickup_visited[order_id]) {\n                // Add delivery point if its order hasn't been completed AND its pickup has been visited\n                candidates.push_back({order_ptr->delivery, manhattan_distance(current_location, order_ptr->delivery), 1, order_id});\n            }\n        }\n\n        // If no valid candidates are found, it means we are stuck.\n        // This should not happen if the problem is solvable for the selected 50 orders and the greedy logic is robust.\n        // If this occurs, `orders_completed` will be less than 50, leading to a WRONG_ANSWER with a similar message.\n        // This break is crucial to prevent infinite loops but signals potential failure.\n        if (candidates.empty()) {\n            // std::cerr << \"Warning: No candidates found. Orders completed: \" << orders_completed << std::endl;\n            break; \n        }\n\n        // Sort candidates by cost (and tie-breaking rule: prefer pickups)\n        std::sort(candidates.begin(), candidates.end());\n        \n        // Select the best candidate (minimum cost)\n        Candidate best_candidate = candidates[0];\n        \n        // Add the chosen point to the route and update current location\n        route_points.push_back(best_candidate.p);\n        current_location = best_candidate.p;\n\n        // Update status based on the type of point visited\n        if (best_candidate.type == 0) { // It was a pickup\n            is_pickup_visited[best_candidate.order_id] = true;\n        } else { // It was a delivery\n            is_delivery_done[best_candidate.order_id] = true;\n            orders_completed++; // Increment count of fully delivered orders\n        }\n    }\n    \n    route_points.push_back(office); // End the route at the office\n\n    // Output the list of selected order IDs\n    std::cout << selected_order_ids.size() << std::endl;\n    for (int i = 0; i < selected_order_ids.size(); ++i) {\n        std::cout << selected_order_ids[i] << (i == selected_order_ids.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    // Output the sequence of points in the optimized route\n    std::cout << route_points.size() << std::endl;\n    for (int i = 0; i < route_points.size(); ++i) {\n        std::cout << route_points[i].x << \" \" << route_points[i].y << (i == route_points.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric> // For std::iota\n#include <algorithm> // For std::swap\n\n// Disjoint Set Union (DSU) data structure\n// Used to keep track of connected components.\nstruct DSU {\n    std::vector<int> parent;\n    std::vector<int> sz;\n\n    // Constructor: Initializes DSU for n elements.\n    // Each element is initially in its own set.\n    DSU(int n) {\n        parent.resize(n);\n        // Initialize each element to be its own parent.\n        // std::iota fills the range [begin, end) with sequentially increasing values, starting from value.\n        std::iota(parent.begin(), parent.end(), 0);\n        // Initialize the size of each set to 1.\n        sz.assign(n, 1);\n    }\n\n    // Finds the representative (root) of the set containing element i.\n    // Implements path compression: flattens the tree structure by making every node\n    // on the path from i to the root point directly to the root. This speeds up future find operations.\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n\n    // Unites the sets containing elements i and j.\n    // Returns true if the sets were different and successfully merged, false otherwise\n    // (i.e., if i and j were already in the same set).\n    // Implements union by size: attaches the root of the smaller tree to the root of the larger tree.\n    // This helps keep the tree heights small, improving the efficiency of find operations.\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            // If sizes are different, attach smaller tree to the root of the larger tree.\n            if (sz[root_i] < sz[root_j])\n                std::swap(root_i, root_j);\n            parent[root_j] = root_i;\n            sz[root_i] += sz[root_j];\n            return true; // Successfully merged two distinct sets\n        }\n        return false; // Elements were already in the same set\n    }\n};\n\n// Structure to store edge information: endpoints and calculated d_i\nstruct Edge {\n    int u, v;\n    long long d; // Rounded Euclidean distance\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // std::ios_base::sync_with_stdio(false) unties C++ streams from C stdio.\n    // std::cin.tie(NULL) unties cin from cout, so cin operations do not force a flush of cout.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // The problem statement specifies that N=400 and M=1995 for all test cases.\n    // These values are fixed and NOT read from standard input.\n    // The input starts directly with vertex coordinates.\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates (x_i, y_i) for each vertex.\n    std::vector<std::pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> coords[i].first >> coords[i].second;\n    }\n\n    // Store edge information: endpoints (u, v) and the pre-calculated d_i for each of the M edges.\n    std::vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u_node, v_node;\n        std::cin >> u_node >> v_node; // Read endpoints for edge i\n        edges[i].u = u_node;\n        edges[i].v = v_node;\n\n        // Calculate the Euclidean distance between endpoints u_node and v_node.\n        // Use long double for intermediate calculations to maintain precision,\n        // especially for sqrt and squaring operations.\n        long double dx = static_cast<long double>(coords[u_node].first) - coords[v_node].first;\n        long double dy = static_cast<long double>(coords[u_node].second) - coords[v_node].second;\n        long double dist_sq = dx * dx + dy * dy;\n        long double dist = std::sqrt(dist_sq);\n        \n        // Round the distance to the nearest integer as per problem statement.\n        // static_cast<long long> is used to cast the result of std::round to long long.\n        edges[i].d = static_cast<long long>(std::round(dist));\n    }\n\n    // Initialize the DSU structure for N vertices.\n    // This structure will track which vertices are connected by the edges we adopt.\n    DSU dsu(N);\n\n    // Keep track of how many edges we've chosen that successfully merged components.\n    // To connect N vertices into a single component, we need exactly N-1 such edges.\n    int merges_made = 0;\n\n    // Process each of the M edges in the order they are revealed.\n    for (int i = 0; i < M; ++i) {\n        long long l_i; // The true edge length for the i-th edge, revealed now.\n        std::cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n\n        // Heuristic Strategy: \"Greedy Connectivity\"\n        // We adopt an edge if and only if it connects two previously disconnected components,\n        // AND we still need to perform component merges to ensure full connectivity.\n        // This strategy guarantees that the final set of adopted edges will be connected.\n        // By limiting adopted edges to exactly N-1 that merge components, we avoid creating cycles,\n        // which is crucial for minimizing total cost under this greedy approach.\n\n        if (dsu.find(u) != dsu.find(v)) {\n            // The endpoints u and v belong to different connected components.\n            // This edge is a candidate for connecting components.\n            \n            if (merges_made < N - 1) {\n                // We still need to make component merges to achieve full connectivity.\n                // Adopt this edge.\n                std::cout << 1 << std::endl;\n                dsu.unite(u, v); // Merge the components of u and v.\n                merges_made++;   // Increment the count of successful merges.\n            } else {\n                // We have already made N-1 merges, meaning the graph is now connected.\n                // Any additional edge that connects two components would form a cycle.\n                // To minimize total cost, we reject such redundant edges.\n                std::cout << 0 << std::endl;\n            }\n        } else {\n            // The endpoints u and v are already in the same connected component.\n            // This edge is redundant for connectivity. Reject it to save cost.\n            std::cout << 0 << std::endl;\n        }\n        \n        // std::endl not only inserts a newline character but also flushes the output buffer.\n        // Flushing is required by the problem statement to ensure the judge receives\n        // our output for each step before providing the next input.\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\n// Structures\nstruct Pos {\n    int r, c;\n    // Equality operator for comparing positions\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n    // Less than operator for sorting and using in maps/sets\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n};\n\nstruct Pet {\n    int id;\n    Pos pos;\n    int type;\n};\n\nstruct Human {\n    int id;\n    Pos pos;\n};\n\n// Directions for movement (U, D, L, R)\n// Corresponding dr and dc values\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1}; // U, D, L, R\n// Corresponding characters for movement and blocking actions\nchar move_chars[] = {'U', 'D', 'L', 'R'};\nchar block_chars[] = {'u', 'd', 'l', 'r'};\n\n// --- Helper Functions ---\n\n// Check if a position is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < GRID_SIZE && c >= 0 && c < GRID_SIZE;\n}\n\n// Calculate Manhattan distance between two positions\nint manhattan_distance(Pos p1, Pos p2) {\n    return abs(p1.r - p2.r) + abs(p1.c - p2.c);\n}\n\n// Get character for human movement action (uppercase)\nchar get_direction_char_for_move(Pos from, Pos to) {\n    if (to.r < from.r) return 'U';\n    if (to.r > from.r) return 'D';\n    if (to.c < from.c) return 'L';\n    if (to.c > from.c) return 'R';\n    return '.'; // Should not happen for movement if positions differ\n}\n\n// Get character for human blocking action (lowercase)\nchar get_direction_char_for_block(Pos from, Pos to) {\n    if (to.r < from.r) return 'u';\n    if (to.r > from.r) return 'd';\n    if (to.c < from.c) return 'l';\n    if (to.c > from.c) return 'r';\n    return '.'; // Should not happen for blocking if positions differ\n}\n\n// Get target position from current position and direction character\nPos get_pos_from_dir_char(Pos from, char dir) {\n    Pos to = from;\n    if (dir == 'U' || dir == 'u') to.r--;\n    else if (dir == 'D' || dir == 'd') to.r++;\n    else if (dir == 'L' || dir == 'l') to.c--;\n    else if (dir == 'R' || dir == 'r') to.c++;\n    return to;\n}\n\n// Get precomputed minimum Manhattan distance from a square (r, c) to any pet.\n// Uses a flattened 1D array for quick lookup.\nint get_min_dist_to_pet(int r, int c, const vector<int>& min_pet_dists_flat) {\n    return min_pet_dists_flat[r * GRID_SIZE + c];\n}\n\n// BFS to find reachable squares from a starting position.\n// This function is primarily for scoring calculation after all turns.\npair<int, vector<Pos>> get_reachable_area(Pos start_pos, const vector<vector<bool>>& is_impassable_grid) {\n    vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n    queue<Pos> q;\n    vector<Pos> reachable_squares;\n\n    // If start position is invalid or impassable, return empty area.\n    if (!is_valid(start_pos.r, start_pos.c) || is_impassable_grid[start_pos.r][start_pos.c]) {\n        return {0, {}};\n    }\n\n    q.push(start_pos);\n    visited[start_pos.r][start_pos.c] = true;\n    reachable_squares.push_back(start_pos);\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        // Explore adjacent squares\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n\n            // If adjacent square is valid, not impassable, and not visited, add to queue.\n            if (is_valid(nr, nc) && !is_impassable_grid[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                Pos next_pos = {nr, nc};\n                q.push(next_pos);\n                reachable_squares.push_back(next_pos);\n            }\n        }\n    }\n    return {reachable_squares.size(), reachable_squares};\n}\n\n// --- Global Variables ---\nint N_pets, M_humans;\nvector<Pet> pets_state;\nvector<Human> humans_state;\n// Grid state: true if impassable, false if passable.\nvector<vector<bool>> is_impassable_grid(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n\n// Main logic for the contest problem\nvoid solve() {\n    // Read initial state: pet positions, types, and human positions.\n    cin >> N_pets;\n    pets_state.resize(N_pets);\n    for (int i = 0; i < N_pets; ++i) {\n        pets_state[i].id = i;\n        cin >> pets_state[i].pos.r >> pets_state[i].pos.c >> pets_state[i].type;\n        pets_state[i].pos.r--; pets_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n    cin >> M_humans;\n    humans_state.resize(M_humans);\n    for (int i = 0; i < M_humans; ++i) {\n        humans_state[i].id = i;\n        cin >> humans_state[i].pos.r >> humans_state[i].pos.c;\n        humans_state[i].pos.r--; humans_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n\n    // Game loop for each turn\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        \n        // --- Precomputation for Human Decision Making ---\n        // Calculate minimum distance from every square to any pet.\n        // This is crucial for the human strategy of staying away from pets.\n        vector<int> min_pet_dists_flat(GRID_SIZE * GRID_SIZE);\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                min_pet_dists_flat[r * GRID_SIZE + c] = GRID_SIZE * 2; // Initialize with a large value\n                for (const auto& pet : pets_state) {\n                    min_pet_dists_flat[r * GRID_SIZE + c] = min(min_pet_dists_flat[r * GRID_SIZE + c], manhattan_distance({r, c}, pet.pos));\n                }\n            }\n        }\n\n        // Identify squares that are potentially blockable by humans.\n        // A square is blockable if it's within bounds, not impassable from previous turns,\n        // not occupied by any human or pet at the start of this turn, and not adjacent to any pet.\n        vector<Pos> blockable_squares;\n        vector<bool> is_occupied_at_start(GRID_SIZE * GRID_SIZE, false); // Mark occupied squares for quick checks\n        for (const auto& p : pets_state) is_occupied_at_start[p.pos.r * GRID_SIZE + p.pos.c] = true;\n        for (const auto& h : humans_state) is_occupied_at_start[h.pos.r * GRID_SIZE + h.pos.c] = true;\n\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                // Rule: Cannot block if adjacent to a pet. Minimum distance >= 2.\n                if (!is_impassable_grid[r][c] && !is_occupied_at_start[r * GRID_SIZE + c] && get_min_dist_to_pet(r, c, min_pet_dists_flat) >= 2) {\n                    blockable_squares.push_back({r, c});\n                }\n            }\n        }\n\n        // For each human, store their best potential blocking and moving action.\n        // Format: {score, position}. Initial score is -1.0 indicating no valid option found.\n        vector<pair<double, Pos>> best_block_options(M_humans, {-1.0, {-1, -1}}); \n        vector<pair<double, Pos>> best_move_options(M_humans, {-1.0, {-1, -1}});  \n\n        // --- Evaluate Blocking Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_block_score = -1.0;\n            Pos best_block_pos = {-1, -1};\n\n            for (const auto& sq : blockable_squares) {\n                double current_block_score = 0;\n                // Heuristic: prioritize blocking squares far from pets\n                current_block_score += (double)get_min_dist_to_pet(sq.r, sq.c, min_pet_dists_flat) * 100.0;\n                \n                // Heuristic: prefer extending existing walls (adjacent to already impassable squares)\n                bool adjacent_to_impassable = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = sq.r + dr[d];\n                    int nc = sq.c + dc[d];\n                    if(is_valid(nr, nc) && is_impassable_grid[nr][nc]) {\n                        adjacent_to_impassable = true;\n                        break;\n                    }\n                }\n                if (adjacent_to_impassable) {\n                    current_block_score += 50.0;\n                }\n                \n                // Heuristic: penalize blocking squares far from human's current position (encourages moving towards blocking target)\n                current_block_score -= manhattan_distance(humans_state[i].pos, sq);\n\n                // Update best option if current score is better\n                if (current_block_score > max_block_score) {\n                    max_block_score = current_block_score;\n                    best_block_pos = sq;\n                } else if (abs(current_block_score - max_block_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                    if (sq.r < best_block_pos.r || (sq.r == best_block_pos.r && sq.c < best_block_pos.c)) {\n                        best_block_pos = sq;\n                    }\n                }\n            }\n            // Store the best block option found for human i\n            if (best_block_pos.r != -1) {\n                best_block_options[i] = {max_block_score, best_block_pos};\n            }\n        }\n\n        // --- Evaluate Movement Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_move_score = -1.0;\n            Pos best_move_pos = {-1, -1};\n\n            // Check all 4 adjacent squares for potential movement\n            for (int d = 0; d < 4; ++d) {\n                int nr = humans_state[i].pos.r + dr[d];\n                int nc = humans_state[i].pos.c + dc[d];\n                Pos next_pos = {nr, nc};\n\n                // Can only move to a valid, passable square\n                if (is_valid(nr, nc) && !is_impassable_grid[nr][nc]) {\n                    // Cannot move to a square occupied by another human at the start of the turn\n                    if (!is_occupied_at_start[nr * GRID_SIZE + nc]) { \n                        double current_move_score = 0;\n                        // Heuristic: prefer moving to squares far from pets\n                        current_move_score += (double)get_min_dist_to_pet(nr, nc, min_pet_dists_flat) * 50.0;\n\n                        // Strong incentive to move to a square that this human plans to block\n                        if (best_block_options[i].second == next_pos) {\n                            current_move_score += 100.0;\n                        }\n                        \n                        // Update best option if current score is better\n                        if (current_move_score > max_move_score) {\n                            max_move_score = current_move_score;\n                            best_move_pos = next_pos;\n                        } else if (abs(current_move_score - max_move_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                            if (next_pos.r < best_move_pos.r || (next_pos.r == best_move_pos.r && next_pos.c < best_move_pos.c)) {\n                                best_move_pos = next_pos;\n                            }\n                        }\n                    }\n                }\n            }\n            // Store the best move option found for human i\n            if (best_move_pos.r != -1) {\n                best_move_options[i] = {max_move_score, best_move_pos};\n            }\n        }\n\n        // --- Conflict Resolution and Final Action Assignment ---\n        // This phase determines which actions are actually performed, resolving conflicts.\n        string human_actions_str(M_humans, '.'); // Stores the output action char for each human\n        vector<Pos> squares_to_move_to_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to move\n        vector<Pos> planned_blocks_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to block\n\n        // Structure to hold all potential actions (block or move) for sorting and conflict resolution\n        struct ActionChoice {\n            int human_id;\n            Pos target_pos;\n            double score;\n            bool is_block_action; // true if this choice is to block, false if to move\n\n            // Custom comparator for sorting: higher score first, then lower human_id for tie-breaking\n            bool operator<(const ActionChoice& other) const {\n                if (abs(score - other.score) > 1e-9) return score > other.score; // Sort by score descending\n                return human_id < other.human_id; // Sort by human_id ascending for ties\n            }\n        };\n        vector<ActionChoice> choices;\n\n        // Populate the list of all potential actions\n        for (int i = 0; i < M_humans; ++i) {\n            if (best_block_options[i].first > -1.0) { // If a block option was found\n                choices.push_back({i, best_block_options[i].second, best_block_options[i].first, true});\n            }\n            if (best_move_options[i].first > -1.0) { // If a move option was found\n                choices.push_back({i, best_move_options[i].second, best_move_options[i].first, false});\n            }\n        }\n        // Sort all potential actions based on score and human_id\n        sort(choices.begin(), choices.end());\n\n        vector<bool> human_assigned_action(M_humans, false); // Track if a human has been assigned an action\n\n        // Process sorted choices to assign actions and resolve conflicts\n        for (const auto& choice : choices) {\n            int hid = choice.human_id;\n            Pos target_pos = choice.target_pos;\n            bool is_block = choice.is_block_action;\n\n            if (human_assigned_action[hid]) continue; // Human already has an assigned action\n\n            if (is_block) {\n                // --- Check if this block action is still possible ---\n                bool can_block = true;\n                // 1. Cannot block if target square will be occupied by a moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (squares_to_move_to_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n                // 2. Cannot block if target square is permanently impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) { // If it was impassable before this turn\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) { // And it's currently empty\n                         can_block = false; // Cannot make an already blocked and empty square impassable.\n                     }\n                }\n                // 3. Cannot block if another human has already planned to block this same square.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n\n                // If the block action is valid, assign it.\n                if (can_block) {\n                    human_actions_str[hid] = get_direction_char_for_block(humans_state[hid].pos, target_pos);\n                    planned_blocks_this_turn[hid] = target_pos; // Record this planned block\n                    human_assigned_action[hid] = true;\n                }\n                // If block failed, this human might try their best move action later if available.\n            } else { // This choice is a movement action\n                // --- Check if this move action is still possible ---\n                bool can_move = true;\n                // 1. Cannot move to a square that is already impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) {\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) {\n                         can_move = false;\n                     }\n                }\n                // 2. Cannot move to a square already claimed by another moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (i != hid && squares_to_move_to_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n                // 3. Cannot move to a square that another human plans to block this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n\n                // If the move action is valid, assign it.\n                if (can_move) {\n                    human_actions_str[hid] = get_direction_char_for_move(humans_state[hid].pos, target_pos);\n                    squares_to_move_to_this_turn[hid] = target_pos; // Record this planned move\n                    human_assigned_action[hid] = true;\n                }\n                // If move failed, this human might have a block action as their next best choice.\n            }\n        }\n        \n        // --- Fallback: Handle humans who couldn't get their preferred action or any action ---\n        // If a human's top choice (block or move) was taken or invalid, they might try their second best,\n        // or default to blocking if possible, or default to staying put.\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                // Try to perform the best block action if it failed initially\n                if (best_block_options[i].first > -1.0) {\n                     Pos block_target = best_block_options[i].second;\n                     bool can_block_fallback = true;\n                     // Check availability similar to above\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (squares_to_move_to_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     if (is_impassable_grid[block_target.r][block_target.c]) {\n                          if (!is_occupied_at_start[block_target.r * GRID_SIZE + block_target.c]) { can_block_fallback = false; }\n                     }\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (planned_blocks_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     \n                     if (can_block_fallback) {\n                          human_actions_str[i] = get_direction_char_for_block(humans_state[i].pos, block_target);\n                          planned_blocks_this_turn[i] = block_target;\n                          human_assigned_action[i] = true;\n                     }\n                }\n                // If blocking still not possible, try to perform the best move action if it failed initially\n                if (!human_assigned_action[i] && best_move_options[i].first > -1.0) {\n                    Pos move_target = best_move_options[i].second;\n                    bool can_move_fallback = true;\n                    // Check availability similar to above\n                    if (is_impassable_grid[move_target.r][move_target.c]) {\n                         if (!is_occupied_at_start[move_target.r * GRID_SIZE + move_target.c]) { can_move_fallback = false; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (h_idx != i && squares_to_move_to_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (planned_blocks_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    \n                    if (can_move_fallback) {\n                         human_actions_str[i] = get_direction_char_for_move(humans_state[i].pos, move_target);\n                         squares_to_move_to_this_turn[i] = move_target;\n                         human_assigned_action[i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Final fallback: If a human still has no action assigned, they do nothing (stay put).\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                human_actions_str[i] = '.';\n            }\n        }\n\n        // --- Output Human Actions and Flush ---\n        cout << human_actions_str << endl;\n        cout << flush; // Essential to flush output for interactive problems\n\n        // --- Read Pet Movements and Update Game State ---\n        vector<string> current_pet_moves(N_pets);\n        for (int i = 0; i < N_pets; ++i) {\n            cin >> current_pet_moves[i];\n        }\n\n        // Update Pet Positions based on input movements\n        for (int i = 0; i < N_pets; ++i) {\n            Pos current_pet_pos = pets_state[i].pos; // Current position at start of turn\n            for (char move : current_pet_moves[i]) { // Process each move character in the string\n                if (move == '.') continue; // No move\n\n                Pos next_pet_pos = current_pet_pos;\n                if (move == 'U') next_pet_pos.r--;\n                else if (move == 'D') next_pet_pos.r++;\n                else if (move == 'L') next_pet_pos.c--;\n                else if (move == 'R') next_pet_pos.c++;\n                \n                // Determine if the target square for the pet is passable.\n                // A square is passable for a pet if it's within grid bounds, AND\n                // it's NOT newly blocked by human action THIS turn, AND\n                // it's NOT permanently blocked (from previous turns) AND currently empty.\n                \n                bool target_is_newly_impassable = false; // Blocked by humans THIS turn\n                for(const auto& block_pos : planned_blocks_this_turn) {\n                    if (block_pos == next_pet_pos) {\n                        target_is_newly_impassable = true;\n                        break;\n                    }\n                }\n                \n                bool is_permanently_blocked_and_empty = false; // Blocked from PREVIOUS turns and currently empty\n                if (is_impassable_grid[next_pet_pos.r][next_pet_pos.c]) { // If it was impassable before this turn\n                    if (!is_occupied_at_start[next_pet_pos.r * GRID_SIZE + next_pet_pos.c]) { // And it's currently empty\n                        is_permanently_blocked_and_empty = true;\n                    }\n                }\n\n                // If the target square is valid and passable for the pet, move the pet.\n                if (is_valid(next_pet_pos.r, next_pet_pos.c) && !target_is_newly_impassable && !is_permanently_blocked_and_empty) {\n                    current_pet_pos = next_pet_pos; // Pet successfully moves\n                } else {\n                    // If move is not possible, pet stays put for this move.\n                    // 'current_pet_pos' remains unchanged, and the next move in the string will be attempted from this position.\n                }\n            }\n            pets_state[i].pos = current_pet_pos; // Update pet's final position for the turn\n        }\n\n        // Update Grid State: Apply the squares that humans planned to block.\n        for (int i = 0; i < M_humans; ++i) {\n            if (planned_blocks_this_turn[i].r != -1) { // If human i planned to block a square\n                is_impassable_grid[planned_blocks_this_turn[i].r][planned_blocks_this_turn[i].c] = true;\n            }\n        }\n\n        // Update Human Positions based on their assigned move actions.\n        for (int i = 0; i < M_humans; ++i) {\n            if (human_actions_str[i] != '.' && human_actions_str[i] != 'u' && human_actions_str[i] != 'd' && human_actions_str[i] != 'l' && human_actions_str[i] != 'r') {\n                // This is a move action (uppercase char)\n                humans_state[i].pos = get_pos_from_dir_char(humans_state[i].pos, human_actions_str[i]);\n            }\n        }\n    }\n\n    // --- Scoring Calculation (for local testing/debugging, not submitted) ---\n    /*\n    double total_satisfaction = 0;\n    for (int i = 0; i < M_humans; ++i) {\n        auto [reachable_count, reachable_squares] = get_reachable_area(humans_state[i].pos, is_impassable_grid);\n        int caught_pets = 0;\n        for (const auto& pet : pets_state) {\n            for (const auto& sq : reachable_squares) {\n                if (pet.pos == sq) {\n                    caught_pets++;\n                    break;\n                }\n            }\n        }\n        double s_i = (double)reachable_count / 900.0 * pow(0.5, caught_pets);\n        total_satisfaction += s_i;\n    }\n    double final_score = round(1e8 * total_satisfaction / M_humans);\n    cerr << \"Final Score (approx): \" << fixed << setprecision(10) << final_score << endl;\n    */\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main game logic\n\n    return 0; // Program finished successfully\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Structure to store parent information for path reconstruction.\n// It records the previous grid cell (r, c), the previous step count (k),\n// and the move character that led to the current state.\nstruct ParentInfo {\n    int r, c, k; // Previous grid position and step count.\n    char move;   // The move character that was chosen to transition from (r,c,k) to the current state.\n};\n\n// Structure representing a state in the Dijkstra search.\n// It includes the expected actual time elapsed, current grid position (r, c),\n// and the number of moves (k) that have been decided/processed for the path.\nstruct State {\n    double expected_time;\n    int r, c, k; \n\n    // Custom comparator for the priority queue to implement a min-priority queue.\n    // States with lower expected_time have higher priority.\n    bool operator>(const State& other) const {\n        return expected_time > other.expected_time;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj, ti, tj; // Start and target coordinates.\n    double p;           // Probability of forgetting a move.\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // Read horizontal wall information. h_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i, j+1), 0 otherwise. Size: 20x19.\n    vector<vector<int>> h_walls(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            h_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    // Read vertical wall information. v_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i+1, j), 0 otherwise. Size: 19x20.\n    vector<vector<int>> v_walls(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            v_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    const int MAX_L = 200; // Maximum allowed length of the output string.\n    const double INF = numeric_limits<double>::max(); // Represents infinity for unreachable states.\n\n    // dist[r][c][k]: Stores the minimum expected actual time to reach grid cell (r, c)\n    // after k moves have been decided/processed for the path.\n    // k ranges from 0 to MAX_L.\n    vector<vector<vector<double>>> dist(20, vector<vector<double>>(20, vector<double>(MAX_L + 1, INF)));\n\n    // parent stores ParentInfo to reconstruct the path.\n    vector<vector<vector<ParentInfo>>> parent(20, vector<vector<ParentInfo>>(20, vector<ParentInfo>(MAX_L + 1, {-1, -1, -1, ' '})));\n\n    // Priority queue for Dijkstra's algorithm.\n    priority_queue<State, vector<State>, greater<State>> pq;\n\n    // Initial state: At home (si, sj), 0 moves processed, with an expected time of 0.0.\n    dist[si][sj][0] = 0.0;\n    pq.push({0.0, si, sj, 0});\n\n    // Define movement directions and corresponding characters for 'U', 'D', 'L', 'R'.\n    int dr[] = {-1, 1, 0, 0}; // Delta row for U, D, L, R\n    int dc[] = {0, 0, -1, 1}; // Delta column for U, D, L, R\n    char moves[] = {'U', 'D', 'L', 'R'};\n\n    // Variables to track the best path found to the office.\n    // min_expected_arrival_time stores the minimum expected time to reach the office.\n    // best_k stores the number of moves processed when the office was reached with min_expected_arrival_time.\n    double min_expected_arrival_time = INF;\n    int best_k = -1; \n\n    // Dijkstra's algorithm main loop.\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        double t = current.expected_time; // Expected time to reach this state.\n        int r = current.r;                 // Current row.\n        int c = current.c;                 // Current column.\n        int k = current.k;                 // Number of moves processed so far.\n\n        // If we found a better path to this state already, skip processing.\n        if (t > dist[r][c][k]) {\n            continue;\n        }\n\n        // Check if the current cell is the office.\n        if (r == ti && c == tj) {\n            // If we reached the office and this path is better than the best found so far, update.\n            if (t < min_expected_arrival_time) {\n                min_expected_arrival_time = t;\n                best_k = k; // Record the number of moves processed for this best path.\n            }\n            // Note: We don't 'continue' here because even if we reached the office,\n            // this state might be part of an even better path to the office IF it's reached earlier in terms of actual moves.\n            // However, since the goal is minimizing expected time, and the arrival time `t` is recorded,\n            // any further exploration from `(r,c,k)` for THIS specific path's time `t` is not useful for finding a *shorter* path to the office *via this specific branch*.\n            // But other states in PQ might offer a path with a lower expected time.\n            // The check `if (k == MAX_L)` below handles the path length limit.\n        }\n        \n        // If we have already processed MAX_L moves, we cannot extend this path further.\n        if (k == MAX_L) {\n            continue;\n        }\n\n        // Explore transitions for the next move (the (k+1)-th move in the sequence).\n        // For each of the 4 possible directions ('U', 'D', 'L', 'R'):\n        for (int i = 0; i < 4; ++i) {\n            char move_char = moves[i];\n            int nr_attempt = r, nc_attempt = c; // Initialize potential next position to current.\n\n            // Determine the target cell if the move is successful, considering grid boundaries and walls.\n            bool wall_collision = false; // True if move is blocked by boundary or wall.\n\n            if (move_char == 'U') {\n                // Check for boundary (r=0) or vertical wall v_walls[r-1][c] (between (r-1,c) and (r,c)).\n                if (r > 0 && !v_walls[r - 1][c]) { nr_attempt = r - 1; } else { wall_collision = true; }\n            } else if (move_char == 'D') {\n                // Check for boundary (r=19) or vertical wall v_walls[r][c] (between (r,c) and (r+1,c)).\n                if (r < 19 && !v_walls[r][c]) { nr_attempt = r + 1; } else { wall_collision = true; }\n            } else if (move_char == 'L') {\n                // Check for boundary (c=0) or horizontal wall h_walls[r][c-1] (between (r,c-1) and (r,c)).\n                if (c > 0 && !h_walls[r][c - 1]) { nc_attempt = c - 1; } else { wall_collision = true; }\n            } else if (move_char == 'R') {\n                // Check for boundary (c=19) or horizontal wall h_walls[r][c] (between (r,c) and (r,c+1)).\n                if (c < 19 && !h_walls[r][c]) { nc_attempt = c + 1; } else { wall_collision = true; }\n            }\n\n            // The actual time advances by 1 turn for this step, regardless of success or failure.\n            double next_expected_time = t + 1.0;\n            int next_k = k + 1; // One more move is now processed.\n\n            // Case 1: Move is forgotten (probability p).\n            // Takahashi stays at the current cell (r, c). The next state is (r, c) after k+1 moves.\n            // If the path to this state (r, c, next_k) via this route is better than previously found paths:\n            if (dist[r][c][next_k] > next_expected_time) {\n                dist[r][c][next_k] = next_expected_time;\n                // Record the parent information: we came from (r, c) at step k, and chose 'move_char'\n                // to generate this state at step k+1.\n                parent[r][c][next_k] = {r, c, k, move_char}; \n                pq.push({next_expected_time, r, c, next_k});\n            }\n\n            // Case 2: Move is executed (probability 1-p).\n            // Takahashi moves to (nr_attempt, nc_attempt). The next state is (nr_attempt, nc_attempt) after k+1 moves.\n            // If the path to this state (nr_attempt, nc_attempt, next_k) via this route is better:\n            if (dist[nr_attempt][nc_attempt][next_k] > next_expected_time) {\n                dist[nr_attempt][nc_attempt][next_k] = next_expected_time;\n                // Record parent information: came from (r, c) at step k, chose 'move_char'.\n                parent[nr_attempt][nc_attempt][next_k] = {r, c, k, move_char};\n                pq.push({next_expected_time, nr_attempt, nc_attempt, next_k});\n            }\n        }\n    }\n\n    // Path reconstruction.\n    string path = \"\";\n    if (best_k != -1) { // If the office was reached at least once within MAX_L moves.\n        int curr_r = ti;\n        int curr_c = tj;\n        int curr_k = best_k;\n\n        // Trace back from the office-reaching state to the start state (0 moves processed).\n        // The loop terminates when curr_k becomes 0.\n        while (curr_k > 0) {\n            ParentInfo p_info = parent[curr_r][curr_c][curr_k];\n            // Append the move character to the path string. This character is the (curr_k)-th move in the sequence.\n            path += p_info.move;\n            // Move to the parent state.\n            curr_r = p_info.r;\n            curr_c = p_info.c;\n            curr_k = p_info.k;\n        }\n        // The path string is built in reverse order, so reverse it.\n        reverse(path.begin(), path.end());\n    }\n    // If best_k remains -1, it means the office was not reached within MAX_L moves with a finite expected time.\n    // According to problem statement, failure leads to score 0. An empty path might be output, or a default path.\n    // However, given problem guarantees and structure, best_k should be set if office is reachable.\n    // For contest robustness, if path is empty, a simple BFS path could be a fallback, but Dijkstra should yield the optimal strategy.\n    \n    cout << path << endl; // Output the constructed commuting route.\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <random>\n#include <chrono> // For seeding the random number generator\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_DIRECTIONS = 4;\n\n// Directions: 0:Left, 1:Up, 2:Right, 3:Down\n// di[d] is the row change for direction d\n// dj[d] is the column change for direction d\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Base connections for the 8 tile types\n// base_connections[tile_type][entry_direction] = exit_direction\n// -1 means no connection\n// This table is derived from the problem statement's 'to' array.\nint base_connections[8][NUM_DIRECTIONS] = {\n    {1, 0, -1, -1}, // Type 0: L-U / U-L (Curve)\n    {3, -1, -1, 0}, // Type 1: L-D / D-L (Curve)\n    {-1, -1, 3, 2}, // Type 2: R-D / D-R (Curve)\n    {-1, 2, 1, -1}, // Type 3: R-U / U-R (Curve)\n    {1, 2, 3, 0},   // Type 4: Square path L->U->R->D->L\n    {3, 2, 1, 0},   // Type 5: S-curve like L->D, U->R, R->U, D->L (as per problem's to table)\n    {2, -1, 0, -1}, // Type 6: Horizontal L<->R (Straight)\n    {-1, 3, -1, 1}  // Type 7: Vertical U<->D (Straight)\n};\n\n// Function to map initial tile type and rotation count to effective tile type\n// The problem states how rotation changes the tile type for different groups.\nint map_type(int initial_type, int rotation) {\n    if (initial_type >= 0 && initial_type <= 3) { // Group 1: {0,1,2,3} rotate cyclically\n        return (initial_type + rotation) % 4;\n    } else if (initial_type == 4) { // Group 2a: {4,5} for initial type 4\n        // Rotation 0,2 -> type 4; Rotation 1,3 -> type 5\n        return 4 + (rotation % 2);\n    } else if (initial_type == 5) { // Group 2b: {4,5} for initial type 5\n        // Rotation 0,2 -> type 5; Rotation 1,3 -> type 4\n        return 4 + ((rotation + 1) % 2);\n    } else if (initial_type == 6) { // Group 3a: {6,7} for initial type 6\n        // Rotation 0,2 -> type 6; Rotation 1,3 -> type 7\n        return 6 + (rotation % 2);\n    } else if (initial_type == 7) { // Group 3b: {6,7} for initial type 7\n        // Rotation 0,2 -> type 7; Rotation 1,3 -> type 6\n        return 6 + ((rotation + 1) % 2);\n    }\n    return -1; // Should not happen\n}\n\n// Global variables to store the current configuration and support loop detection\nvector<vector<int>> base_type_input_grid; // Stores the initial tile type for each cell\nvector<vector<int>> current_rotations_grid; // Stores rotation count (0-3) for each cell\nvector<vector<vector<int>>> effective_to_grid; // Stores the connections for the current configuration of all cells\nvector<vector<vector<bool>>> visited_edge; // To mark edges (cell, entry_direction) that have been part of a found loop or dead end path\nvector<int> loop_lengths; // Stores lengths of all detected loop lines\n\n// Function to calculate the connections for a cell (r, c) based on its base type and current rotation\nvector<int> get_cell_connections(int r, int c) {\n    int initial_type = base_type_input_grid[r][c];\n    int rotation = current_rotations_grid[r][c];\n    int effective_type = map_type(initial_type, rotation);\n    // Return a copy of the connection rules for the effective tile type\n    return vector<int>(base_connections[effective_type], base_connections[effective_type] + NUM_DIRECTIONS);\n}\n\n// Function to find all loop lines and calculate the score (L1 * L2)\n// This function is called repeatedly by the local search heuristic.\nlong long evaluate_all_loops() {\n    // 1. Populate the effective_to_grid based on current rotations\n    effective_to_grid.assign(GRID_SIZE, vector<vector<int>>(GRID_SIZE, vector<int>(NUM_DIRECTIONS)));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            effective_to_grid[i][j] = get_cell_connections(i, j);\n        }\n    }\n\n    // 2. Find all loops using Depth First Search\n    loop_lengths.clear();\n    // visited_edge[i][j][d_in] marks if the edge entering cell (i,j) from direction d_in has been visited globally.\n    // This ensures each directed edge is explored at most once across all DFS traversals, making loop detection efficient.\n    visited_edge.assign(GRID_SIZE, vector<vector<bool>>(GRID_SIZE, vector<bool>(NUM_DIRECTIONS, false)));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            for (int d_in = 0; d_in < NUM_DIRECTIONS; ++d_in) {\n                // If this edge has not been visited yet, start a new DFS traversal\n                if (!visited_edge[i][j][d_in]) {\n                    vector<tuple<int, int, int>> current_path; // Stores the sequence of (row, col, entry_direction) visited in this DFS\n                    map<tuple<int, int, int>, int> visited_in_current_dfs; // Maps state to the step index in current_path for cycle detection\n                    \n                    int cur_i = i, cur_j = j, cur_d_in = d_in;\n                    int step = 0;\n\n                    while (true) {\n                        // Check for out of bounds\n                        if (cur_i < 0 || cur_i >= GRID_SIZE || cur_j < 0 || cur_j >= GRID_SIZE) {\n                            break; // Path broken (out of bounds)\n                        }\n\n                        auto state = make_tuple(cur_i, cur_j, cur_d_in);\n                        \n                        // Check for cycle\n                        if (visited_in_current_dfs.count(state)) {\n                            int cycle_start_step = visited_in_current_dfs[state];\n                            int loop_len = step - cycle_start_step;\n                            \n                            // Mark all edges in the found cycle as visited globally\n                            for (int k = cycle_start_step; k < current_path.size(); ++k) {\n                                auto [pi, pj, pd_in] = current_path[k];\n                                visited_edge[pi][pj][pd_in] = true;\n                            }\n                            loop_lengths.push_back(loop_len);\n                            break; // Found a loop, stop this DFS traversal\n                        }\n\n                        // Mark current state as visited in this DFS and add to path\n                        visited_in_current_dfs[state] = step;\n                        current_path.push_back(state);\n\n                        // Determine next tile and direction\n                        int d_out = effective_to_grid[cur_i][cur_j][cur_d_in];\n                        if (d_out == -1) {\n                            break; // Path broken (tile has no exit in this direction)\n                        }\n\n                        cur_i += di[d_out];\n                        cur_j += dj[d_out];\n                        cur_d_in = (d_out + 2) % 4; // The entry direction to the next tile is opposite of the exit direction from current tile\n                        step++;\n                    }\n                    \n                    // Mark all edges in the path explored by this DFS as globally visited.\n                    // This prevents re-exploring dead-end paths or segments that didn't form a cycle.\n                    for(const auto& path_state : current_path) {\n                        auto [pi, pj, pd_in] = path_state;\n                        visited_edge[pi][pj][pd_in] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 3. Calculate the score: L1 * L2\n    sort(loop_lengths.rbegin(), loop_lengths.rend()); // Sort lengths in descending order\n\n    if (loop_lengths.size() < 2) {\n        return 0; // Score is 0 if less than two loop lines are found\n    }\n    // Use long long for score to prevent overflow\n    return (long long)loop_lengths[0] * loop_lengths[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input and store base tile types\n    base_type_input_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            base_type_input_grid[i][j] = row[j] - '0';\n        }\n    }\n\n    // Initialize rotations: start with all tiles at 0 rotation.\n    // This is a common starting point for heuristic search.\n    current_rotations_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0)); \n\n    long long best_score = 0;\n    vector<vector<int>> best_rotations = current_rotations_grid;\n\n    // Calculate initial score for the all-zero rotation configuration\n    best_score = evaluate_all_loops();\n\n    // --- Randomized Iterative Improvement (Hill Climbing Variant) ---\n    // Use a Mersenne Twister engine for good random number generation.\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> cell_dist(0, GRID_SIZE - 1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n\n    // Number of iterations for the local search. This value is a heuristic tuning parameter.\n    // More iterations generally yield better results but increase computation time.\n    int num_iterations = 100000; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        // Pick a random cell (r, c) to potentially change its rotation\n        int r = cell_dist(rng);\n        int c = cell_dist(rng);\n        int original_rotation = current_rotations_grid[r][c];\n\n        // Explore all 4 possible rotations for the chosen cell (r, c).\n        // For each, evaluate the total score. Keep track of the rotation that yields the maximum score locally.\n        long long max_local_score = -1; // Initialize with a value lower than any possible score\n        int best_local_r = original_rotation; // Default to keeping the original rotation if no improvement found\n\n        for (int test_r = 0; test_r < 4; ++test_r) {\n            current_rotations_grid[r][c] = test_r; // Temporarily set this rotation\n            long long score = evaluate_all_loops(); // Evaluate the score for this configuration\n            \n            if (score > max_local_score) {\n                max_local_score = score;\n                best_local_r = test_r;\n            }\n        }\n        \n        // After trying all 4 rotations, commit the best one found for this cell (r, c).\n        // This is a greedy step: always move to a state that improves the local score.\n        current_rotations_grid[r][c] = best_local_r;\n\n        // Update the global best score and configuration if the current configuration is better\n        if (max_local_score > best_score) {\n            best_score = max_local_score;\n            best_rotations = current_rotations_grid; // Save the rotations that achieved this best score\n        }\n    }\n\n    // Output the resulting rotations as a single string of 900 digits.\n    string result_string = \"\";\n    result_string.reserve(GRID_SIZE * GRID_SIZE); // Reserve space for efficiency\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            result_string += to_string(best_rotations[i][j]);\n        }\n    }\n    cout << result_string << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional> // for std::greater\n\nusing namespace std;\n\nint N;\nint T_limit;\nvector<vector<int>> initial_board_grid;\npair<int, int> initial_empty_pos;\n\n// Target configuration: canonical grid graph with empty at (N-1, N-1)\nvector<vector<int>> canonical_board_grid;\n\n// For state representation and visited set\nusing Board = vector<vector<int>>;\nusing StateKey = vector<int>; // Flattened board\n\n// Stores minimum cost (number of moves) and the path to reach a board state.\n// Key: flattened board configuration.\nmap<StateKey, pair<int, string>> visited;\n\n// Movement directions: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\nchar move_chars[] = {'U', 'D', 'L', 'R'};\n\n// --- Heuristic function ---\n// Calculates the Manhattan distance of the empty square from the target position (N-1, N-1).\n// This is an admissible heuristic for sliding tile puzzles.\nint calculate_heuristic(int r, int c) {\n    return abs(r - (N - 1)) + abs(c - (N - 1));\n}\n\n// --- Board to StateKey conversion ---\n// Converts the 2D board representation to a 1D vector for use as a map key.\nStateKey board_to_key(const Board& board) {\n    StateKey key;\n    key.reserve(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            key.push_back(board[r][c]);\n        }\n    }\n    return key;\n}\n\n// --- Custom State struct for Priority Queue ---\n// Represents a state in the search: current board, empty square position, cost (moves), and path.\nstruct SearchState {\n    Board board;\n    int empty_r, empty_c;\n    int cost; // g_cost: number of moves from initial state\n    string path;\n\n    // Operator overload for priority_queue to prioritize states with lower f_cost (g_cost + h_cost).\n    // If f_costs are equal, prioritize states with lower actual cost (g_cost).\n    bool operator>(const SearchState& other) const {\n        int h_self = calculate_heuristic(empty_r, empty_c);\n        int h_other = calculate_heuristic(other.empty_r, other.empty_c);\n        \n        // Primary sort by f_cost (g + h)\n        if ((cost + h_self) != (other.cost + h_other)) {\n            return (cost + h_self) > (other.cost + h_other);\n        }\n        // Secondary sort by actual cost (g) to favor shorter paths when heuristics are equal\n        return cost > other.cost; \n    }\n};\n\nvoid solve() {\n    // 1. Construct the canonical target board configuration.\n    // This configuration aims to form a grid graph spanning tree with the empty square at (N-1, N-1).\n    // Each tile (r, c) (not the empty square) is assigned bits representing lines needed\n    // to connect to its neighbors in the grid, excluding any connection to the empty square.\n    canonical_board_grid.assign(N, vector<int>(N));\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (r == N - 1 && c == N - 1) {\n                canonical_board_grid[r][c] = 0; // The empty square\n            } else {\n                int val = 0;\n                // Tile at (r, c) needs a RIGHT line (bit 4) if neighbor (r, c+1) exists and is not empty.\n                if (c < N - 1) val |= 4; \n                // Tile at (r, c) needs a LEFT line (bit 1) if neighbor (r, c-1) exists.\n                if (c > 0) val |= 1;     \n                // Tile at (r, c) needs a DOWN line (bit 8) if neighbor (r+1, c) exists and is not empty.\n                if (r < N - 1) val |= 8; \n                // Tile at (r, c) needs an UP line (bit 2) if neighbor (r-1, c) exists.\n                if (r > 0) val |= 2;     \n                canonical_board_grid[r][c] = val;\n            }\n        }\n    }\n\n    // 2. Initialize A* search.\n    priority_queue<SearchState, vector<SearchState>, greater<SearchState>> pq;\n    visited.clear();\n\n    StateKey initial_key = board_to_key(initial_board_grid);\n    SearchState initial_state = {initial_board_grid, initial_empty_pos.first, initial_empty_pos.second, 0, \"\"};\n    \n    // Check if the initial state is already the target state.\n    bool is_initial_target = true;\n    if (initial_state.empty_r != N - 1 || initial_state.empty_c != N - 1) {\n        is_initial_target = false;\n    } else {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r == N - 1 && c == N - 1) continue; // Skip the empty square itself\n                if (initial_state.board[r][c] != canonical_board_grid[r][c]) {\n                    is_initial_target = false;\n                    break;\n                }\n            }\n            if (!is_initial_target) break;\n        }\n    }\n\n    if (is_initial_target) {\n        cout << \"\" << endl; // Zero moves needed if already in target state.\n        return;\n    }\n\n    visited[initial_key] = {0, \"\"};\n    pq.push(initial_state);\n\n    // Limit the number of states explored to prevent Time Limit Exceeded.\n    // This limit is heuristic and may need tuning. It's adjusted based on N.\n    int max_states_to_explore = 2500000; // Default value\n    if (N >= 8) max_states_to_explore = 1800000; \n    if (N == 10) max_states_to_explore = 1200000; \n\n    int states_explored = 0;\n\n    // A* search loop.\n    while (!pq.empty() && states_explored < max_states_to_explore) {\n        SearchState current = pq.top();\n        pq.pop();\n\n        states_explored++;\n\n        StateKey current_key = board_to_key(current.board);\n        \n        // If we've found a shorter path to this state already, skip.\n        if (visited.count(current_key) && visited[current_key].first < current.cost) {\n            continue;\n        }\n\n        // Check if the current state is the target state.\n        bool is_target = true;\n        if (current.empty_r != N - 1 || current.empty_c != N - 1) {\n            is_target = false;\n        } else {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (r == N - 1 && c == N - 1) continue; // Skip the empty square\n                    if (current.board[r][c] != canonical_board_grid[r][c]) {\n                        is_target = false;\n                        break;\n                    }\n                }\n                if (!is_target) break;\n            }\n        }\n\n        // If target is reached, print the path and terminate.\n        if (is_target) {\n            cout << current.path << endl;\n            return; \n        }\n        \n        // Explore neighboring states by moving the empty square.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current.empty_r + dr[i];\n            int nc = current.empty_c + dc[i];\n\n            // Check if the potential new position for the empty square is within board bounds.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                Board next_board = current.board; // Create a copy of the current board.\n                // Perform the move: swap the empty square with the adjacent tile.\n                swap(next_board[current.empty_r][current.empty_c], next_board[nr][nc]);\n\n                StateKey next_key = board_to_key(next_board);\n                int next_cost = current.cost + 1;\n\n                // If this state hasn't been visited, or if we found a shorter path to it:\n                if (!visited.count(next_key) || next_cost < visited[next_key].first) {\n                    // Record the new state with its cost and path.\n                    visited[next_key] = {next_cost, current.path + move_chars[i]};\n                    // Add the new state to the priority queue for exploration.\n                    pq.push({next_board, nr, nc, next_cost, current.path + move_chars[i]});\n                }\n            }\n        }\n    }\n    \n    // According to the problem statement, a solution that forms a tree of size N^2-1\n    // is guaranteed to exist within T operations. If the search loop finishes\n    // without finding the target state, it implies that the search limits (e.g.,\n    // max_states_to_explore) were too strict, the heuristic was insufficient,\n    // or the state space exploration was too slow for the given time limit.\n    // In a competitive programming context, if this part is reached, it typically\n    // indicates a need for optimization, a better heuristic, or a different algorithm.\n    // For this problem, we assume the target state is reachable and will be found.\n    // If not found, the program would exit without outputting a path, which would be WA/TLE.\n}\n\n// Helper function to convert hexadecimal character to integer tile value.\nint char_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input: N (board size) and T (move limit).\n    cin >> N >> T_limit;\n\n    // Read the initial board configuration.\n    initial_board_grid.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            initial_board_grid[i][j] = char_to_int(row[j]);\n            // Store the position of the empty square (tile value 0).\n            if (initial_board_grid[i][j] == 0) {\n                initial_empty_pos = {i, j};\n            }\n        }\n    }\n\n    // Solve the puzzle using A* search.\n    solve();\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <iomanip>\n\nusing namespace std;\n\n// Using large constants for line endpoints to ensure they span across the cake.\n// The problem statement allows coordinates up to 10^9, so these are well within range.\nconst long long INF_COORD = 1e9; \n\nstruct Strawberry {\n    long long x, y;\n    int id;\n};\n\n// Structure to represent a line for output\nstruct Line {\n    long long px, py, qx, qy;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    int k; // Maximum number of cuts\n    cin >> n >> k;\n\n    vector<int> a(11); // a[d] is the number of attendees for d years\n    int total_attendees = 0;\n    for (int d = 1; d <= 10; ++d) {\n        cin >> a[d];\n        total_attendees += a[d];\n    }\n\n    vector<Strawberry> strawberries(n);\n    set<long long> x_coords_set, y_coords_set;\n    for (int i = 0; i < n; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        x_coords_set.insert(strawberries[i].x);\n        y_coords_set.insert(strawberries[i].y);\n    }\n\n    // Strategy: Use k/2 vertical lines and k - k/2 horizontal lines.\n    // This creates a grid of (k/2 + 1) * (k - k/2 + 1) regions.\n    // We need to ensure lines do not pass through any strawberry centers.\n    int num_v_lines = k / 2;\n    int num_h_lines = k - num_v_lines;\n\n    vector<long long> v_line_values; // x-coordinates for vertical lines\n    vector<long long> h_line_values; // y-coordinates for horizontal lines\n\n    // Find num_v_lines integer coordinates for vertical lines.\n    // The range for strawberry coordinates is roughly [-10000, 10000].\n    // We search for values outside this range first, then within.\n    long long current_coord = -10001; // Start searching outside the typical strawberry range\n    while (v_line_values.size() < num_v_lines && current_coord >= -10000 - num_v_lines) { // Search downwards\n        if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord--;\n    }\n    current_coord = 10001; // Start searching outside the typical strawberry range\n    while (v_line_values.size() < num_v_lines && current_coord <= 10000 + num_v_lines) { // Search upwards\n         if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n    // If still not enough, search strictly within the coordinate range\n    current_coord = -10000;\n     while (v_line_values.size() < num_v_lines && current_coord <= 10000) {\n        if (x_coords_set.find(current_coord) == x_coords_set.end()) {\n            v_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n\n\n    // Find num_h_lines integer coordinates for horizontal lines.\n    current_coord = -10001; \n    while (h_line_values.size() < num_h_lines && current_coord >= -10000 - num_h_lines) { // Search downwards\n        if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord--;\n    }\n    current_coord = 10001;\n    while (h_line_values.size() < num_h_lines && current_coord <= 10000 + num_h_lines) { // Search upwards\n         if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n    // If still not enough, search strictly within the coordinate range\n    current_coord = -10000;\n     while (h_line_values.size() < num_h_lines && current_coord <= 10000) {\n        if (y_coords_set.find(current_coord) == y_coords_set.end()) {\n            h_line_values.push_back(current_coord);\n        }\n        current_coord++;\n    }\n\n\n    // Define boundaries for regions. These are used to define cells.\n    // We use values slightly outside the typical range of strawberry coordinates.\n    vector<long long> v_boundaries = {-20000}; // Sentinel: smaller than any possible x_i\n    v_boundaries.insert(v_boundaries.end(), v_line_values.begin(), v_line_values.end());\n    v_boundaries.push_back(20000); // Sentinel: larger than any possible x_i\n\n    vector<long long> h_boundaries = {-20000};\n    h_boundaries.insert(h_boundaries.end(), h_line_values.begin(), h_line_values.end());\n    h_boundaries.push_back(20000);\n\n    // Sort boundaries and remove duplicates to ensure proper interval definition\n    sort(v_boundaries.begin(), v_boundaries.end());\n    v_boundaries.erase(unique(v_boundaries.begin(), v_boundaries.end()), v_boundaries.end());\n    sort(h_boundaries.begin(), h_boundaries.end());\n    h_boundaries.erase(unique(h_boundaries.begin(), h_boundaries.end()), h_boundaries.end());\n\n    // Count strawberries in each region defined by the grid.\n    // Store regions as pairs: {strawberry_count, region_flat_index}\n    vector<pair<int, int>> region_info; \n    // Group regions by their strawberry count for easier assignment.\n    map<int, vector<int>> regions_by_count; // count -> list of region_flat_indices\n\n    int region_flat_idx = 0;\n    for (size_t j = 0; j < v_boundaries.size() - 1; ++j) {\n        for (size_t k = 0; k < h_boundaries.size() - 1; ++k) {\n            int count = 0;\n            long long min_x = v_boundaries[j];\n            long long max_x = v_boundaries[j+1];\n            long long min_y = h_boundaries[k];\n            long long max_y = h_boundaries[k+1];\n\n            // Count strawberries within the current rectangular region.\n            for (const auto& straw : strawberries) {\n                if (straw.x >= min_x && straw.x < max_x &&\n                    straw.y >= min_y && straw.y < max_y) {\n                    count++;\n                }\n            }\n            \n            // We only care about regions that contain at least one strawberry.\n            if (count > 0) { \n                region_info.push_back({count, region_flat_idx});\n                regions_by_count[count].push_back(region_flat_idx);\n                region_flat_idx++;\n            }\n        }\n    }\n    \n    // Sort regions by their strawberry count. This helps in greedy assignment.\n    sort(region_info.begin(), region_info.end());\n\n    // Assignment phase: greedily assign available regions to satisfy demands a[d].\n    vector<bool> region_taken(region_flat_idx, false); // Tracks if a region has been assigned.\n    vector<int> b_counts(11, 0); // b_counts[d] will store the number of pieces with d strawberries.\n    vector<Line> cuts; // Stores the lines to be output.\n\n    // Iterate through each demand (d from 1 to 10, and for each a[d] attendees).\n    for (int d = 1; d <= 10; ++d) {\n        for (int i = 0; i < a[d]; ++i) {\n            // Try to find an available region with exactly 'd' strawberries.\n            bool found_region_for_demand = false;\n            if (regions_by_count.count(d)) {\n                // Get the list of regions that contain exactly 'd' strawberries.\n                vector<int>& available_regions_for_d = regions_by_count[d];\n                \n                // Iterate through these regions to find one that hasn't been taken.\n                for (size_t region_list_idx = 0; region_list_idx < available_regions_for_d.size(); ++region_list_idx) {\n                    int r_idx = available_regions_for_d[region_list_idx];\n                    if (!region_taken[r_idx]) {\n                        region_taken[r_idx] = true; // Mark this region as taken.\n                        b_counts[d]++;             // Increment the count of pieces with 'd' strawberries.\n                        found_region_for_demand = true;\n                        \n                        // To ensure this region is not considered again for the same demand 'd',\n                        // we move it to the end of the list and then pop it. This is an efficient way\n                        // to \"remove\" it from consideration for future demands of count 'd'.\n                        swap(available_regions_for_d[region_list_idx], available_regions_for_d.back());\n                        available_regions_for_d.pop_back();\n                        break; // Found a region for this specific demand, move to the next demand.\n                    }\n                }\n            }\n        }\n    }\n\n    // Output the cuts.\n    // For each selected vertical line coordinate C, create a line from (C, -INF_COORD) to (C, INF_COORD).\n    for (long long val : v_line_values) {\n        cuts.push_back({val, -INF_COORD, val, INF_COORD});\n    }\n    // For each selected horizontal line coordinate C, create a line from (-INF_COORD, C) to (INF_COORD, C).\n    for (long long val : h_line_values) {\n        cuts.push_back({-INF_COORD, val, INF_COORD, val});\n    }\n\n    cout << cuts.size() << endl;\n    for (const auto& line : cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <set>\n#include <algorithm>\n#include <map>\n#include <tuple>\n\nusing namespace std;\n\n// Maximum number of operations to perform.\n// A limit is needed to prevent infinite loops and control execution time.\nconst int MAX_OPS = 5000; \n\n// Structure to represent a grid point.\nstruct Point {\n    int x, y;\n\n    // For use in std::set and std::map.\n    // Lexicographical comparison.\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n\n    // For equality checks.\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Global variables for grid dimensions, center, and total weight.\nlong long N_val; // Grid size (N x N). Renamed from N to avoid conflict.\nPoint center; // Center of the grid for weight calculation.\nlong long total_weight_sum_val; // Sum of weights of all points with dots. Renamed to avoid conflict.\n\n// Data structures for storing drawn segments to check for overlaps.\n// For axis-aligned segments:\n// h_segments_by_y[y] stores a set of pairs {min_x, max_x} for horizontal segments on line y.\n// v_segments_by_x[x] stores a set of pairs {min_y, max_y} for vertical segments on line x.\nmap<int, set<pair<int, int>>> h_segments_by_y;\nmap<int, set<pair<int, int>>> v_segments_by_x;\n\n// For 45-degree segments, we use transformed coordinates:\n// u = x + y\n// v = x - y\n// A segment with dx=dy becomes horizontal in (u,v) space (v is constant).\n//   Stored in uv_v_segments_by_v: key is the constant v, value is the range of u {min_u, max_u}.\n// A segment with dx=-dy becomes vertical in (u,v) space (u is constant).\n//   Stored in uv_h_segments_by_u: key is the constant u, value is the range of v {min_v, max_v}.\nmap<int, set<pair<int, int>>> uv_h_segments_by_u; // Stores vertical segments in (u,v) plane\nmap<int, set<pair<int, int>>> uv_v_segments_by_v; // Stores horizontal segments in (u,v) plane\n\n// Calculates the weight of a grid point based on its distance from the center.\nlong long weight(Point p) {\n    long long dx = p.x - center.x;\n    long long dy = p.y - center.y;\n    return dx * dx + dy * dy + 1;\n}\n\n// Adds a new segment (defined by two points) to the appropriate segment tracking maps.\nvoid add_segment(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        v_segments_by_x[p1.x].insert({min_y, max_y});\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        h_segments_by_y[p1.y].insert({min_x, max_x});\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // For 45-degree segments, |dx| must equal |dy|.\n        // This check is defensive; it should not be necessary if rectangle shape is correctly validated.\n        if (abs(dx) != abs(dy)) {\n             return; \n        }\n\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n\n        if (dx == dy) { // Segment is horizontal in (u,v) space (v is constant).\n            int v_const = v1; // v1 == v2 for dx=dy.\n            // Store in uv_v_segments_by_v, keyed by the constant v. Range is of u.\n            uv_v_segments_by_v[v_const].insert({min(u1, u2), max(u1, u2)});\n        } else { // dx == -dy. Segment is vertical in (u,v) space (u is constant).\n            int u_const = u1; // u1 == u2 for dx=-dy.\n            // Store in uv_h_segments_by_u, keyed by the constant u. Range is of v.\n            uv_h_segments_by_u[u_const].insert({min(v1, v2), max(v1, v2)});\n        }\n    }\n}\n\n// Checks if a new segment defined by p1 and p2 overlaps with any previously drawn segment.\nbool check_segment_overlap(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        \n        auto it_map = v_segments_by_x.find(p1.x); // Look for segments on the same vertical line.\n        if (it_map != v_segments_by_x.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_y, max_y}.\n            \n            // Efficiently find potentially overlapping segments.\n            // Find the first segment whose max_y is greater than or equal to our min_y.\n            // A segment [seg_min_y, seg_max_y] overlaps with [min_y, max_y] if seg_max_y >= min_y AND seg_min_y <= max_y.\n            // We search for segments whose 'first' element (seg_min_y) is <= max_y.\n            // `upper_bound({max_y, -1})` finds the first element strictly greater than {max_y, -1}.\n            // Decrementing it gives the first element that might overlap (its start is <= max_y).\n            auto it = segments.upper_bound({max_y, -1}); \n            if (it != segments.begin()) {\n                --it; // Move to the first segment that could overlap.\n                do {\n                    // Check for overlap: existing segment [it->first, it->second] vs new segment [min_y, max_y].\n                    if (it->second >= min_y && it->first <= max_y) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break; // Stop if we reached the beginning.\n                    --it; // Move to the next potential overlapping segment.\n                } while (it->first >= min_y); // Optimization: If an existing segment starts before our new segment, further preceding segments cannot overlap.\n            }\n        }\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        \n        auto it_map = h_segments_by_y.find(p1.y); // Look for segments on the same horizontal line.\n        if (it_map != h_segments_by_y.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_x, max_x}.\n            \n            auto it = segments.upper_bound({max_x, -1});\n            if (it != segments.begin()) {\n                --it;\n                do {\n                    // Existing segment [it->first, it->second] vs new segment [min_x, max_x].\n                    if (it->second >= min_x && it->first <= max_x) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_x);\n            }\n        }\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // This branch is for 45-degree segments, where |dx| == |dy|.\n        if (abs(dx) != abs(dy)) return false; // Should not happen if shape is valid.\n\n        // Calculate transformed coordinates for the new segment.\n        int u1_new = p1.x + p1.y;\n        int v1_new = p1.x - p1.y;\n        int u2_new = p2.x + p2.y;\n        int v2_new = p2.x - p2.y;\n\n        if (dx == dy) { // New segment is horizontal in (u,v) space (v is constant).\n            int v_const_new = v1_new; // v1_new == v2_new.\n            int min_u_new = min(u1_new, u2_new);\n            int max_u_new = max(u1_new, u2_new);\n\n            auto it_map = uv_v_segments_by_v.find(v_const_new); // Map stores horizontal segments in (u,v).\n            if (it_map != uv_v_segments_by_v.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_u, max_u}.\n                \n                auto it = segments.upper_bound({max_u_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_u_new, max_u_new].\n                        if (it->second >= min_u_new && it->first <= max_u_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_u_new);\n                }\n            }\n        } else { // dx == -dy. New segment is vertical in (u,v) space (u is constant).\n            int u_const_new = u1_new; // u1_new == u2_new.\n            int min_v_new = min(v1_new, v2_new);\n            int max_v_new = max(v1_new, v2_new);\n\n            auto it_map = uv_h_segments_by_u.find(u_const_new); // Map stores vertical segments in (u,v).\n            if (it_map != uv_h_segments_by_u.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_v, max_v}.\n                \n                auto it = segments.upper_bound({max_v_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_v_new, max_v_new].\n                        if (it->second >= min_v_new && it->first <= max_v_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_v_new);\n                }\n            }\n        }\n    }\n    return false; // No overlap found.\n}\n\n\n// Checks if a point 'test_p' lies strictly on the line segment defined by 'seg_p1' and 'seg_p2',\n// excluding the endpoints.\nbool is_point_on_segment_exclusive(Point test_p, Point seg_p1, Point seg_p2) {\n    if (seg_p1 == seg_p2) return false; // Degenerate segment.\n\n    // Check collinearity using the cross product.\n    // (test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) == (test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y)\n    long long cross_product = (long long)(test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) - (long long)(test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y);\n    if (cross_product != 0) return false; // Not collinear.\n\n    // Check if the point lies within the bounding box of the segment.\n    bool on_x = (test_p.x >= min(seg_p1.x, seg_p2.x) && test_p.x <= max(seg_p1.x, seg_p2.x));\n    bool on_y = (test_p.y >= min(seg_p1.y, seg_p2.y) && test_p.y <= max(seg_p1.y, seg_p2.y));\n\n    if (!on_x || !on_y) return false; // Collinear but outside the segment's bounds.\n\n    // Point is collinear and within the bounding box. Now check if it's strictly between the endpoints.\n    // It's strictly between if it's not equal to either endpoint.\n    bool is_endpoint1 = (test_p.x == seg_p1.x && test_p.y == seg_p1.y);\n    bool is_endpoint2 = (test_p.x == seg_p2.x && test_p.y == seg_p2.y);\n    \n    return !(is_endpoint1 || is_endpoint2);\n}\n\n// Checks Condition 2: No dots (other than the rectangle's corners) lie on the perimeter of the proposed rectangle.\n// p1_new is the point where the new dot will be placed.\n// p2_old, p3_old, p4_old are the three existing points that form the rectangle with p1_new.\nbool check_perimeter_dots(Point p1_new, Point p2_old, Point p3_old, Point p4_old, const set<Point>& current_dots) {\n    // Define the four segments of the rectangle.\n    Point segments[4][2] = {{p1_new, p2_old}, {p2_old, p3_old}, {p3_old, p4_old}, {p4_old, p1_new}};\n    \n    // The dots that are allowed to be on the perimeter are the existing corners of the rectangle.\n    set<Point> allowed_on_perimeter = {p2_old, p3_old, p4_old};\n\n    for (auto& seg : segments) {\n        Point seg_p1 = seg[0];\n        Point seg_p2 = seg[1];\n\n        if (seg_p1 == seg_p2) continue; // Skip degenerate segments.\n\n        // Iterate through all currently placed dots.\n        for (const auto& dot : current_dots) {\n            // If the dot is one of the allowed corners, it's fine.\n            if (allowed_on_perimeter.count(dot)) continue;\n            \n            // Check if this dot lies strictly on the current segment.\n            if (is_point_on_segment_exclusive(dot, seg_p1, seg_p2)) {\n                return false; // Found a forbidden dot on the perimeter.\n            }\n        }\n    }\n    return true; // No forbidden dots found on any segment.\n}\n\n// Checks if four points (p1, p2, p3, p4) in order form a valid rectangle.\n// p1 is the potential new dot, and p2, p3, p4 are existing dots.\nbool check_rectangle_shape_and_order(Point p1, Point p2, Point p3, Point p4) {\n    // Calculate vectors for each side.\n    long long dx1 = p2.x - p1.x; // Vector p1->p2\n    long long dy1 = p2.y - p1.y;\n    long long dx2 = p3.x - p2.x; // Vector p2->p3\n    long long dy2 = p3.y - p2.y;\n    long long dx3 = p4.x - p3.x; // Vector p3->p4\n    long long dy3 = p4.y - p3.y;\n    long long dx4 = p1.x - p4.x; // Vector p4->p1\n    long long dy4 = p1.y - p4.y;\n\n    // A rectangle is a parallelogram with perpendicular adjacent sides.\n    // Check if opposite sides are parallel and equal in length:\n    // Vector p1->p2 should be the negation of p3->p4 (or p4->p3).\n    bool side1_matches_side3 = (dx1 == -dx3) && (dy1 == -dy3);\n    // Vector p2->p3 should be the negation of p4->p1 (or p1->p4).\n    bool side2_matches_side4 = (dx2 == -dx4) && (dy2 == -dy4);\n\n    if (!side1_matches_side3 || !side2_matches_side4) {\n        return false; // Not a parallelogram.\n    }\n    \n    // Check if adjacent sides are perpendicular using the dot product.\n    // Dot product of vector p1->p2 and vector p2->p3 must be zero.\n    long long dot_product_12_23 = dx1 * dx2 + dy1 * dy2;\n    \n    if (dot_product_12_23 != 0) {\n        return false; // Adjacent sides are not perpendicular.\n    }\n\n    // All conditions met: it's a rectangle.\n    return true;\n}\n\n// Structure to represent a candidate move (placing a new dot).\nstruct CandidateMove {\n    Point p1_new; // The new dot's coordinates.\n    Point p2_old, p3_old, p4_old; // The three existing dots used to form the rectangle.\n    long long weight_val; // The weight of the new dot (p1_new).\n\n    // For sorting candidates: we want the move that adds the point with the highest weight.\n    bool operator<(const CandidateMove& other) const {\n        return weight_val < other.weight_val; // Ascending for std::sort, so we sort reversed later.\n    }\n};\n\n// Finds all possible valid moves (rectangles that can be drawn).\nvector<CandidateMove> find_candidate_moves(const set<Point>& current_dots) {\n    vector<CandidateMove> candidates;\n    // Convert the set of dots to a vector for easier iteration.\n    vector<Point> dots_vec(current_dots.begin(), current_dots.end());\n\n    // Strategy: Iterate through pairs of existing dots (pa, pb) and check if they can be part of a rectangle.\n\n    // --- Generate Axis-Aligned Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point pa = dots_vec[i];\n            Point pb = dots_vec[j];\n\n            // Case 1: pa and pb share the same y-coordinate (form a horizontal segment).\n            if (pa.y == pb.y) {\n                int y_base = pa.y;\n                int x1 = min(pa.x, pb.x);\n                int x2 = max(pa.x, pb.x);\n                \n                // Search for points on parallel lines y_new = y_base + dy and y_new = y_base - dy.\n                // We search symmetrically outwards from the base segment.\n                for (int dy = 1; ; ++dy) {\n                    // If both upward and downward searches go out of bounds, stop.\n                    if (y_base + dy >= N_val && y_base - dy < 0) break; \n\n                    bool found_upper = false;\n                    Point pc_upper = {-1, -1}, pd_upper = {-1, -1}; // Placeholder for potential points.\n                    // Check for points on the line y_base + dy.\n                    if (y_base + dy < N_val) {\n                        pc_upper = {x1, y_base + dy};\n                        pd_upper = {x2, y_base + dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_upper) && current_dots.count(pd_upper)) {\n                            found_upper = true;\n                        }\n                    }\n\n                    bool found_lower = false;\n                    Point pc_lower = {-1, -1}, pd_lower = {-1, -1};\n                    // Check for points on the line y_base - dy.\n                    if (y_base - dy >= 0) {\n                        pc_lower = {x1, y_base - dy};\n                        pd_lower = {x2, y_base - dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_lower) && current_dots.count(pd_lower)) {\n                            found_lower = true;\n                        }\n                    }\n\n                    // If no points were found in either direction at this distance 'dy',\n                    // and 'dy' has exceeded a reasonable limit (e.g., grid size), stop searching in this direction.\n                    if (!found_upper && !found_lower) {\n                        if (dy > N_val) break; // Heuristic limit to prevent excessive search.\n                        continue; // Continue to the next 'dy' if not out of bounds.\n                    }\n                    \n                    // If we found two points on the upper line (pc_upper, pd_upper):\n                    if (found_upper) {\n                        // Potential rectangle vertices are: (x1, y_base), (x2, y_base), pc_upper, pd_upper.\n                        // We need to find a NEW dot (p_new) and three OLD dots (p2_old, p3_old, p4_old).\n                        // If pc_upper is empty, it can be p_new. The existing dots are pd_upper, pa, pb.\n                        Point p_new = pc_upper;\n                        if (!current_dots.count(p_new)) {\n                            // Try forming the rectangle with p_new and the three existing dots.\n                            // The existing dots for this case are pd_upper, pa, pb.\n                            // Vertices are (x1, y_base), (x2, y_base), (x2, y_base+dy), (x1, y_base+dy).\n                            // Possible pairings for (p2_old, p3_old, p4_old) to form a rectangle with p_new=(x1, y_base+dy):\n                            // 1. (p_new, (x1, y_base), (x2, y_base), (x2, y_base+dy))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_upper)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_upper, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // 2. (p_new, pd_upper, pb, pa) - this order tries to form a rectangle (x1,y_up), (x2,y_up), (x2,y_base), (x1,y_base)\n                            if (current_dots.count(pd_upper) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_upper, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_upper, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_upper, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_upper is empty, it can be p_new. Existing dots: pc_upper, pa, pb.\n                        p_new = pd_upper;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_upper, pa, pb) -> ((x2, y_base+dy), (x1, y_base+dy), (x1, y_base), (x2, y_base))\n                            if (current_dots.count(pc_upper) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_upper, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_upper, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_upper, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pb, pa, pc_upper) -> ((x2, y_base+dy), (x2, y_base), (x1, y_base), (x1, y_base+dy))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_upper)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_upper, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    // If both upper and lower lines had pairs of points, we don't need to search further for this pa, pb pair in 'dy' direction.\n                    if (found_upper && found_lower) break; \n                    // If neither direction yielded points, further 'dy' won't find them either.\n                    if (!found_upper && !found_lower) break;\n                }\n            }\n\n            // Case 2: pa and pb share the same x-coordinate (form a vertical segment).\n            if (pa.x == pb.x) {\n                int x_base = pa.x;\n                int y1 = min(pa.y, pb.y);\n                int y2 = max(pa.y, pb.y);\n\n                // Search for points on parallel lines x_new = x_base + dx and x_new = x_base - dx.\n                for (int dx = 1; ; ++dx) {\n                    if (x_base + dx >= N_val && x_base - dx < 0) break;\n\n                    bool found_right = false;\n                    Point pc_right = {-1, -1}, pd_right = {-1, -1};\n                    // Check for points on the line x_base + dx.\n                    if (x_base + dx < N_val) {\n                        pc_right = {x_base + dx, y1};\n                        pd_right = {x_base + dx, y2};\n                        if (current_dots.count(pc_right) && current_dots.count(pd_right)) {\n                            found_right = true;\n                        }\n                    }\n\n                    bool found_left = false;\n                    Point pc_left = {-1, -1}, pd_left = {-1, -1};\n                    // Check for points on the line x_base - dx.\n                    if (x_base - dx >= 0) {\n                        pc_left = {x_base - dx, y1};\n                        pd_left = {x_base - dx, y2};\n                        if (current_dots.count(pc_left) && current_dots.count(pd_left)) {\n                            found_left = true;\n                        }\n                    }\n\n                    if (!found_right && !found_left) {\n                        if (dx > N_val) break;\n                        continue;\n                    }\n\n                    // If we found two points on the right line (pc_right, pd_right):\n                    if (found_right) {\n                        // Potential rectangle vertices: (x_base, y1), (x_base, y2), pc_right, pd_right.\n                        // Try placing new dot at pc_right. Existing dots are pd_right, pa, pb.\n                        Point p_new = pc_right;\n                        if (!current_dots.count(p_new)) {\n                            // Try (p_new, pa, pb, pd_right) -> ((x_base+dx, y1), (x_base, y1), (x_base, y2), (x_base+dx, y2))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_right)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_right) &&\n                                        !check_segment_overlap(pd_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_right, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pd_right, pb, pa) -> ((x_base+dx, y1), (x_base+dx, y2), (x_base, y2), (x_base, y1))\n                             if (current_dots.count(pd_right) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_right, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_right) &&\n                                        !check_segment_overlap(pd_right, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_right, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_right, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_right is empty, it can be p_new. Existing dots: pc_right, pa, pb.\n                        p_new = pd_right;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_right, pa, pb) -> ((x_base+dx, y2), (x_base+dx, y1), (x_base, y1), (x_base, y2))\n                            if (current_dots.count(pc_right) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_right, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_right) &&\n                                        !check_segment_overlap(pc_right, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_right, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_right, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                             // Try (p_new, pb, pa, pc_right) -> ((x_base+dx, y2), (x_base, y2), (x_base, y1), (x_base+dx, y1))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_right)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_right) &&\n                                        !check_segment_overlap(pc_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_right, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_right && found_left) break;\n                    if (!found_right && !found_left) break;\n                }\n            }\n        }\n    }\n\n    // --- Generate 45-degree Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point p_a = dots_vec[i];\n            Point p_b = dots_vec[j];\n\n            long long dx_ab = p_b.x - p_a.x;\n            long long dy_ab = p_b.y - p_a.y;\n\n            // Check if p_a and p_b could be adjacent vertices of a 45-degree rectangle.\n            // This implies their difference vector (dx_ab, dy_ab) must have |dx_ab| == |dy_ab| and not be zero.\n            if (abs(dx_ab) == abs(dy_ab) && dx_ab != 0) {\n                // The vector for the next side must be perpendicular and have the same length.\n                // Two possibilities for the next vector: (-dy_ab, dx_ab) and (dy_ab, -dx_ab).\n                int possible_v[2][2] = {{- (int)dy_ab, (int)dx_ab}, {(int)dy_ab, - (int)dx_ab}};\n\n                for (int k = 0; k < 2; ++k) {\n                    long long next_dx = possible_v[k][0];\n                    long long next_dy = possible_v[k][1];\n\n                    // Calculate the coordinates of the other two potential vertices of the rectangle.\n                    Point p_c = {p_b.x + (int)next_dx, p_b.y + (int)next_dy}; // p_c = p_b + next_vector\n                    Point p_d = {p_a.x + (int)next_dx, p_a.y + (int)next_dy}; // p_d = p_a + next_vector\n\n                    // Check if these potential points are within grid bounds.\n                    if (p_c.x >= 0 && p_c.x < N_val && p_c.y >= 0 && p_c.y < N_val &&\n                        p_d.x >= 0 && p_d.x < N_val && p_d.y >= 0 && p_d.y < N_val) {\n                        \n                        // If both p_c and p_d already exist as dots:\n                        if (current_dots.count(p_c) && current_dots.count(p_d)) {\n                            // We've found a rectangle formed by p_a, p_b, p_c, p_d.\n                            // A new dot can be placed at any of these vertices if it's currently empty.\n                            // We need to find an empty point (p_new) and three existing points (p2, p3, p4).\n\n                            // Case 1: p_a is the new dot (p_new). p_b, p_c, p_d must be existing dots.\n                            Point p_new = p_a;\n                            if (!current_dots.count(p_new)) { // Check if p_a is empty.\n                                // Order: (p_new, p_b, p_c, p_d) where p_b is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_b, p_c, p_d)) {\n                                    // Check for segment overlaps and perimeter dots.\n                                    if (!check_segment_overlap(p_new, p_b) &&\n                                        !check_segment_overlap(p_b, p_c) &&\n                                        !check_segment_overlap(p_c, p_d) &&\n                                        !check_segment_overlap(p_d, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_b, p_c, p_d, current_dots)) {\n                                            candidates.push_back({p_new, p_b, p_c, p_d, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 2: p_b is the new dot (p_new). p_a, p_c, p_d must be existing dots.\n                            p_new = p_b;\n                            if (!current_dots.count(p_new)) { // Check if p_b is empty.\n                                // Order: (p_new, p_a, p_d, p_c) where p_a is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_a, p_d, p_c)) {\n                                    if (!check_segment_overlap(p_new, p_a) &&\n                                        !check_segment_overlap(p_a, p_d) &&\n                                        !check_segment_overlap(p_d, p_c) &&\n                                        !check_segment_overlap(p_c, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_a, p_d, p_c, current_dots)) {\n                                            candidates.push_back({p_new, p_a, p_d, p_c, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 3: p_c is the new dot (p_new). p_a, p_b, p_d must be existing dots.\n                            p_new = p_c;\n                            if (!current_dots.count(p_new)) { // Check if p_c is empty.\n                                // Order: (p_new, p_d, p_a, p_b) where p_d is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_d, p_a, p_b)) {\n                                    if (!check_segment_overlap(p_new, p_d) &&\n                                        !check_segment_overlap(p_d, p_a) &&\n                                        !check_segment_overlap(p_a, p_b) &&\n                                        !check_segment_overlap(p_b, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_d, p_a, p_b, current_dots)) {\n                                            candidates.push_back({p_new, p_d, p_a, p_b, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 4: p_d is the new dot (p_new). p_a, p_b, p_c must be existing dots.\n                            p_new = p_d;\n                            if (!current_dots.count(p_new)) { // Check if p_d is empty.\n                                // Order: (p_new, p_c, p_b, p_a) where p_c is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_c, p_b, p_a)) {\n                                    if (!check_segment_overlap(p_new, p_c) &&\n                                        !check_segment_overlap(p_c, p_b) &&\n                                        !check_segment_overlap(p_b, p_a) &&\n                                        !check_segment_overlap(p_a, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_c, p_b, p_a, current_dots)) {\n                                            candidates.push_back({p_new, p_c, p_b, p_a, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M; // Number of initially placed dots.\n    cin >> N_val >> M;\n\n    // Calculate grid center coordinates. N is always odd.\n    center = {(int)(N_val - 1) / 2, (int)(N_val - 1) / 2};\n    total_weight_sum_val = 0; // Initialize total weight sum.\n\n    // Store the initial dots.\n    set<Point> current_dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        current_dots.insert({x, y});\n        total_weight_sum_val += weight({x, y}); // Add weight of initial dots.\n    }\n\n    // Store the operations performed.\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    int ops_count = 0;\n    // Game loop: continue as long as possible and within the operation limit.\n    while (ops_count < MAX_OPS) {\n        // Find all possible moves.\n        vector<CandidateMove> candidates = find_candidate_moves(current_dots);\n\n        // If no more moves can be made, break the loop.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates in descending order of weight (using reverse iterators on ascending sort).\n        sort(candidates.rbegin(), candidates.rend());\n\n        // Select the best move: the one with the highest weight for the new dot.\n        const auto& best_move = candidates[0];\n\n        // Apply the best move: add the new dot and update total weight.\n        current_dots.insert(best_move.p1_new);\n        total_weight_sum_val += best_move.weight_val;\n        ops_count++;\n\n        // Record the operation details.\n        operations.emplace_back(best_move.p1_new.x, best_move.p1_new.y,\n                                best_move.p2_old.x, best_move.p2_old.y,\n                                best_move.p3_old.x, best_move.p3_old.y,\n                                best_move.p4_old.x, best_move.p4_old.y);\n\n        // Add the segments of the newly drawn rectangle to the tracking maps.\n        add_segment(best_move.p1_new, best_move.p2_old);\n        add_segment(best_move.p2_old, best_move.p3_old);\n        add_segment(best_move.p3_old, best_move.p4_old);\n        add_segment(best_move.p4_old, best_move.p1_new);\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output the details of each operation.\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) << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int SIZE = 10;\nint board[SIZE][SIZE]; // 0 for empty, 1, 2, 3 for flavors\n\n// Helper to find the p_t-th empty cell\npair<int, int> find_empty_cell(int p_t) {\n    int empty_count = 0;\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            if (board[r][c] == 0) {\n                empty_count++;\n                if (empty_count == p_t) {\n                    return {r, c};\n                }\n            }\n        }\n    }\n    return {-1, -1}; // Should not happen\n}\n\n// Helper to apply a tilt and update the board\nvoid apply_tilt(char dir) {\n    if (dir == 'F') { // Move down\n        for (int col = 0; col < SIZE; ++col) {\n            vector<pair<int, int>> occupied_cells; // {original_row, flavor}\n            for (int row = 0; row < SIZE; ++row) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({row, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[SIZE - 1 - (k - 1 - i)][col] = occupied_cells[i].second;\n            }\n            for (int row = 0; row < SIZE - k; ++row) {\n                board[row][col] = 0;\n            }\n        }\n    } else if (dir == 'B') { // Move up\n        for (int col = 0; col < SIZE; ++col) {\n            vector<pair<int, int>> occupied_cells; // {original_row, flavor}\n            for (int row = 0; row < SIZE; ++row) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({row, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[i][col] = occupied_cells[i].second;\n            }\n            for (int row = k; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n        }\n    } else if (dir == 'R') { // Move right\n        for (int row = 0; row < SIZE; ++row) {\n            vector<pair<int, int>> occupied_cells; // {original_col, flavor}\n            for (int col = 0; col < SIZE; ++col) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({col, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][SIZE - 1 - (k - 1 - i)] = occupied_cells[i].second;\n            }\n            for (int col = 0; col < SIZE - k; ++col) {\n                board[row][col] = 0;\n            }\n        }\n    } else { // dir == 'L', Move left\n        for (int row = 0; row < SIZE; ++row) {\n            vector<pair<int, int>> occupied_cells; // {original_col, flavor}\n            for (int col = 0; col < SIZE; ++col) {\n                if (board[row][col] != 0) {\n                    occupied_cells.push_back({col, board[row][col]});\n                }\n            }\n            sort(occupied_cells.begin(), occupied_cells.end());\n\n            int k = occupied_cells.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][i] = occupied_cells[i].second;\n            }\n            for (int col = k; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    vector<int> f(101);\n    for (int i = 1; i <= 100; ++i) {\n        cin >> f[i];\n    }\n\n    for (int i = 0; i < SIZE; ++i) {\n        for (int j = 0; j < SIZE; ++j) {\n            board[i][j] = 0;\n        }\n    }\n\n    for (int t = 1; t <= 100; ++t) {\n        int p_t;\n        cin >> p_t;\n\n        pair<int, int> cell = find_empty_cell(p_t);\n        int current_r = cell.first;\n        int current_c = cell.second;\n        board[current_r][current_c] = f[t];\n\n        if (t == 100) {\n            // No output for the 100th tilt as per problem statement\n            continue;\n        }\n\n        char best_tilt = 'F';\n        int min_final_dist = 1000; // Larger than any possible Manhattan distance\n\n        for (char tilt_dir : {'F', 'B', 'L', 'R'}) {\n            int sim_r_final = -1, sim_c_final = -1;\n\n            if (tilt_dir == 'F') { // Move down\n                vector<pair<int, int>> occupied_in_col; // {original_row, flavor}\n                for (int row = 0; row < SIZE; ++row) {\n                    if (board[row][current_c] != 0) {\n                        occupied_in_col.push_back({row, board[row][current_c]});\n                    }\n                }\n                sort(occupied_in_col.begin(), occupied_in_col.end());\n\n                int k = occupied_in_col.size();\n                sim_c_final = current_c; // Column doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_row = occupied_in_col[i].first;\n                    int new_row = SIZE - 1 - (k - 1 - i); // Packed to the bottom\n                    if (original_row == current_r) {\n                        sim_r_final = new_row;\n                    }\n                }\n            } else if (tilt_dir == 'B') { // Move up\n                vector<pair<int, int>> occupied_in_col; // {original_row, flavor}\n                for (int row = 0; row < SIZE; ++row) {\n                    if (board[row][current_c] != 0) {\n                        occupied_in_col.push_back({row, board[row][current_c]});\n                    }\n                }\n                sort(occupied_in_col.begin(), occupied_in_col.end());\n\n                int k = occupied_in_col.size();\n                sim_c_final = current_c; // Column doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_row = occupied_in_col[i].first;\n                    int new_row = i; // Packed to the top\n                    if (original_row == current_r) {\n                        sim_r_final = new_row;\n                    }\n                }\n            } else if (tilt_dir == 'R') { // Move right\n                vector<pair<int, int>> occupied_in_row; // {original_col, flavor}\n                for (int col = 0; col < SIZE; ++col) {\n                    if (board[current_r][col] != 0) {\n                        occupied_in_row.push_back({col, board[current_r][col]});\n                    }\n                }\n                sort(occupied_in_row.begin(), occupied_in_row.end());\n\n                int k = occupied_in_row.size();\n                sim_r_final = current_r; // Row doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_col = occupied_in_row[i].first;\n                    int new_col = SIZE - 1 - (k - 1 - i); // Packed to the right\n                    if (original_col == current_c) {\n                        sim_c_final = new_col;\n                    }\n                }\n            } else { // tilt_dir == 'L', Move left\n                vector<pair<int, int>> occupied_in_row; // {original_col, flavor}\n                for (int col = 0; col < SIZE; ++col) {\n                    if (board[current_r][col] != 0) {\n                        occupied_in_row.push_back({col, board[current_r][col]});\n                    }\n                }\n                sort(occupied_in_row.begin(), occupied_in_row.end());\n\n                int k = occupied_in_row.size();\n                sim_r_final = current_r; // Row doesn't change\n                for (int i = 0; i < k; ++i) {\n                    int original_col = occupied_in_row[i].first;\n                    int new_col = i; // Packed to the left\n                    if (original_col == current_c) {\n                        sim_c_final = new_col;\n                    }\n                }\n            }\n\n            // Calculate min distance from (sim_r_final, sim_c_final) to same flavored candies\n            int current_min_dist = 1000;\n            bool found_other_candy = false;\n            for (int r_other = 0; r_other < SIZE; ++r_other) {\n                for (int c_other = 0; c_other < SIZE; ++c_other) {\n                    // Check if it's a candy of the same flavor AND it's NOT the one we just placed\n                    if (board[r_other][c_other] == f[t] && !(r_other == current_r && c_other == current_c)) {\n                        found_other_candy = true;\n                        int dist = abs(sim_r_final - r_other) + abs(sim_c_final - c_other);\n                        current_min_dist = min(current_min_dist, dist);\n                    }\n                }\n            }\n            \n            // If current_min_dist is still 1000, it means there are no other candies of the same flavor.\n            // In this case, any tilt is equally \"good\" in terms of distance.\n            // The tie-breaking logic below will handle this.\n\n            if (current_min_dist < min_final_dist) {\n                min_final_dist = current_min_dist;\n                best_tilt = tilt_dir;\n            } else if (current_min_dist == min_final_dist) {\n                // Tie-breaking: F < B < L < R\n                // The loop order {'F', 'B', 'L', 'R'} naturally implements this.\n                // If a new direction gives the same min distance, we do NOT update `best_tilt`.\n                // Thus, the first direction encountered that achieved `min_final_dist` is kept.\n            }\n        }\n\n        apply_tilt(best_tilt);\n        cout << best_tilt << endl;\n        cout << flush;\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\n// Function to convert an adjacency matrix to its bitstring representation.\n// The order of edges in the string is lexicographical by (i, j) pairs where i < j.\nstd::string adj_matrix_to_string(int N, const std::vector<std::vector<bool>>& adj) {\n    std::string s = \"\";\n    s.reserve(N * (N - 1) / 2); // Pre-allocate memory for efficiency\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Function to compute the degree sequence of a graph from its bitstring representation.\n// The degree sequence is returned as a vector of integers.\nstd::vector<int> get_degrees_from_string(int N, const std::string& s) {\n    std::vector<int> degrees(N, 0); // Initialize degrees for all vertices to 0\n    int k = 0; // Index for iterating through the bitstring\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (s[k] == '1') { // If an edge exists between vertex i and vertex j\n                degrees[i]++; // Increment degree of vertex i\n                degrees[j]++; // Increment degree of vertex j\n            }\n            k++; // Move to the next character in the bitstring\n        }\n    }\n    // The degree sequence comparison uses the canonical degree sequence of G_i,\n    // which is stored in precomputed_degrees. We do NOT sort degrees_H here,\n    // as we compare it against the specific, non-sorted degree sequences of G_i.\n    return degrees;\n}\n\nint main() {\n    // Fast I/O operations\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    std::cin >> M >> epsilon;\n\n    // Heuristic choice for N:\n    // The score formula round(10^9 * 0.9^E / N) implies a smaller N is better for the score multiplier (1/N).\n    // However, N must be large enough to create M distinct graphs that are robust to noise and vertex shuffling.\n    // The total number of possible edges in an N-vertex graph is N*(N-1)/2.\n    // To distinguish M graphs using edge counts as a primary feature, we need N*(N-1)/2 >= M-1.\n    // For M=100, this implies N=15 (since 14*13/2=91 and 15*14/2=105).\n    // Given epsilon can be up to 0.4, relying solely on edge counts might be insufficient.\n    // N=20 provides 190 edges, offering more structural diversity and thus better distinguishability.\n    // It balances the 1/N score factor (1/20) with sufficient edge capacity for M=100 graphs.\n    // N=20 is within the problem's constraint [4, 100].\n    int N = 20; \n\n    // Store precomputed degree sequences for G_0, ..., G_{M-1}.\n    // This allows for quick comparison during query processing.\n    std::vector<std::vector<int>> precomputed_degrees(M, std::vector<int>(N));\n    // Store the string representations of G_0, ..., G_{M-1} for output.\n    std::vector<std::string> graph_strings(M);\n\n    // Seed the random number generator for graph generation.\n    // Using a fixed seed (0) ensures that the generated graphs are identical\n    // across different runs for the same M and epsilon values, which is crucial for reproducibility.\n    std::mt19937 rng(0); \n\n    // Maximum possible edges in an N-vertex graph.\n    int max_possible_edges = N * (N - 1) / 2;\n\n    // Generate M distinct graphs.\n    for (int i = 0; i < M; ++i) {\n        // Generate graphs with edge counts spaced out to maximize distinguishability.\n        // The i-th graph (0-indexed) will have approximately i * (max_edges / (M-1)) edges.\n        // This strategy spreads the edge counts evenly from 0 up to max_possible_edges.\n        // Since M >= 10, M-1 is at least 9, so division by zero is avoided.\n        int target_edges = static_cast<int>(static_cast<double>(i) * max_possible_edges / (M - 1));\n        \n        // Ensure target_edges is within valid bounds [0, max_possible_edges].\n        // This is a safeguard against potential floating-point inaccuracies or edge cases.\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n\n        // Initialize an adjacency matrix for the graph G_i.\n        std::vector<std::vector<bool>> adj(N, std::vector<bool>(N, false));\n        int edges_added = 0;\n\n        // Add exactly target_edges randomly to the graph G_i.\n        // This loop picks random pairs of vertices and adds an edge if it doesn't exist,\n        // until the target number of edges is reached.\n        // For N=20, this approach is efficient enough.\n        if (target_edges > 0) {\n            while (edges_added < target_edges) {\n                int u = rng() % N; // Pick a random vertex u\n                int v = rng() % N; // Pick a random vertex v\n                if (u == v) continue; // Avoid self-loops\n                if (u > v) std::swap(u, v); // Ensure consistent ordering (u < v) for edge representation\n                \n                if (!adj[u][v]) { // If the edge (u,v) does not exist yet\n                    adj[u][v] = adj[v][u] = true; // Add the edge (undirected)\n                    edges_added++; // Increment the count of added edges\n                }\n            }\n        }\n        \n        // Convert the constructed adjacency matrix to the required string format.\n        graph_strings[i] = adj_matrix_to_string(N, adj);\n        // Compute and store the degree sequence for this graph G_i.\n        precomputed_degrees[i] = get_degrees_from_string(N, graph_strings[i]);\n    }\n\n    // Output N, followed by the string representations of the M generated graphs.\n    std::cout << N << std::endl;\n    for (int i = 0; i < M; ++i) {\n        std::cout << graph_strings[i] << std::endl;\n    }\n    // Flush the output buffer to ensure all generated graph data is sent to the judge.\n    std::cout << std::flush; \n\n    // Process the 100 queries.\n    for (int k = 0; k < 100; ++k) {\n        std::string H_str; // The graph string received for the current query H_k.\n        std::cin >> H_str;\n\n        // Compute the degree sequence of the received graph H_k.\n        std::vector<int> degrees_H = get_degrees_from_string(N, H_str);\n\n        int best_match_idx = -1; // Stores the index of the best matching G_i found so far.\n        // Initialize min_dist to a value larger than any possible L1 distance.\n        // For N=20, the maximum L1 distance is N*(N-1) = 20*19 = 380.\n        // Using -1 as a flag indicates that no comparison has been made yet.\n        long long min_dist = -1; \n\n        // Find which precomputed graph G_i has a degree sequence 'closest' to H_k's degree sequence.\n        // Closeness is measured by the L1 distance.\n        for (int i = 0; i < M; ++i) {\n            long long current_dist = 0; // L1 distance for G_i.\n            for (int j = 0; j < N; ++j) {\n                // Sum of absolute differences in degrees between H_k and G_i for each vertex.\n                current_dist += std::abs(degrees_H[j] - precomputed_degrees[i][j]);\n            }\n\n            // If this is the first graph considered (best_match_idx == -1), or\n            // if the current graph G_i is closer to H_k than the current best match,\n            // update the best match.\n            if (best_match_idx == -1 || current_dist < min_dist) {\n                min_dist = current_dist;\n                best_match_idx = i;\n            }\n        }\n        \n        // Output the predicted index t_k. This is the index of the graph G_i\n        // that H_k is most likely generated from based on degree sequence similarity.\n        std::cout << best_match_idx << std::endl;\n        // Flush the output buffer to ensure the prediction is sent immediately.\n        std::cout << std::flush; \n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Use a large value for infinity, greater than any possible shortest path sum.\n// Max path length can be approximately N * max_w = 1000 * 10^6 = 10^9.\n// The problem uses 10^9 for unreachable distances. Our internal INF must be larger\n// to correctly identify unreachable nodes in Dijkstra's algorithm.\nconst long long INF = 4e15; \n\n// Structure to represent an edge in the graph.\nstruct Edge {\n    int u, v, w, id;       // Endpoints, weight, and original index of the edge.\n    long long dist_uv;     // Shortest path distance between u and v in the original graph.\n    int assignment;        // The day this edge is scheduled for repair.\n};\n\n// Structure for Dijkstra's priority queue: stores distance and vertex.\nstruct State {\n    long long dist;\n    int vertex;\n\n    // For priority_queue: sort by distance (min-heap).\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\n// Dijkstra's algorithm to find shortest paths from a single source vertex.\n// It returns a vector containing the shortest distance from start_node to every other node.\n// Time complexity: O(M log N) or O(M + N log N) depending on priority queue implementation.\nvector<long long> dijkstra(int start_node, int n, const vector<vector<pair<int, int>>>& adj) {\n    vector<long long> dist(n + 1, INF); // Initialize distances to infinity.\n    dist[start_node] = 0;               // Distance from source to itself is 0.\n    priority_queue<State, vector<State>, greater<State>> pq;\n    pq.push({0, start_node});\n\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        long long d = current.dist;\n        int v = current.vertex;\n\n        // If we found a shorter path to 'v' already, skip this one.\n        if (d > dist[v]) {\n            continue;\n        }\n\n        // Explore neighbors of vertex 'v'.\n        for (auto& edge_info : adj[v]) {\n            int neighbor = edge_info.first;\n            int weight = edge_info.second;\n            \n            // Relaxation step: If a shorter path to 'neighbor' is found through 'v'.\n            // Check for overflow before addition. If dist[v] is INF, dist[v] + weight will be larger than any finite path or INF, so this condition handles INF correctly.\n            if (dist[v] != INF && dist[v] + weight < dist[neighbor]) {\n                dist[neighbor] = dist[v] + weight;\n                pq.push({dist[neighbor], neighbor});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, d_days, k_limit;\n    cin >> n >> m >> d_days >> k_limit;\n\n    // Adjacency list for graph: vector of vectors of pairs {neighbor, weight}.\n    // Vertices are 1-indexed in input, so we use size n+1 for 1-based indexing.\n    vector<vector<pair<int, int>>> adj(n + 1);\n    vector<Edge> edges;\n    edges.reserve(m); // Pre-allocate memory for edges.\n\n    // Read edges and build the adjacency list.\n    for (int i = 0; i < m; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w}); // Graph is undirected.\n        // Store edge details including its original index 'i' (0 to m-1).\n        edges.push_back({u, v, w, i, 0, 0});\n    }\n\n    // Step 1: Compute all-pairs shortest paths (APSP).\n    // This is done by running Dijkstra from each vertex.\n    // For N=1000, M=3000, complexity O(N*(M+N log N)) is feasible.\n    vector<vector<long long>> dist_matrix(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        dist_matrix[i] = dijkstra(i, n, adj);\n    }\n\n    // Step 2: For each edge, calculate the shortest path distance between its endpoints.\n    // This 'dist_uv' value is used as a heuristic: edges connecting vertices that are far apart\n    // in the graph (large shortest path distance) are considered more critical to the network's structure.\n    for (auto& edge : edges) {\n        edge.dist_uv = dist_matrix[edge.u][edge.v];\n        // The problem guarantees the graph is 2-edge-connected, implying it is connected.\n        // Therefore, dist_matrix[edge.u][edge.v] will always be a finite value (not INF).\n    }\n\n    // Step 3: Sort edges based on heuristics to decide the order of repair.\n    // Heuristic: Prioritize edges connecting vertices that are far apart (large dist_uv).\n    // If dist_uv is equal, prioritize heavier edges (large w).\n    // This strategy aims to group critical \"arteries\" (long-span, heavy edges) together on the same day.\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        if (a.dist_uv != b.dist_uv) {\n            return a.dist_uv > b.dist_uv; // Sort by dist_uv descending: edges spanning larger distances first.\n        }\n        // Tie-breaker: if dist_uv is the same, sort by weight descending.\n        // This prioritizes heavier edges among those connecting distant nodes.\n        return a.w > b.w; \n    });\n\n    // Step 4: Assign edges to days using a round-robin approach for better balance.\n    // Instead of assigning the top K edges to day 1, then the next K to day 2, etc.,\n    // we distribute the top-ranked edges evenly across all days.\n    vector<int> assignments(m); // To store the day assignment for each edge, indexed by its original ID.\n    \n    for (int i = 0; i < m; ++i) {\n        // Assign the i-th edge in the sorted list to day (i % d_days) + 1.\n        // This ensures that critical edges are spread out over the D days.\n        // The constraint K > ceil(M/D) guarantees that each day will receive at most ceil(M/D) edges, which is <= K.\n        int assigned_day = (i % d_days) + 1;\n        edges[i].assignment = assigned_day;\n        assignments[edges[i].id] = assigned_day;\n    }\n\n    // Step 5: Output the assignments for each edge in the order they appeared in the input.\n    for (int i = 0; i < m; ++i) {\n        cout << assignments[i] << (i == m - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\n// Grid index helpers\n#define GRID_IDX(x, y, z, D) ((x) * (D) * (D) + (y) * (D) + (z))\n\n// Grid access macros\n#define GRID_GET(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n#define GRID_WRITE(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n\n// Polycube representation\nstruct Polycube {\n    vector<tuple<int, int, int>> cells;\n\n    // Custom comparison for Polycube, used for std::map keys\n    bool operator<(const Polycube& other) const {\n        return cells < other.cells;\n    }\n    bool operator==(const Polycube& other) const {\n        return cells == other.cells;\n    }\n    int volume() const { return cells.size(); }\n};\n\n// Global parameters\nint D;\nvector<string> f1_str, r1_str, f2_str, r2_str;\nvector<bool> G1_grid, G2_grid; // G1_grid[idx] is true if cell can be occupied for obj1\n\n// Helper to create a 3D grid vector\ntemplate<typename T>\nvector<T> create_grid_vec(size_t size, T default_val) {\n    return vector<T>(size, default_val);\n}\n\n// Convert string silhouettes to boolean grids representing valid cell locations\nvoid setup_grids() {\n    G1_grid.assign(D * D * D, false);\n    G2_grid.assign(D * D * D, false);\n\n    // For object 1, a cell (x,y,z) can be occupied if f1(z,x)=1 and r1(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int x = 0; x < D; ++x) {\n            if (f1_str[z][x] == '1') {\n                for (int y = 0; y < D; ++y) {\n                    if (r1_str[z][y] == '1') {\n                        GRID_GET(G1_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // For object 2, a cell (x,y,z) can be occupied if f2(z,x)=1 and r2(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int y = 0; y < D; ++y) {\n            if (r2_str[z][y] == '1') {\n                for (int x = 0; x < D; ++x) {\n                    if (f2_str[z][x] == '1') {\n                        GRID_GET(G2_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalize a polycube: translate its cells so the minimum coordinate is (0,0,0)\n// and sort the cells lexicographically. This gives a canonical representation for translation.\nPolycube normalize(const Polycube& poly) {\n    if (poly.cells.empty()) return poly;\n    int min_x = get<0>(poly.cells[0]);\n    int min_y = get<1>(poly.cells[0]);\n    int min_z = get<2>(poly.cells[0]);\n    for (const auto& cell : poly.cells) {\n        min_x = min(min_x, get<0>(cell));\n        min_y = min(min_y, get<1>(cell));\n        min_z = min(min_z, get<2>(cell));\n    }\n    Polycube normalized_poly;\n    normalized_poly.cells.reserve(poly.cells.size());\n    for (const auto& cell : poly.cells) {\n        normalized_poly.cells.emplace_back(get<0>(cell) - min_x, get<1>(cell) - min_y, get<2>(cell) - min_z);\n    }\n    sort(normalized_poly.cells.begin(), normalized_poly.cells.end());\n    return normalized_poly;\n}\n\n// Generate all 24 unique orientations (rotations) of a polycube\nvector<Polycube> get_orientations(const Polycube& poly) {\n    set<Polycube> unique_orientations;\n    \n    vector<tuple<int,int,int>> current_cells = poly.cells;\n\n    // Apply rotations around X, Y, Z axes\n    // Loop 4 times for each axis to cover 0, 90, 180, 270 degrees\n    for (int rotx = 0; rotx < 4; ++rotx) { // Rotations around X-axis\n        vector<tuple<int,int,int>> current_cells_y = current_cells;\n        for (int roty = 0; roty < 4; ++roty) { // Rotations around Y-axis\n            vector<tuple<int,int,int>> current_cells_z = current_cells_y;\n            for (int rotz = 0; rotz < 4; ++rotz) { // Rotations around Z-axis\n                Polycube oriented_poly;\n                oriented_poly.cells = current_cells_z;\n                unique_orientations.insert(normalize(oriented_poly));\n                \n                // Rotate around Z: (x, y, z) -> (-y, x, z)\n                vector<tuple<int,int,int>> next_z;\n                next_z.reserve(current_cells_z.size());\n                for(const auto& cell : current_cells_z) {\n                    next_z.emplace_back(-get<1>(cell), get<0>(cell), get<2>(cell));\n                }\n                current_cells_z = next_z;\n            }\n            // Rotate around Y: (x, y, z) -> (z, y, -x)\n            vector<tuple<int,int,int>> next_y;\n            next_y.reserve(current_cells_y.size());\n            for(const auto& cell : current_cells_y) {\n                next_y.emplace_back(get<2>(cell), get<1>(cell), -get<0>(cell));\n            }\n            current_cells_y = next_y;\n        }\n        // Rotate around X: (x, y, z) -> (x, -z, y)\n        vector<tuple<int,int,int>> next_x;\n        next_x.reserve(current_cells.size());\n        for(const auto& cell : current_cells) {\n            next_x.emplace_back(get<0>(cell), -get<2>(cell), get<1>(cell));\n        }\n        current_cells = next_x;\n    }\n\n    vector<Polycube> orientations;\n    orientations.reserve(unique_orientations.size());\n    for (const auto& p : unique_orientations) {\n        orientations.push_back(p);\n    }\n    return orientations;\n}\n\n// Map to store canonical form of a polycube to its assigned unique ID\nmap<Polycube, int> canonical_shape_to_id;\nint next_block_id; // Counter for assigning new block IDs\n\n// Store final block assignments for each object\nstruct BlockAssignment {\n    int id;\n    Polycube shape;\n};\nvector<BlockAssignment> assignments1, assignments2;\n\n// Utility to check if a cell coordinate is within the DxD D grid bounds\nbool is_valid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n    \n// Attempt to place a given block_shape at (target_x, target_y, target_z)\n// The target cell must be uncovered and valid for the current object.\n// Returns true if a valid placement is found, false otherwise.\n// placed_block_out will contain the normalized, placed polycube if successful.\nbool try_place(const Polycube& block_shape, int target_x, int target_y, int target_z,\n               const vector<bool>& G, // Grid indicating valid cell locations\n               const vector<bool>& covered, // Grid indicating already occupied cells\n               Polycube& placed_block_out) {\n\n    // Iterate through each cell of the block_shape. Try to align this cell with (target_x, target_y, target_z).\n    // This determines the potential origin of the block if it were placed.\n    for (const auto& cell_in_shape : block_shape.cells) {\n        int shape_cell_x, shape_cell_y, shape_cell_z;\n        tie(shape_cell_x, shape_cell_y, shape_cell_z) = cell_in_shape;\n\n        // Calculate the potential origin of the block in the grid\n        int origin_x = target_x - shape_cell_x;\n        int origin_y = target_y - shape_cell_y;\n        int origin_z = target_z - shape_cell_z;\n\n        Polycube current_placement_poly;\n        bool possible = true;\n\n        // Check if all cells of the block, when placed at this origin, are valid\n        for (const auto& cell_in_shape_ : block_shape.cells) {\n            int cx, cy, cz;\n            tie(cx, cy, cz) = cell_in_shape_;\n            int px = origin_x + cx;\n            int py = origin_y + cy;\n            int pz = origin_z + cz;\n\n            // Check boundaries, if cell is allowed by G, and if it's not already covered\n            if (!is_valid(px, py, pz) || !GRID_GET(G, px, py, pz, D) || GRID_GET(covered, px, py, pz, D)) {\n                possible = false;\n                break;\n            }\n            current_placement_poly.cells.emplace_back(px, py, pz);\n        }\n\n        if (possible) {\n            // Found a valid placement. Normalize it and return.\n            placed_block_out = normalize(current_placement_poly);\n            return true;\n        }\n    }\n    return false; // No valid placement found for this block shape at this target cell\n}\n\n// Greedily fill the target grid G with blocks from the library.\n// Prioritizes larger blocks.\nvoid fill_object(const vector<bool>& G,\n                 vector<bool>& covered,\n                 vector<BlockAssignment>& assignments,\n                 bool is_object1) {\n\n    // Library of candidate block shapes with their volumes.\n    // These are basic polycubes. More complex ones could be generated from components of G.\n    vector<pair<int, Polycube>> candidate_blocks_with_vol; // volume, shape\n    \n    // Basic shapes (monomino, domino, trominoes, tetrominoes)\n    candidate_blocks_with_vol.push_back({1, {{{0,0,0}}}}); // Monomino\n    candidate_blocks_with_vol.push_back({2, {{{0,0,0}, {1,0,0}}}}); // Domino (linear)\n    candidate_blocks_with_vol.push_back({3, {{{0,0,0}, {1,0,0}, {2,0,0}}}}); // Tromino (linear)\n    candidate_blocks_with_vol.push_back({3, {{{0,0,0}, {1,0,0}, {0,1,0}}}}); // Tromino (L)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}}}}); // Tetromino (square)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {3,0,0}}}}); // Tetromino (linear I)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}}}}); // Tetromino (linear I vertical)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {1,1,0}}}}); // Tetromino (T)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {2,0,0}, {2,1,0}}}}); // Tetromino (L)\n    candidate_blocks_with_vol.push_back({4, {{{0,0,0}, {1,0,0}, {1,1,0}, {2,1,0}}}}); // Tetromino (skew)\n    // Add more shapes if needed (e.g., pentominoes)\n\n    // TODO: Optionally, generate connected components from G and add their shapes to candidate_blocks_with_vol.\n    // This part is omitted for simplicity in this example, focusing on a fixed library.\n\n    // Sort candidate blocks by volume in descending order to prioritize larger blocks\n    sort(candidate_blocks_with_vol.rbegin(), candidate_blocks_with_vol.rend());\n\n    // Pre-calculate all orientations for each library block shape\n    vector<pair<int, vector<Polycube>>> library_orientations; // volume, list of orientations\n    for(auto const& [vol, shape] : candidate_blocks_with_vol) {\n        library_orientations.push_back({vol, get_orientations(shape)});\n    }\n\n    // Iterate through all cells of the grid. If a cell must be filled (in G) and is not yet covered:\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 (GRID_GET(G, x, y, z, D) && !GRID_GET(covered, x, y, z, D)) {\n                    // Found an uncovered cell that must be filled\n                    \n                    bool placed_best_block_this_turn = false;\n                    Polycube best_placed_shape; // The actual placed shape in the grid\n                    int best_block_id = -1;\n                    int max_volume_placed = -1; // Track the volume of the best block placed for this cell\n\n                    // Try to place the largest possible block from the library that fits\n                    for (const auto& lib_item : library_orientations) {\n                        int current_vol = lib_item.first;\n                        const vector<Polycube>& orientations = lib_item.second;\n                        \n                        // Optimization: If the current block's volume is less than or equal to the best one\n                        // already found for this cell, we can skip it.\n                        if (placed_best_block_this_turn && current_vol <= max_volume_placed) continue;\n\n                        for (const auto& oriented_shape : orientations) {\n                            Polycube placed_block;\n                            \n                            // Attempt to place the oriented shape to cover (x,y,z)\n                            if (try_place(oriented_shape, x, y, z, G, covered, placed_block)) {\n                                \n                                // If placement is successful, get its canonical form to check for shared blocks\n                                Polycube canonical_shape = normalize(placed_block);\n                                int current_id;\n\n                                // Assign an existing ID if this shape has been used before, otherwise assign a new one\n                                if (canonical_shape_to_id.count(canonical_shape)) {\n                                    current_id = canonical_shape_to_id[canonical_shape];\n                                } else {\n                                    current_id = next_block_id++;\n                                    canonical_shape_to_id[canonical_shape] = current_id;\n                                }\n\n                                // Update the best placement found for this cell if this block is larger\n                                if (!placed_best_block_this_turn || current_vol > max_volume_placed) {\n                                    best_placed_shape = placed_block;\n                                    best_block_id = current_id;\n                                    max_volume_placed = current_vol;\n                                    placed_best_block_this_turn = true;\n                                }\n                            }\n                        }\n                    }\n\n                    // If a block was successfully placed, apply it to the grid and assignments\n                    if (placed_best_block_this_turn) {\n                        assignments.push_back({best_block_id, best_placed_shape});\n                        // Mark all cells occupied by this block as covered\n                        for (const auto& cell : best_placed_shape.cells) {\n                            GRID_GET(covered, get<0>(cell), get<1>(cell), get<2>(cell), D) = true;\n                        }\n                    } else {\n                        // Fallback: If no block from the library could be placed, use a 1x1x1 unit block.\n                        Polycube unit_block = {{{0,0,0}}}; // A single cell at relative (0,0,0)\n                        Polycube canonical_unit = normalize(unit_block);\n                        int current_id;\n                        // Assign ID for unit block (it will be a new ID if not used before)\n                        if (canonical_shape_to_id.count(canonical_unit)) {\n                            current_id = canonical_shape_to_id[canonical_unit];\n                        } else {\n                            current_id = next_block_id++;\n                            canonical_shape_to_id[canonical_unit] = current_id;\n                        }\n                        assignments.push_back({current_id, unit_block});\n                        GRID_GET(covered, x, y, z, D) = true; // Mark this single cell as covered\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input D (dimension of the grid)\n    cin >> D;\n    \n    // Resize input strings for silhouettes\n    f1_str.resize(D); r1_str.resize(D);\n    f2_str.resize(D); r2_str.resize(D);\n\n    // Read the four silhouette images\n    for (int i = 0; i < D; ++i) cin >> f1_str[i];\n    for (int i = 0; i < D; ++i) cin >> r1_str[i];\n    for (int i = 0; i < D; ++i) cin >> f2_str[i];\n    for (int i = 0; i < D; ++i) cin >> r2_str[i];\n\n    // Initialize the grids that define where cells can be occupied\n    setup_grids();\n\n    // --- Filling for Object 1 ---\n    next_block_id = 1; // Reset block ID counter for each object, shared IDs are managed by map\n    canonical_shape_to_id.clear(); // Clear map for potentially new shared blocks\n    assignments1.clear(); // Clear previous assignments\n    vector<bool> covered1(D * D * D, false); // Track covered cells for object 1\n    fill_object(G1_grid, covered1, assignments1, true); // Call the greedy fill function\n\n    // --- Filling for Object 2 ---\n    // Note: canonical_shape_to_id is NOT cleared here. This ensures that if a shape\n    // used in object 1 is also used in object 2, it gets the same ID.\n    vector<bool> covered2(D * D * D, false); // Track covered cells for object 2\n    assignments2.clear(); // Clear previous assignments\n    fill_object(G2_grid, covered2, assignments2, false); // Call the greedy fill function\n\n    // --- Output ---\n    // The total number of unique blocks used across both objects\n    cout << next_block_id - 1 << endl;\n\n    // Output the block assignments for object 1\n    vector<int> b1_output(D * D * D, 0);\n    for (const auto& assign : assignments1) {\n        for (const auto& cell : assign.shape.cells) {\n            GRID_WRITE(b1_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b1_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    // Output the block assignments for object 2\n    vector<int> b2_output(D * D * D, 0);\n    for (const auto& assign : assignments2) {\n        for (const auto& cell : assign.shape.cells) {\n            GRID_WRITE(b2_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b2_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <set>\n#include <queue>\n\n// Use long double for precision in distance calculations\nusing ftype = long double;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n    ftype dist_sq; // Squared Euclidean distance\n};\n\nstruct Resident {\n    int id;\n    Point pos;\n};\n\nint N_stations_global, M_edges_global, K_residents_global;\nstd::vector<Point> station_pos_global;\nstd::vector<Edge> edges_global;\nstd::vector<Resident> residents_global;\n\n// Precomputed distances: dists[i][k] is distance from station i to resident k\nstd::vector<std::vector<ftype>> dists_global;\n\n// Function to calculate squared Euclidean distance between two points\nftype distSq(Point p1, Point p2) {\n    ftype dx = static_cast<ftype>(p1.x) - p2.x;\n    ftype dy = static_cast<ftype>(p1.y) - p2.y;\n    return dx * dx + dy * dy;\n}\n\n// Function to calculate Euclidean distance\nftype dist(Point p1, Point p2) {\n    return std::sqrt(distSq(p1, p2));\n}\n\n// Check connectivity of V_prime from station 0\nbool is_connected(int start_node, const std::vector<int>& V_prime_indices, const std::vector<int>& edge_indices_B) {\n    if (V_prime_indices.empty()) return true;\n    \n    std::vector<bool> is_in_V_prime(N_stations_global, false);\n    for(int idx : V_prime_indices) is_in_V_prime[idx] = true;\n\n    std::vector<std::vector<int>> adj(N_stations_global);\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (edge_indices_B[j]) {\n            adj[edges_global[j].u - 1].push_back(edges_global[j].v - 1);\n            adj[edges_global[j].v - 1].push_back(edges_global[j].u - 1);\n        }\n    }\n\n    std::vector<bool> visited(N_stations_global, false);\n    std::queue<int> q;\n\n    // Find the first node in V_prime to start BFS from. It must be connected to vertex 1.\n    // If vertex 1 itself is not in V_prime, this check is different.\n    // The problem guarantees station 1 is at (0,0) and it's the source.\n    // So we always check connectivity from station 0 (which is vertex 1).\n    if (!is_in_V_prime[start_node]) return false; // Source must be in V_prime\n\n    q.push(start_node);\n    visited[start_node] = true;\n    int count_visited_in_V_prime = 0;\n    if (is_in_V_prime[start_node]) count_visited_in_V_prime++;\n\n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n\n        for (int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                if (is_in_V_prime[v]) {\n                    count_visited_in_V_prime++;\n                }\n            }\n        }\n    }\n    \n    // Check if all stations in V_prime are reachable from start_node\n    return count_visited_in_V_prime == V_prime_indices.size();\n}\n\n// Calculate total cost\nlong long calculate_total_cost(const std::vector<int>& P, const std::vector<int>& B) {\n    long long edge_cost = 0;\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (B[j]) {\n            edge_cost += edges_global[j].w;\n        }\n    }\n    long long station_cost = 0;\n    for (int i = 0; i < N_stations_global; ++i) {\n        station_cost += static_cast<long long>(P[i]) * P[i];\n    }\n    return station_cost + edge_cost;\n}\n\n// Represents a potential connection for coverage\nstruct CoverageOption {\n    ftype radius; // d_ik\n    int station_idx; // i\n    int resident_idx; // k\n\n    bool operator<(const CoverageOption& other) const {\n        return radius < other.radius;\n    }\n};\n\n// Greedy assignment for P_i values using marginal cost\nstd::vector<int> solve_P_greedy_marginal_cost(const std::vector<int>& V_prime_indices) {\n    std::vector<int> P(N_stations_global, 0);\n    std::vector<bool> resident_covered(K_residents_global, false);\n    int uncovered_count = K_residents_global;\n    \n    std::vector<int> current_V_prime_indices = V_prime_indices; // Copy V_prime\n\n    int iterations = 0;\n    const int MAX_ITER = 2 * K_residents_global + 50; // Heuristic limit\n\n    while (uncovered_count > 0 && iterations < MAX_ITER) {\n        iterations++;\n        \n        int best_resident_to_cover = -1;\n        int best_station_to_use = -1;\n        long long min_marginal_cost = -1; \n\n        // Find an uncovered resident and a station to cover it with minimum marginal cost\n        for(int k = 0; k < K_residents_global; ++k) {\n            if (!resident_covered[k]) {\n                for(int station_idx : current_V_prime_indices) {\n                    ftype d = dists_global[station_idx][k];\n                    if (d > 5000.0) continue; // Station cannot cover this resident within limit\n\n                    int required_p_int = static_cast<int>(std::ceil(d));\n                    if (required_p_int > 5000) required_p_int = 5000;\n\n                    long long current_p_sq = static_cast<long long>(P[station_idx]) * P[station_idx];\n                    long long new_p_val = std::max(P[station_idx], required_p_int);\n                    long long new_p_sq = new_p_val * new_p_val;\n                    \n                    long long marginal_cost = new_p_sq - current_p_sq;\n\n                    if (best_station_to_use == -1 || marginal_cost < min_marginal_cost) {\n                        min_marginal_cost = marginal_cost;\n                        best_station_to_use = station_idx;\n                        best_resident_to_cover = k;\n                    } else if (marginal_cost == min_marginal_cost) {\n                        // Tie-breaking: prefer smaller radius, then smaller current P, then smaller station index\n                        ftype current_best_d = dists_global[best_station_to_use][best_resident_to_cover];\n                        ftype new_d = d;\n                        if (new_d < current_best_d) {\n                            best_station_to_use = station_idx;\n                            best_resident_to_cover = k;\n                        } else if (new_d == current_best_d) {\n                            if (P[station_idx] < P[best_station_to_use]) {\n                                best_station_to_use = station_idx;\n                                best_resident_to_cover = k;\n                            } else if (P[station_idx] == P[best_station_to_use]) {\n                                if (station_idx < best_station_to_use) {\n                                     best_station_to_use = station_idx;\n                                     best_resident_to_cover = k;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        if (best_station_to_use != -1) {\n            // Update P for the chosen station\n            ftype d = dists_global[best_station_to_use][best_resident_to_cover];\n            int required_p_int = static_cast<int>(std::ceil(d));\n            if (required_p_int > 5000) required_p_int = 5000;\n            P[best_station_to_use] = std::max(P[best_station_to_use], required_p_int);\n            \n            // Update coverage status for all residents\n            int newly_covered_in_this_step = 0;\n            for(int k=0; k<K_residents_global; ++k) {\n                if (!resident_covered[k]) {\n                    ftype d_k = dists_global[best_station_to_use][k];\n                    if (d_k <= P[best_station_to_use]) {\n                        resident_covered[k] = true;\n                        newly_covered_in_this_step++;\n                    }\n                }\n            }\n            uncovered_count -= newly_covered_in_this_step;\n        } else {\n            // Cannot cover any more residents with available stations and P <= 5000.\n            // This could happen if remaining residents require radii > 5000 from available stations.\n            // Based on problem statement, this shouldn't be the case unless V_prime is too small.\n            break; \n        }\n    }\n\n    // Final fallback: ensure all residents are covered. If not, increase P of closest station to 5000.\n    if (uncovered_count > 0) {\n        for(int k=0; k<K_residents_global; ++k) {\n            if (!resident_covered[k]) {\n                ftype min_d = 5001.0;\n                int best_station_idx = -1;\n                for (int station_idx : current_V_prime_indices) {\n                    ftype d = dists_global[station_idx][k];\n                    if (d < min_d) {\n                        min_d = d;\n                        best_station_idx = station_idx;\n                    }\n                }\n                if (best_station_idx != -1 && min_d <= 5000.0) {\n                    P[best_station_idx] = std::max(P[best_station_to_use], 5000); // Force coverage\n                    // Mark all residents as covered by this station if P is now 5000\n                    for(int kk=0; kk<K_residents_global; ++kk) {\n                        if (!resident_covered[kk]) {\n                            ftype d_kk = dists_global[best_station_to_use][kk];\n                            if (d_kk <= P[best_station_to_use]) {\n                                resident_covered[kk] = true;\n                                uncovered_count--;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return P;\n}\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> N_stations_global >> M_edges_global >> K_residents_global;\n\n    station_pos_global.resize(N_stations_global);\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cin >> station_pos_global[i].x >> station_pos_global[i].y;\n    }\n\n    edges_global.resize(M_edges_global);\n    for (int i = 0; i < M_edges_global; ++i) {\n        edges_global[i].id = i;\n        std::cin >> edges_global[i].u >> edges_global[i].v >> edges_global[i].w;\n        edges_global[i].u--; // 0-indexed\n        edges_global[i].v--; // 0-indexed\n        edges_global[i].dist_sq = distSq(station_pos_global[edges_global[i].u], station_pos_global[edges_global[i].v]);\n    }\n\n    residents_global.resize(K_residents_global);\n    for (int i = 0; i < K_residents_global; ++i) {\n        residents_global[i].id = i;\n        std::cin >> residents_global[i].pos.x >> residents_global[i].pos.y;\n    }\n\n    // 1. Precompute all distances\n    dists_global.resize(N_stations_global, std::vector<ftype>(K_residents_global));\n    for (int i = 0; i < N_stations_global; ++i) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            dists_global[i][k] = dist(station_pos_global[i], residents_global[k].pos);\n        }\n    }\n\n    // 2. Initial Connectivity: Use Minimum Spanning Tree (Kruskal's algorithm)\n    std::sort(edges_global.begin(), edges_global.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    std::vector<int> parent(N_stations_global);\n    std::iota(parent.begin(), parent.end(), 0);\n    auto find_set = [&](auto self, int v) -> int {\n        if (v == parent[v]) return v;\n        return parent[v] = self(self, parent[v]);\n    };\n    auto unite_sets = [&](int a, int b) -> bool {\n        a = find_set(find_set, a);\n        b = find_set(find_set, b);\n        if (a != b) {\n            parent[b] = a;\n            return true;\n        }\n        return false;\n    };\n\n    std::vector<int> B_mst(M_edges_global, 0);\n    std::vector<int> mst_edge_indices;\n    int edges_count = 0;\n    for (const auto& edge : edges_global) {\n        if (unite_sets(edge.u, edge.v)) {\n            B_mst[edge.id] = 1;\n            mst_edge_indices.push_back(edge.id);\n            edges_count++;\n            if (edges_count == N_stations_global - 1) break;\n        }\n    }\n    // If graph was not connected initially, MST might not span all nodes.\n    // However, problem statement guarantees a connected graph.\n\n    // 3. Edge Pruning (Iterative Improvement)\n    std::vector<int> B = B_mst; // Start with MST edges\n    std::vector<int> current_V_prime_indices;\n    \n    // Sort edges by weight for pruning\n    std::vector<Edge> sorted_edges = edges_global;\n    std::sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    // Try to remove edges in increasing order of weight\n    for (const auto& edge_to_consider : sorted_edges) {\n        int edge_id = edge_to_consider.id;\n        \n        // Temporarily remove the edge\n        B[edge_id] = 0;\n\n        // Determine V_prime with the current set of active edges B\n        std::vector<int> temp_V_prime_indices;\n        std::vector<bool> station_in_V_prime(N_stations_global, false);\n        \n        std::vector<std::vector<int>> adj(N_stations_global);\n        for(int j=0; j<M_edges_global; ++j) {\n            if (B[j]) {\n                adj[edges_global[j].u].push_back(edges_global[j].v);\n                adj[edges_global[j].v].push_back(edges_global[j].u);\n            }\n        }\n\n        std::queue<int> q;\n        if (!adj[0].empty() || N_stations_global == 1) { // Station 0 must be reachable from itself\n            q.push(0);\n            station_in_V_prime[0] = true;\n            temp_V_prime_indices.push_back(0);\n        }\n        \n        std::vector<bool> visited(N_stations_global, false);\n        visited[0] = true;\n        \n        while(!q.empty()) {\n            int u = q.front();\n            q.pop();\n            for(int v : adj[u]) {\n                if (!visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                    station_in_V_prime[v] = true;\n                    temp_V_prime_indices.push_back(v);\n                }\n            }\n        }\n        \n        // Check if removing this edge disconnects any station that *might* need power ON (i.e. P > 0)\n        // Initially, we don't know P. So we need all stations to be reachable from 0.\n        // The strategy is: prune edges until all stations are disconnected from station 0.\n        // Then, we must re-add edges to ensure connectivity for stations that *will* have P_i > 0.\n        // This is tricky. A simpler pruning: remove edges that are not part of any minimal spanning tree connecting {0} to {stations that will have P_i > 0}.\n        // Let's try: remove edge if all stations that will have P_i > 0 are still reachable.\n        // For now, assume we need to connect all stations.\n        \n        // A simpler pruning: if removing edge disconnects the graph of currently active edges, put it back.\n        // This means `temp_V_prime_indices` should contain all N_stations_global IF we initially connect all.\n        // If `temp_V_prime_indices.size() != N_stations_global`, then removing this edge disconnects the component.\n        // If we want to ensure all stations are potentially usable, we need to keep edges that keep the graph connected.\n        \n        // A more accurate check: after pruning, will all stations that are *needed* (i.e., will have P_i > 0) be reachable?\n        // This is hard to know beforehand. Let's simplify: we must connect station 0 to all stations *that we decide to use*.\n        // For now, let's try to keep a connected component of all stations from station 0.\n\n        if (temp_V_prime_indices.size() < N_stations_global) {\n            // Removing this edge disconnected the graph. Restore it.\n            B[edge_id] = 1;\n        }\n    }\n\n    // 4. Assign initial P values for the determined V_prime\n    // First, get the final V_prime based on the pruned edges B\n    current_V_prime_indices.clear();\n    std::vector<bool> station_in_V_prime(N_stations_global, false);\n    \n    std::vector<std::vector<int>> adj(N_stations_global);\n    for(int j=0; j<M_edges_global; ++j) {\n        if (B[j]) {\n            adj[edges_global[j].u].push_back(edges_global[j].v);\n            adj[edges_global[j].v].push_back(edges_global[j].u);\n        }\n    }\n\n    std::queue<int> q;\n    if (!adj[0].empty() || N_stations_global == 1) { // Station 0 is always source\n        q.push(0);\n        station_in_V_prime[0] = true;\n        current_V_prime_indices.push_back(0);\n    }\n    \n    std::vector<bool> visited(N_stations_global, false);\n    visited[0] = true;\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for(int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                station_in_V_prime[v] = true;\n                current_V_prime_indices.push_back(v);\n            }\n        }\n    }\n    \n    // Now, `current_V_prime_indices` contains all stations reachable from station 0.\n    // Assign P values using the greedy marginal cost approach for the determined V_prime.\n    std::vector<int> P = solve_P_greedy_marginal_cost(current_V_prime_indices);\n\n    // 5. Local Search / Iterative Refinement (Optional but good for score)\n    // This part is complex and time-consuming. For a contest heuristic, we might skip this\n    // or implement a very simple version.\n    // Example: Try removing edges one by one again, and re-optimizing P.\n    // If total cost decreases, keep the edge removed.\n\n    // Let's try a simple local search for edge removal and P re-optimization.\n    // Iterate multiple times to allow for cascading improvements.\n    // Maximum number of local search iterations.\n    const int LOCAL_SEARCH_ITER = 10000; \n\n    for(int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        bool improved = false;\n\n        // --- Edge Removal ---\n        // Try removing edges by increasing weight\n        std::vector<Edge> edges_to_try_removing = edges_global;\n        std::sort(edges_to_try_removing.begin(), edges_to_try_removing.end(), [](const Edge& a, const Edge& b) {\n            return a.w < b.w;\n        });\n\n        for (const auto& edge_to_consider : edges_to_try_removing) {\n            int edge_id = edge_to_consider.id;\n            if (B[edge_id] == 0) continue; // Already removed\n\n            // Temporarily remove the edge\n            B[edge_id] = 0;\n\n            // Determine new V_prime\n            current_V_prime_indices.clear();\n            std::fill(station_in_V_prime.begin(), station_in_V_prime.end(), false);\n            std::fill(&adj[0][0], &adj[0][0] + N_stations_global * N_stations_global, 0); // Clear adjacency list\n            for(int j=0; j<M_edges_global; ++j) {\n                if (B[j]) {\n                    adj[edges_global[j].u].push_back(edges_global[j].v);\n                    adj[edges_global[j].v].push_back(edges_global[j].u);\n                }\n            }\n            \n            std::queue<int> q_ls;\n            if (!adj[0].empty() || N_stations_global == 1) {\n                q_ls.push(0);\n                station_in_V_prime[0] = true;\n                current_V_prime_indices.push_back(0);\n            }\n            std::vector<bool> visited_ls(N_stations_global, false);\n            visited_ls[0] = true;\n            \n            while(!q_ls.empty()) {\n                int u = q_ls.front();\n                q_ls.pop();\n                for(int v : adj[u]) {\n                    if (!visited_ls[v]) {\n                        visited_ls[v] = true;\n                        q_ls.push(v);\n                        station_in_V_prime[v] = true;\n                        current_V_prime_indices.push_back(v);\n                    }\n                }\n            }\n\n            // Re-solve P values for the new V_prime\n            std::vector<int> next_P = solve_P_greedy_marginal_cost(current_V_prime_indices);\n            \n            // Calculate cost\n            long long current_total_cost = calculate_total_cost(P, B); // Cost before removing edge_id\n            long long next_total_cost = calculate_total_cost(next_P, B);\n            \n            // Check if this move is valid and improves the solution\n            // Validity: all residents must be covered by next_P and next_V_prime\n            bool coverage_ok = true;\n            if (current_V_prime_indices.empty() && K_residents_global > 0) coverage_ok = false;\n            else {\n                std::vector<bool> covered(K_residents_global, false);\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    for(int station_idx : current_V_prime_indices) {\n                        if (next_P[station_idx] > 0 && dists_global[station_idx][k] <= next_P[station_idx]) {\n                            covered[k] = true;\n                            break;\n                        }\n                    }\n                    if(covered[k]) covered_count++;\n                }\n                if (covered_count < K_residents_global) coverage_ok = false;\n            }\n\n            if (coverage_ok && next_total_cost < current_total_cost) {\n                P = next_P; // Update P values\n                // B is already updated (edge_id is 0)\n                improved = true;\n            } else {\n                // Revert the change\n                B[edge_id] = 1;\n            }\n        }\n        \n        // --- P Value Adjustment ---\n        // Try to decrease P values for stations in V_prime\n        if (!current_V_prime_indices.empty()) {\n            int station_to_adjust = current_V_prime_indices[rand() % current_V_prime_indices.size()]; // Pick random station in V_prime\n            \n            if (P[station_to_adjust] > 0) {\n                int original_P = P[station_to_adjust];\n                P[station_to_adjust]--; // Try decreasing P by 1\n                \n                // Re-check coverage. This is slow. A quicker check:\n                // Which residents are ONLY covered by this station with original P?\n                // If decreasing P makes them uncovered, we must revert or increase P elsewhere.\n                \n                // Full check:\n                long long cost_before_p_adjust = calculate_total_cost(P, B); // P still has original value here\n                //temporarily P is decreased\n                P[station_to_adjust]--;\n                \n                // Check coverage with new P\n                bool coverage_ok = true;\n                std::vector<bool> covered(K_residents_global, false);\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    for(int station_idx : current_V_prime_indices) {\n                         if (P[station_idx] > 0 && dists_global[station_idx][k] <= P[station_idx]) {\n                            covered[k] = true;\n                            break;\n                        }\n                    }\n                    if(covered[k]) covered_count++;\n                }\n                if (covered_count < K_residents_global) coverage_ok = false;\n                \n                long long cost_after_p_adjust = calculate_total_cost(P, B);\n\n                if (coverage_ok && cost_after_p_adjust < cost_before_p_adjust) {\n                    // Keep the decrease\n                    improved = true;\n                } else {\n                    // Revert\n                    P[station_to_adjust] = original_P;\n                }\n            }\n        }\n\n        if (!improved) break; // Stop if no improvement in an iteration\n    }\n\n    // Output final P values and B values\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cout << P[i] << (i == N_stations_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n    for (int j = 0; j < M_edges_global; ++j) {\n        std::cout << B[j] << (j == M_edges_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <map>\n#include <tuple> // For tie-breaking if needed, though struct comparison is sufficient\n\n// Maximum number of tiers\nconst int N = 30;\n// Total number of balls\nconst int M = N * (N + 1) / 2; // M = 465\n\n// Structure to represent coordinates (tier x, position y)\nstruct Coord {\n    int x, y;\n\n    // Operator overloading for map keys and comparisons.\n    // Required for std::map and for determining lexicographical order.\n    bool operator<(const Coord& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Coord& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Useful for tie-breaking in lexicographical order.\n    bool operator>(const Coord& other) const {\n        if (x != other.x) return x > other.x;\n        return y > other.y;\n    }\n};\n\n// Convert pyramid coordinates (x, y) to a linear index.\n// This index serves as the \"target position\" for a ball with a value equal to this index.\n// For example, ball with value 0 should be at (0,0), value 1 at (1,0), value 2 at (1,1), etc.\ninline int get_idx_from_coord(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Define relative coordinates for the 6 possible adjacent moves.\n// These correspond to the adjacency rules given in the problem statement.\n// Order:\n// (dx[0], dy[0]) = (1, 0) : (x+1, y)   (Down-Left)\n// (dx[1], dy[1]) = (1, 1) : (x+1, y+1) (Down-Right)\n// (dx[2], dy[2]) = (0, 1) : (x, y+1)   (Right)\n// (dx[3], dy[3]) = (0,-1) : (x, y-1)   (Left)\n// (dx[4], dy[4]) = (-1,0) : (x-1, y)   (Up-Left)\n// (dx[5], dy[5]) = (-1,1) : (x-1, y+1) (Up-Right)\nint dx[] = {1, 1, 0, 0, -1, -1}; // change in x\nint dy[] = {0, 1, 1, -1, 0, 1}; // change in y\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Map to store the current value of the ball at a given coordinate.\n    // Key: Coord, Value: ball_value\n    std::map<Coord, int> current_values_map;\n    \n    // Vector to store all valid coordinates in the pyramid.\n    // Populated in order: (0,0), (1,0), (1,1), (2,0), (2,1), (2,2), ...\n    // This order ensures deterministic iteration through all cells and facilitates tie-breaking.\n    std::vector<Coord> all_coords;\n    all_coords.reserve(M);\n\n    // Read input and populate the initial state of the pyramid.\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            Coord c = {x, y};\n            all_coords.push_back(c);\n            int value;\n            std::cin >> value;\n            current_values_map[c] = value;\n        }\n    }\n\n    // Store the sequence of performed swaps.\n    // Each swap is a pair of adjacent coordinates.\n    std::vector<std::pair<Coord, Coord>> swaps;\n    const int MAX_SWAPS = 10000; // Maximum allowed operations.\n\n    // Heuristic strategy:\n    // This problem is NP-hard, so we employ a greedy heuristic.\n    // The target configuration is one where each ball with value `v` is located at\n    // coordinate `c` such that `get_idx_from_coord(c.x, c.y) == v`.\n    // This configuration guarantees the condition V(x,y) < V(x+1,y) and V(x,y) < V(x+1,y+1).\n    //\n    // In each step (up to MAX_SWAPS operations), we find the single best adjacent swap.\n    // The \"best\" swap is defined as one that maximizes the reduction in the total absolute error.\n    // The total absolute error is the sum of |target_index - current_value| for all balls.\n    // A swap is only considered if it moves a ball with a larger value to a position\n    // that should ideally hold a larger index (i.e., resolves an inversion where idx1 < idx2 but val1 > val2).\n    // If multiple swaps yield the same maximum benefit, we choose the one that is\n    // lexicographically smallest in terms of the coordinate pair (c1, c2), where c1 is\n    // the \"left/up\" ball and c2 is the \"right/down\" ball (idx(c1) < idx(c2)).\n\n    for (int k = 0; k < MAX_SWAPS; ++k) {\n        // Variables to track the best swap found in this iteration.\n        // Initialize max_benefit to a very small number. We are interested in non-negative benefits.\n        long long max_benefit = -2e18; \n        Coord best_c1 = {-1, -1}, best_c2 = {-1, -1}; // Initialize to invalid coordinates.\n\n        // Iterate through all balls (c1) and their potential neighbors (c2).\n        // `all_coords` is iterated in lexicographical order.\n        for (const auto& c1 : all_coords) { \n            int val1 = current_values_map.at(c1);\n            int idx1 = get_idx_from_coord(c1.x, c1.y);\n\n            // Check each of the 6 possible adjacent neighbors of c1.\n            for (int i = 0; i < 6; ++i) {\n                Coord c2 = {c1.x + dx[i], c1.y + dy[i]};\n\n                // Validate if the neighbor coordinate c2 is within the pyramid boundaries.\n                if (c2.x < 0 || c2.x >= N || c2.y < 0 || c2.y > c2.x) {\n                    continue; // c2 is outside the pyramid.\n                }\n\n                int val2 = current_values_map.at(c2);\n                int idx2 = get_idx_from_coord(c2.x, c2.y);\n\n                // We are only interested in swaps that fix an \"inversion\" according to the target index.\n                // An inversion exists if c1 should have a smaller index than c2 (idx1 < idx2),\n                // but c1 currently holds a larger value than c2 (val1 > val2).\n                // Swapping these would move a smaller value towards a smaller index, and a larger value\n                // towards a larger index, thus reducing the total absolute error.\n                if (idx1 < idx2 && val1 > val2) {\n                    // Calculate the benefit of swapping c1 and c2.\n                    // Benefit is defined as the reduction in the sum of absolute errors:\n                    // Total Error = Sum over all balls v of | target_idx(pos[v]) - v |\n                    // current_error_sum = |idx1 - val1| + |idx2 - val2|\n                    // new_error_sum     = |idx1 - val2| + |idx2 - val1|  (after swapping val1 and val2)\n                    // benefit           = current_error_sum - new_error_sum\n                    long long current_error_sum = std::abs((long long)idx1 - val1) + std::abs((long long)idx2 - val2);\n                    long long new_error_sum = std::abs((long long)idx1 - val2) + std::abs((long long)idx2 - val1);\n                    long long benefit = current_error_sum - new_error_sum;\n\n                    // Update `best_c1`, `best_c2`, and `max_benefit` if this swap is better.\n                    // Selection criteria:\n                    // 1. Maximize the benefit. We require `benefit >= 0`. A benefit of 0 means\n                    //    the total error sum doesn't decrease, but the swap might still resolve\n                    //    an inversion and potentially reduce direct violations (E), or help reach MAX_SWAPS.\n                    // 2. If benefits are equal, choose the lexicographically smaller coordinate pair (c1, c2).\n                    //    The iteration order ensures that the first encountered pair for a given\n                    //    benefit is the lexicographically smallest. Thus, we update only if the current\n                    //    pair (c1, c2) is strictly smaller than the current `(best_c1, best_c2)`.\n                    \n                    if (benefit > max_benefit) {\n                        max_benefit = benefit;\n                        best_c1 = c1;\n                        best_c2 = c2;\n                    } else if (benefit == max_benefit) {\n                        // Tie-breaking: select the lexicographically smaller coordinate pair (c1, c2).\n                        if (c1 < best_c1 || (c1 == best_c1 && c2 < best_c2)) {\n                             best_c1 = c1;\n                             best_c2 = c2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // If a beneficial swap was found (best_c1 is valid and max_benefit >= 0),\n        // and we haven't reached the maximum allowed number of swaps:\n        if (best_c1.x != -1 && max_benefit >= 0) {\n            // Apply the selected best swap.\n            std::swap(current_values_map.at(best_c1), current_values_map.at(best_c2));\n            // Record the swap operation.\n            swaps.push_back({best_c1, best_c2});\n        } else {\n            // No swap found with non-negative benefit, or we have already performed MAX_SWAPS (implicit in k loop condition).\n            // In this case, we cannot improve further with this greedy strategy, so we stop.\n            break;\n        }\n    }\n\n    // Output the total number of operations performed.\n    std::cout << swaps.size() << std::endl;\n    // Output each swap operation in the specified format.\n    for (const auto& sw : swaps) {\n        std::cout << sw.first.x << \" \" << sw.first.y << \" \" << sw.second.x << \" \" << sw.second.y << std::endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions and properties\nconst int MAX_D = 9; // D is fixed at 9 for all test cases\nint D;\nbool is_obstacle[MAX_D][MAX_D];\nint dist[MAX_D][MAX_D];\npair<int, int> entrance;\n\n// Directions for BFS: North, East, South, West\n// These correspond to changes in (row, column) coordinates.\nint dr[] = {-1, 0, 1, 0};\nint dc[] = {0, 1, 0, -1};\n\n// Structure to hold cell information: row, column, and its shortest distance from the entrance.\n// This is used for sorting storage locations.\nstruct CellInfo {\n    int r, c, d;\n\n    // Custom comparison operator for sorting:\n    // 1. Primarily by distance (ascending).\n    // 2. Secondarily by row index (ascending).\n    // 3. Tertiarily by column index (ascending).\n    bool operator<(const CellInfo& other) const {\n        if (d != other.d) {\n            return d < other.d;\n        }\n        if (r != other.r) {\n            return r < other.r;\n        }\n        return c < other.c;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming performance.\n    // `ios_base::sync_with_stdio(false)` unties C++ streams from C stdio.\n    // `cin.tie(NULL)` unties cin from cout, meaning cin operations do not force cout to flush.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N; // Number of obstacles\n    cin >> D >> N;\n\n    // Set entrance coordinates (0-indexed). D is always 9, so (D-1)/2 is 4.\n    entrance = {0, (D - 1) / 2};\n\n    // Initialize grid properties: mark all cells as not an obstacle and unreachable initially.\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            is_obstacle[i][j] = false;\n            dist[i][j] = -1; // -1 indicates unreachable or unvisited\n        }\n    }\n\n    // Read and mark obstacle locations.\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    // --- BFS to calculate shortest distances ---\n    // We perform a Breadth-First Search starting from the entrance to find the shortest\n    // path distance to all reachable non-obstacle cells.\n    queue<pair<int, int>> q;\n\n    // The entrance is guaranteed not to be an obstacle.\n    dist[entrance.first][entrance.second] = 0;\n    q.push(entrance);\n\n    // This vector will store information about all reachable cells (including the entrance)\n    // along with their distances.\n    vector<CellInfo> all_reachable_cells;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n\n        // Add the current cell to our list of reachable cells.\n        all_reachable_cells.push_back({r, c, dist[r][c]});\n\n        // Explore neighbors in all four directions.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid bounds, is not an obstacle, and has not been visited yet.\n            if (nr >= 0 && nr < D && nc >= 0 && nc < D && !is_obstacle[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1; // Distance is one more than the current cell's distance.\n                q.push({nr, nc}); // Add the neighbor to the queue for exploration.\n            }\n        }\n    }\n\n    // --- Sorting Storage Locations ---\n    // The problem states that containers are stored in squares other than the entrance and obstacles.\n    // The total number of containers is M = D*D - 1 - N. These will occupy M storage locations.\n    // We need to sort these storage locations based on their proximity to the entrance to establish an order.\n    vector<CellInfo> sorted_storage_locs;\n    for (const auto& cell : all_reachable_cells) {\n        // The entrance cell itself is not a storage location, so we skip it.\n        if (cell.r == entrance.first && cell.c == entrance.second) {\n            continue;\n        }\n        sorted_storage_locs.push_back(cell);\n    }\n\n    // Sort the storage locations using the custom comparison operator defined in CellInfo.\n    // This ensures they are ordered by distance, then row, then column.\n    sort(sorted_storage_locs.begin(), sorted_storage_locs.end());\n\n    // Calculate the total number of containers to be stored.\n    int num_containers = D * D - 1 - N;\n\n    // --- Container Placement Phase ---\n    // This phase handles the arrival of containers one by one.\n    // For each arriving container, we decide where to store it.\n    // Our strategy: The d-th container to arrive (with ID t_d) is placed in the d-th location\n    // from our sorted list of storage locations (`sorted_storage_locs`). This greedy approach aims\n    // to keep containers with smaller target retrieval IDs in \"closer\" or more accessible locations.\n    \n    // We need to record the arrival order for each container ID.\n    // `container_arrival_idx[container_id]` will store the index `d` (0 to num_containers-1)\n    // representing the order in which `container_id` arrived and was placed.\n    vector<int> container_arrival_idx(num_containers); \n\n    for (int d = 0; d < num_containers; ++d) {\n        int container_id; // The ID of the container arriving at step d.\n        cin >> container_id;\n\n        // The d-th arriving container is placed at the d-th location in our sorted list.\n        CellInfo current_storage_loc = sorted_storage_locs[d];\n        pair<int, int> pos = {current_storage_loc.r, current_storage_loc.c};\n        \n        // Output the chosen storage location (row and column) for this container.\n        cout << pos.first << \" \" << pos.second << endl;\n        // `endl` typically flushes the output buffer in C++ streams, which is required.\n        \n        // Record that `container_id` arrived at step `d` and was assigned to `sorted_storage_locs[d]`.\n        // This means container_id is stored at the d-th closest available slot.\n        container_arrival_idx[container_id] = d; \n    }\n\n    // --- Container Retrieval Phase ---\n    // After all containers are stored, we need to determine the order in which they are transported out.\n    // The goal is to minimize the number of inversions in the retrieval sequence `b_0, b_1, ..., b_{M-1}`.\n    // This is achieved by aiming for the sorted sequence `0, 1, ..., M-1`.\n    // Our placement strategy (d-th arrival at d-th closest slot) allows for this.\n    // Container `k` is placed at `sorted_storage_locs[container_arrival_idx[k]]`.\n    // By retrieving containers in increasing order of their IDs (0, 1, 2, ...), we can achieve minimal inversions.\n    // Container `k` can be retrieved at step `k` because its location is guaranteed to be reachable.\n    // All containers `0, ..., k-1` are retrieved before container `k`, making their locations empty.\n    // The entire storage area is connected to the entrance, ensuring reachability.\n    \n    for (int k = 0; k < num_containers; ++k) {\n        // We want to retrieve container with ID `k` at step `k` of the retrieval sequence.\n        // Find out which storage slot `d` this container `k` was assigned to based on its arrival order.\n        int d = container_arrival_idx[k]; \n        \n        // The location of container `k` is the d-th sorted storage location.\n        CellInfo retrieved_cell = sorted_storage_locs[d];\n        pair<int, int> pos = {retrieved_cell.r, retrieved_cell.c};\n        \n        // Output the coordinates of the container to be transported out at this step.\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> initial_grid;\nvector<vector<int>> output_grid; // -1: unassigned, 0..m: assigned color\nvector<vector<bool>> adj;\nvector<pair<int, int>> dx = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n// Checks if assigning color 'color_to_assign' to a cell is valid\n// given the colors of its already assigned neighbors.\n// 'neighbor_colors' is a set of colors of already assigned neighbors of the cell.\nbool is_valid(int color_to_assign, const set<int>& neighbor_colors) {\n    for (int neighbor_color : neighbor_colors) {\n        if (color_to_assign != neighbor_color) {\n            if (!adj[min(color_to_assign, neighbor_color)][max(color_to_assign, neighbor_color)]) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> n >> m;\n\n    initial_grid.resize(n, vector<int>(n));\n    output_grid.resize(n, vector<int>(n, -1)); // Initialize all cells as unassigned (-1)\n\n    // Store first occurrence of each color (1 to m) as a seed\n    vector<pair<int, int>> seeds(m + 1, {-1, -1});\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> initial_grid[i][j];\n            if (initial_grid[i][j] >= 1 && initial_grid[i][j] <= m) {\n                if (seeds[initial_grid[i][j]].first == -1) {\n                    seeds[initial_grid[i][j]] = {i, j};\n                }\n            }\n        }\n    }\n\n    // Compute adjacency matrix for colors 0 to m\n    adj.resize(m + 1, vector<bool>(m + 1, false));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = initial_grid[i][j];\n            if (c1 != 0) { // Only check adjacencies for non-zero colors in the input\n                for (auto& move : dx) {\n                    int ni = i + move.first;\n                    int nj = j + move.second;\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int c2 = initial_grid[ni][nj];\n                        if (c1 != c2) {\n                            adj[min(c1, c2)][max(c1, c2)] = true;\n                        }\n                    } else { // Neighbor is outside the grid, which means it's adjacent to color 0\n                        adj[min(c1, 0)][max(c1, 0)] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // BFS queue stores cells to process. We prioritize processing non-zero colors.\n    queue<pair<int, int>> q;\n\n    // Seed the grid with initial colors and add them to the queue\n    // Priority is given to non-zero colors.\n    for (int k = 1; k <= m; ++k) {\n        if (seeds[k].first != -1) {\n            int r = seeds[k].first;\n            int c = seeds[k].second;\n            if (output_grid[r][c] == -1) { // If cell is unassigned\n                output_grid[r][c] = k;\n                q.push({r, c});\n            }\n        }\n    }\n\n    // Initialize color 0 for cells that are initially 0 and on the border,\n    // or if the input color was 0. These ensure color 0 connectivity.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (initial_grid[i][j] == 0) {\n                if (output_grid[i][j] == -1) { // If unassigned and input was 0\n                    output_grid[i][j] = 0;\n                    // We don't push color 0 to the queue because color 0 expansion is implicit\n                    // and doesn't drive the assignment of non-zero colors.\n                    // However, if 0 is the *only* color assigned initially (e.g. all 0s input),\n                    // we might need to seed it if it's a border cell.\n                }\n            }\n        }\n    }\n    // Ensure border cells that are unassigned default to 0.\n    for (int i = 0; i < n; ++i) {\n        if (output_grid[i][0] == -1) { output_grid[i][0] = 0; }\n        if (output_grid[i][n-1] == -1) { output_grid[i][n-1] = 0; }\n    }\n    for (int j = 0; j < n; ++j) {\n        if (output_grid[0][j] == -1) { output_grid[0][j] = 0; }\n        if (output_grid[n-1][j] == -1) { output_grid[n-1][j] = 0; }\n    }\n\n\n    // BFS to fill the grid\n    // The queue `q` primarily contains seeds of non-zero colors.\n    // When a non-zero cell expands, it decides the color of its unassigned neighbors.\n    while (!q.empty()) {\n        pair<int, int> current_cell = q.front();\n        q.pop();\n        int r = current_cell.first;\n        int c = current_cell.second;\n        int current_color = output_grid[r][c];\n\n        for (auto& move : dx) {\n            int nr = r + move.first;\n            int nc = c + move.second;\n\n            if (nr >= 0 && nr < n && nc >= 0 && nc < n) {\n                if (output_grid[nr][nc] == -1) { // If neighbor is unassigned\n                    // Collect colors of already assigned neighbors of (nr, nc)\n                    set<int> neighbor_colors;\n                    for (auto& next_move : dx) {\n                        int nnr = nr + next_move.first;\n                        int nnc = nc + next_move.second;\n                        if (nnr >= 0 && nnr < n && nnc >= 0 && nnc < n) {\n                            if (output_grid[nnr][nnc] != -1) { // Collect colors of assigned neighbors\n                                neighbor_colors.insert(output_grid[nnr][nnc]);\n                            }\n                        }\n                    }\n\n                    int color_to_assign = -1;\n\n                    // Strategy:\n                    // 1. Try to assign color 0 if it's valid.\n                    // 2. If 0 is not valid, try to assign a non-zero color K.\n                    //    - Prioritize K if it's required by `current_color` (i.e., `adj[current_color][K]` is true).\n                    //    - If multiple such K exist, pick the smallest.\n                    //    - If no prioritized K is found, pick the smallest valid K.\n\n                    bool can_be_zero = is_valid(0, neighbor_colors);\n\n                    if (can_be_zero) {\n                        // Color 0 is valid. We prefer it to maximize score.\n                        // Assigning 0 means it remains 0 (since output_grid[nr][nc] was -1, and now becomes 0).\n                        // We do not push 0 to the queue as its expansion is implicit.\n                        color_to_assign = 0;\n                    } else {\n                        // Color 0 is NOT valid. We MUST assign a non-zero color.\n                        int best_k = -1;\n\n                        // First, try to find a K required by current_color\n                        if (current_color != 0) { // current_color is non-zero, check its adjacencies\n                            for (int k = 1; k <= m; ++k) {\n                                if (adj[min(current_color, k)][max(current_color, k)]) { // k is required by current_color\n                                    if (is_valid(k, neighbor_colors)) { // k is valid for this cell\n                                        best_k = k; // Found a candidate K\n                                        break; // Prioritize first such K\n                                    }\n                                }\n                            }\n                        }\n\n                        // If no prioritized K was found, find any valid non-zero color K\n                        if (best_k == -1) {\n                            for (int k = 1; k <= m; ++k) {\n                                if (is_valid(k, neighbor_colors)) {\n                                    best_k = k;\n                                    break; // Found first valid non-zero color K\n                                }\n                            }\n                        }\n                        color_to_assign = best_k;\n                    }\n\n                    // Assign the determined color and enqueue if it's non-zero.\n                    if (color_to_assign != -1) {\n                        output_grid[nr][nc] = color_to_assign;\n                        if (color_to_assign != 0) { // Only push non-zero colors to the queue\n                            q.push({nr, nc});\n                        }\n                    } else {\n                        // This case implies that no color (0 or 1..m) could be validly assigned.\n                        // This could happen if the problem constraints are impossible for this heuristic,\n                        // or if the seeding/expansion order leads to a dead end.\n                        // For a contest, leaving it as -1 and filling later might be an option,\n                        // but the problem implies a solution exists. We assume best_k is found if !can_be_zero.\n                        // As a fallback, we might assign 0 if it was valid but not preferred, or if problem implies any solution is fine.\n                        // However, the logic implies if !can_be_zero, then best_k MUST be found.\n                        // If it's not found, the strategy fails.\n                        // Given the scoring and heuristic nature, this state is unlikely if adjacencies are feasible.\n                    }\n                }\n            }\n        }\n    }\n\n    // Final pass: Fill any remaining unassigned cells (-1) with color 0.\n    // This ensures connectivity of color 0 and maximizes the score.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (output_grid[i][j] == -1) {\n                output_grid[i][j] = 0;\n            }\n        }\n    }\n\n    // Print the output grid\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << output_grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Use a large value for infinity in distance calculations.\n// Given N <= 100, a path length is at most N-1. Max difference per step is 1.\n// So N+5 should be sufficiently large for INF.\nconst long long INF = 1e18; \n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, d, q;\n    cin >> n >> d >> q;\n\n    // Stores the result of pairwise comparisons:\n    // comparison[i][j] = 1 if w_i < w_j\n    // comparison[i][j] = -1 if w_i > w_j\n    // comparison[i][j] = 0 if w_i = w_j\n    // comparison[i][j] = 2 if unknown\n    vector<vector<int>> comparison(n, vector<int>(n, 2));\n\n    int queries_budget = q;\n    int current_queries = 0;\n\n    // Phase 1: Prioritize comparisons between items with small index differences.\n    // This helps establish local relationships and might reveal structured weight distributions.\n    // We check differences from 1 up to a certain limit. The limit is capped by N/2\n    // to avoid redundant checks (e.g., diff=1 queries (0,1), (1,2), ..., (N-1,0). diff=N-1 queries (0,N-1), etc. which are inverse of diff=1).\n    // Also, cap the number of differences to check to not exceed Q.\n    int max_diff_to_check = min(10, n / 2); \n\n    for (int diff = 1; diff <= max_diff_to_check; ++diff) {\n        if (current_queries >= queries_budget) break;\n        for (int i = 0; i < n; ++i) {\n            if (current_queries >= queries_budget) break;\n            int j = (i + diff) % n; // Circular index difference\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1; // Symmetric relation\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1; // Symmetric relation\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0; // Symmetric relation\n                }\n            }\n        }\n    }\n    \n    // Phase 2: If budget remains, query arbitrary pairs (i, j) with i < j.\n    // This strategy aims to gather as many direct pairwise comparisons as possible.\n    for (int i = 0; i < n; ++i) {\n        if (current_queries >= queries_budget) break;\n        for (int j = i + 1; j < n; ++j) { // Iterate through unique pairs (i, j) with i < j\n            if (current_queries >= queries_budget) break;\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1;\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1;\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0;\n                }\n            }\n        }\n    }\n\n    // Initialize distance matrix for Floyd-Warshall algorithm.\n    // dist[i][j] will store the minimum possible value of (w_i - w_j).\n    // Weights w_i are positive integers (>= 1).\n    // If w_i < w_j, then w_i - w_j <= -1. The minimum possible difference is -1.\n    // If w_i > w_j, then w_i - w_j >= 1. The minimum possible difference is 1.\n    // If w_i = w_j, then w_i - w_j = 0.\n    vector<vector<long long>> dist(n, vector<long long>(n));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (i == j) {\n                dist[i][j] = 0; // Distance to self is 0\n            } else if (comparison[i][j] == 1) { // w_i < w_j => w_i - w_j <= -1\n                dist[i][j] = -1;\n            } else if (comparison[i][j] == -1) { // w_i > w_j => w_i - w_j >= 1\n                dist[i][j] = 1;\n            } else if (comparison[i][j] == 0) { // w_i = w_j\n                dist[i][j] = 0;\n            } else { // Unknown relationship\n                dist[i][j] = INF; // Initialize with infinity\n            }\n        }\n    }\n\n    // Run Floyd-Warshall to compute all-pairs shortest paths (minimum differences).\n    // This step integrates all pairwise comparisons to infer transitive relationships.\n    for (int k = 0; k < n; ++k) { // Intermediate node\n        for (int i = 0; i < n; ++i) { // Source node\n            for (int j = 0; j < n; ++j) { // Destination node\n                // If paths through k are possible, update distance\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    // Estimate weights based on the computed differences.\n    // We use dist[0][i] which represents the minimum inferred difference w_0 - w_i.\n    // So, w_i = w_0 + dist[0][i].\n    // To get an estimate of w_i's magnitude, we can use -dist[0][i] as a proxy.\n    // If dist[0][i] is -5, it implies w_i is roughly 5 units heavier than w_0. So -dist[0][i] = 5.\n    // If dist[0][i] is 3, it implies w_i is roughly 3 units lighter than w_0. So -dist[0][i] = -3.\n    // This gives a relative ordering.\n    vector<pair<long long, int>> estimated_weights(n);\n    long long min_estimated_val = 0; // To find the minimum estimated value for shifting\n    \n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i] = {-dist[0][i], i}; // Use -dist[0][i] as estimated weight\n        min_estimated_val = min(min_estimated_val, estimated_weights[i].first);\n    }\n\n    // Shift the estimated weights so that the minimum weight is 1.\n    // This ensures all estimated weights are positive integers, respecting the problem's constraint.\n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i].first = estimated_weights[i].first - min_estimated_val + 1;\n    }\n\n    // Sort items by their estimated weights in descending order.\n    // This is for the Largest Processing Time (LPT) heuristic, commonly used for multiway number partitioning.\n    sort(estimated_weights.rbegin(), estimated_weights.rend());\n\n    // Partitioning phase using the LPT heuristic.\n    // We want to assign items to 'd' bins such that the sum of weights in each bin is as equal as possible.\n    vector<long long> bin_sums(d, 0); // Stores the current total estimated weight for each bin\n    vector<int> assignment(n);       // Stores the final bin assignment for each item\n\n    for (const auto& item_pair : estimated_weights) {\n        long long weight = item_pair.first; // Estimated weight of the current item\n        int item_idx = item_pair.second;    // Original index of the item\n\n        // Find the bin with the minimum current sum of weights.\n        int best_bin = 0;\n        for (int b = 1; b < d; ++b) {\n            if (bin_sums[b] < bin_sums[best_bin]) {\n                best_bin = b;\n            }\n        }\n\n        // Assign the current item to the bin with the minimum sum.\n        assignment[item_idx] = best_bin;\n        bin_sums[best_bin] += weight; // Update the sum for this bin\n    }\n\n    // Output the final assignment of items to bins.\n    for (int i = 0; i < n; ++i) {\n        cout << assignment[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\n// Use 1-based indexing for boxes, 0-based for internal stack indices.\n// Output requires 1-based indexing for stacks.\n\nstruct BoxLocation {\n    int stack_idx; // 0-indexed\n    int pos_in_stack; // 0-indexed from bottom\n};\n\n// Global variables to store state\nstd::vector<std::vector<int>> stacks;\nstd::vector<BoxLocation> box_locations;\nstd::vector<bool> is_carried_out;\nint n_boxes, m_stacks;\nint next_box_to_carry_id = 1;\nstd::vector<std::pair<int, int>> operations; // pair {box_id, destination_stack_idx+1 or 0}\n\n// Helper to update box_locations after a stack modification\nvoid update_box_locations_in_stack(int stack_idx, const std::vector<int>& stack_content) {\n    for (int i = 0; i < stack_content.size(); ++i) {\n        int box_id = stack_content[i];\n        box_locations[box_id] = {stack_idx, i};\n    }\n}\n\n// Function to perform operation 1\n// Moves the block starting from `v_id` (and everything above it) from its current stack\n// to `dest_stack_idx`. The `v_id` is the box that initiates the move, as per problem statement.\nvoid perform_move_operation(int v_id, int dest_stack_idx) {\n    int src_stack_idx = box_locations[v_id].stack_idx;\n    int v_pos_in_src_stack = box_locations[v_id].pos_in_stack;\n    \n    std::vector<int>& src_stack = stacks[src_stack_idx];\n\n    // The block to move starts at v_id and goes to the top of the current stack.\n    int start_move_pos = v_pos_in_src_stack;\n    \n    std::vector<int> block_to_move;\n    for (int i = start_move_pos; i < src_stack.size(); ++i) {\n        block_to_move.push_back(src_stack[i]);\n    }\n    \n    // The first element of block_to_move is the box `v` for the operation.\n    // In this strategy, v_id is always `next_box_to_carry_id`, which is block_to_move[0].\n    // int op_v_id = block_to_move[0]; // This is guaranteed to be v_id in our strategy.\n\n    // Output operation (v_id, dest_stack_idx + 1). dest_stack_idx is 0-indexed.\n    operations.push_back({v_id, dest_stack_idx + 1});\n\n    // Update source stack: remove the block\n    src_stack.resize(start_move_pos);\n    // Update locations for boxes remaining in source stack\n    update_box_locations_in_stack(src_stack_idx, src_stack);\n\n    // Update destination stack: add the block\n    auto& dest_stack = stacks[dest_stack_idx];\n    for (int box_id : block_to_move) {\n        dest_stack.push_back(box_id);\n        box_locations[box_id] = {dest_stack_idx, dest_stack.size() - 1};\n    }\n}\n\nvoid solve() {\n    std::cin >> n_boxes >> m_stacks;\n\n    stacks.resize(m_stacks);\n    // box_locations will store {stack_idx, pos_in_stack} for each box ID (1 to n_boxes).\n    // Initialize with invalid values or resize as needed. Size n_boxes + 1 for 1-based indexing.\n    box_locations.resize(n_boxes + 1); \n\n    for (int i = 0; i < m_stacks; ++i) {\n        int num_boxes_in_stack = n_boxes / m_stacks; // Problem constraint\n        stacks[i].resize(num_boxes_in_stack);\n        for (int j = 0; j < num_boxes_in_stack; ++j) {\n            std::cin >> stacks[i][j];\n            // Record initial location for each box\n            box_locations[stacks[i][j]] = {i, j};\n        }\n    }\n\n    is_carried_out.resize(n_boxes + 1, false);\n\n    // Main loop: process boxes 1 to n in order.\n    while (next_box_to_carry_id <= n_boxes) {\n        int current_box_id = next_box_to_carry_id;\n        int src_stack_idx = box_locations[current_box_id].stack_idx;\n        int pos_in_stack = box_locations[current_box_id].pos_in_stack;\n        std::vector<int>& current_stack = stacks[src_stack_idx];\n\n        // Check if the current box is at the top of its stack\n        if (pos_in_stack == current_stack.size() - 1) { \n            // Operation 2: Carry out the box\n            operations.push_back({current_box_id, 0}); // 0 signifies carry-out\n            is_carried_out[current_box_id] = true;\n            current_stack.pop_back();\n            \n            // Update locations for any boxes that might have been affected (none in this case, as no boxes were above)\n            // For safety, call update on the stack, though pop_back doesn't shift elements' indices.\n            update_box_locations_in_stack(src_stack_idx, current_stack);\n            \n            next_box_to_carry_id++; // Move to the next box\n        } else { \n            // Operation 1 is required because `current_box_id` is NOT at the top.\n            // Heuristic for choosing destination stack:\n            // 1. Prefer an empty stack with the smallest index.\n            // 2. If no empty stacks exist, prefer a non-empty stack whose top element is MINIMIZED.\n            //    If there's a tie in minimum top element, pick the stack with the smallest index.\n            \n            int dest_stack_idx = -1;\n            int min_top_val = -1; // Sentinel for \"no suitable non-empty stack found yet\"\n            bool found_empty_stack = false;\n\n            for (int i = 0; i < m_stacks; ++i) {\n                if (i == src_stack_idx) continue; // Cannot move to the same stack.\n\n                if (stacks[i].empty()) {\n                    if (!found_empty_stack) { // Found the first empty stack\n                        dest_stack_idx = i;\n                        found_empty_stack = true;\n                    }\n                    // If multiple empty stacks, `dest_stack_idx` will naturally hold the smallest index encountered first.\n                } else { // Stack `i` is not empty\n                    if (!found_empty_stack) { // Only consider non-empty stacks if no empty ones were found\n                        int top_val = stacks[i].back();\n                        if (min_top_val == -1 || top_val < min_top_val) {\n                            min_top_val = top_val;\n                            dest_stack_idx = i;\n                        } else if (top_val == min_top_val) {\n                            // Tie-breaking: prefer smaller index\n                            if (i < dest_stack_idx) {\n                                dest_stack_idx = i;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Fallback: If for some reason dest_stack_idx wasn't set (e.g., m=1, which is not the case here),\n            // pick the first available stack other than the source.\n            if (dest_stack_idx == -1) {\n                 for(int i = 0; i < m_stacks; ++i) {\n                     if (i != src_stack_idx) {\n                         dest_stack_idx = i;\n                         break;\n                     }\n                 }\n            }\n\n            // Perform the move operation. The box initiating the move (v_id) is `current_box_id`.\n            perform_move_operation(current_box_id, dest_stack_idx);\n            \n            // `next_box_to_carry_id` does NOT increment because `current_box_id` is still not at the top\n            // of its NEW stack after the move. The loop will repeat for `current_box_id` again.\n        }\n    }\n\n    // Output all recorded operations\n    for (const auto& op : operations) {\n        std::cout << op.first << \" \" << op.second << \"\\n\";\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n    \n    solve();\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\nint N;\nvector<string> h_walls, v_walls;\nvector<vector<int>> d;\n\n// Adjacency list for grid graph\n// Stores pairs of {neighbor_row, neighbor_col, move_char, wall_type}\n// wall_type: 0 for no wall, 1 for horizontal wall, 2 for vertical wall\n// This information is not strictly needed if we check walls dynamically,\n// but could be useful for pathfinding. For this problem, we check walls directly.\nvector<pair<int, int>> adj[40][40];\n\nint dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar moves[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (r, c) to (nr, nc) is valid (no wall)\nbool is_valid_move(int r, int c, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n        return false;\n    }\n    if (nr == r - 1) { // Moving Up\n        if (v_walls[r][c] == '1') return false;\n    } else if (nr == r + 1) { // Moving Down\n        if (h_walls[r][c] == '1') return false;\n    } else if (nc == c - 1) { // Moving Left\n        if (v_walls[r][c-1] == '1') return false;\n    } else if (nc == c + 1) { // Moving Right\n        if (v_walls[r][c] == '1') return false;\n    }\n    return true;\n}\n\n// DFS to generate an initial path that visits all nodes\nstring initial_path_str;\nbool visited_dfs[40][40];\nint initial_path_len = 0;\nmap<pair<int, int>, int> visit_counts_dfs;\n\nvoid dfs_generate(int r, int c) {\n    visited_dfs[r][c] = true;\n    visit_counts_dfs[{r, c}]++;\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited_dfs[nr][nc]) {\n            if (is_valid_move(r, c, nr, nc)) {\n                initial_path_str += moves[i];\n                initial_path_len++;\n                dfs_generate(nr, nc);\n                initial_path_str += moves[i ^ 1]; // Move back\n                initial_path_len++;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[i];\n\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Build adjacency list implicitly by checking walls in is_valid_move\n    // DFS to generate initial path\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_dfs[i][j] = false;\n        }\n    }\n    dfs_generate(0, 0);\n    \n    // Ensure (0,0) is visited twice if DFS starts/ends there\n    // The DFS logic above adds return moves, so (0,0) is visited at start and end\n    // If initial_path_len is 0 (e.g. 1x1 grid, though N>=20), handle it.\n    if (N > 0 && initial_path_len == 0) { // For N=1, this might happen. But N>=20.\n        // If grid is just one cell (0,0), path is empty, length 0.\n        // But problem says N>=20. So DFS should generate a path.\n    }\n\n\n    // Target visit counts proportional to sqrt(d_i,j)\n    // Minimize sum( d_i,j / N_i,j^2 )\n    // Equivalent to maximizing sum( d_i,j / N_i,j^2 )\n    // For total visits V, N_i,j should be proportional to sqrt(d_i,j)\n    // N_i,j = C * sqrt(d_i,j)\n    // Sum(N_i,j) = V => C = V / Sum(sqrt(d_i,j))\n    // N_i,j = V * sqrt(d_i,j) / Sum(sqrt(d_k,m))\n\n    // Max path length is 100000.\n    // Initial path length L_dfs.\n    // Each additional visit can be achieved by a detour X->Y->X, adding 2 moves.\n    // Max number of extra visits K_max = (100000 - L_dfs) / 2\n    // Total max visits V_max = N*N + K_max\n\n    long double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((long double)d[i][j]);\n        }\n    }\n\n    int max_total_visits = 100000; // Maximum allowed path length\n\n    vector<long long> target_N(N * N, 0);\n    long long current_total_visits = 0;\n\n    // Ensure each cell is visited at least once\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            target_N[i * N + j] = 1;\n            current_total_visits++;\n        }\n    }\n    \n    // Distribute remaining visits greedily based on sqrt(d_i,j)\n    // We have `max_total_visits - current_total_visits` visits to distribute.\n    // This number is an upper bound on the sum of ADDITIONAL visits beyond the first one for each cell.\n    // Let's use the objective function to guide distribution: maximize sum(d_i,j / N_i,j^2)\n    // This implies N_i,j should be proportional to sqrt(d_i,j).\n\n    // Strategy: calculate proportional counts for all cells, then scale and adjust.\n    vector<pair<long double, pair<int, int>>> proportional_visits;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            proportional_visits.push_back({sqrt((long double)d[i][j]), {i, j}});\n        }\n    }\n    sort(proportional_visits.rbegin(), proportional_visits.rend());\n\n    // Distribute visits until total path length constraint is met.\n    // We have `max_total_visits` moves. Each visit adds at least 1 move, often 2 (detour).\n    // Let's use the rule that each visit adds 2 moves (detour)\n    // Total visits V should satisfy L_dfs + 2 * (V - N*N) <= 100000\n    // 2 * (V - N*N) <= 100000 - L_dfs\n    // V - N*N <= (100000 - L_dfs) / 2\n    // V <= N*N + (100000 - L_dfs) / 2\n    int max_additional_visits = (100000 - initial_path_len) / 2;\n    if (max_additional_visits < 0) max_additional_visits = 0;\n\n    current_total_visits = N * N; // All cells visited once initially\n\n    // Greedily assign additional visits to cells with high sqrt(d_i,j)\n    vector<long long> N_final(N * N, 1); // Start with 1 visit for each cell\n    long long visits_added_count = 0;\n\n    // First, distribute visits to reach max_additional_visits for sqrt(d_i,j) based proportional counts\n    vector<pair<long double, pair<int,int>>> sqrt_d_sorted;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) sqrt_d_sorted.push_back({sqrt((long double)d[i][j]), {i,j}});\n    sort(sqrt_d_sorted.rbegin(), sqrt_d_sorted.rend());\n    \n    for(const auto& p : sqrt_d_sorted) {\n        if (visits_added_count >= max_additional_visits) break;\n        int r = p.second.first;\n        int c = p.second.second;\n        N_final[r*N+c]++;\n        visits_added_count++;\n    }\n\n    // If we still have budget for more visits (e.g. if max_additional_visits was very large, and sum of sqrt(d_i,j) was small)\n    // we can add more visits to cells with highest d_i,j, using the priority queue logic.\n    // However, the proportional distribution up to max_additional_visits is likely optimal.\n\n    // If current_total_visits (N*N) + visits_added_count > 100000 (this check is redundant if max_additional_visits is calculated correctly)\n    // we need to cap it. But max_additional_visits ensures total length <= 100000.\n\n    // Current visit counts based on initial DFS and N_final assignment\n    map<pair<int, int>, int> current_N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_N[{i, j}] = visit_counts_dfs.count({i, j}) ? visit_counts_dfs[{i, j}] : 0;\n        }\n    }\n\n    // Adjust initial DFS counts to match N_final targets\n    // The DFS path might visit cells more than once initially.\n    // We need to reach N_final counts.\n    vector<pair<long double, pair<int, int>>> pq_cells; // (priority, {r, c})\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (current_N[{i, j}] < N_final[i * N + j]) {\n                pq_cells.push_back({ (long double)d[i][j] / (long double)(current_N[{i, j}] * current_N[{i, j}]), {i, j} });\n            }\n        }\n    }\n    sort(pq_cells.rbegin(), pq_cells.rend());\n\n    vector<pair<int, int>> cells_to_visit_extra; // Cells to add extra visits to\n    vector<int> extra_visits_count(N*N, 0);\n\n    int current_extra_visits_total = 0;\n    for(const auto& p : pq_cells) {\n        int r = p.second.first;\n        int c = p.second.second;\n        int needed = N_final[r*N+c] - current_N[{r,c}];\n        for(int k=0; k<needed; ++k) {\n            if (current_extra_visits_total >= max_additional_visits) break;\n            cells_to_visit_extra.push_back({r, c});\n            extra_visits_count[r*N+c]++;\n            current_extra_visits_total++;\n        }\n        if (current_extra_visits_total >= max_additional_visits) break;\n    }\n    \n    // Construct final path by adding detours\n    string final_path = initial_path_str;\n    int current_path_len = initial_path_len;\n\n    // Store path as sequence of cells for easier detour insertion\n    vector<pair<int, int>> path_cells;\n    path_cells.push_back({0,0});\n    int cur_r = 0, cur_c = 0;\n    for(char move : initial_path_str) {\n        if (move == 'U') cur_r--;\n        else if (move == 'D') cur_r++;\n        else if (move == 'L') cur_c--;\n        else if (move == 'R') cur_c++;\n        path_cells.push_back({cur_r, cur_c});\n    }\n\n    // Add detours\n    for (int r_target = 0; r_target < N; ++r_target) {\n        for (int c_target = 0; c_target < N; ++c_target) {\n            int count_to_add = extra_visits_count[r_target * N + c_target];\n            if (count_to_add == 0) continue;\n\n            // For each cell, add `count_to_add` detours.\n            // Simple detour: find last visit to (r_target, c_target) and insert a minimal path to it.\n            // This is complicated. A simpler approach: append detours from the END of current path.\n            // Path: P_dfs, then for each (r,c) to visit K times: append path(current_pos, r, c), append path(r,c, current_pos)\n            \n            for(int k=0; k<count_to_add; ++k) {\n                 if (current_path_len + 2 > 100000) break; // Safety break\n\n                // Find current end of path\n                cur_r = path_cells.back().first;\n                cur_c = path_cells.back().second;\n                \n                // Find shortest path from (cur_r, cur_c) to (r_target, c_target)\n                queue<pair<int, int>> q;\n                q.push({cur_r, cur_c});\n                vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited(N, vector<bool>(N, false));\n                visited[cur_r][cur_c] = true;\n                bool found = false;\n\n                while (!q.empty()) {\n                    pair<int, int> curr = q.front();\n                    q.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == r_target && c_curr == c_target) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited[nr][nc]) {\n                            visited[nr][nc] = true;\n                            parent[nr][nc] = {r_curr, c_curr};\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen as all cells are reachable */ continue; }\n\n                // Reconstruct path from (cur_r, cur_c) to (r_target, c_target)\n                vector<char> detour_fwd;\n                vector<pair<int, int>> detour_cells_fwd;\n                pair<int, int> trace = {r_target, c_target};\n                while (trace.first != cur_r || trace.second != cur_c) {\n                    pair<int, int> p_trace = parent[trace.first][trace.second];\n                    if (p_trace.first == -1) break; // Should not happen\n\n                    if (trace.first == p_trace.first - 1) detour_fwd.push_back('U');\n                    else if (trace.first == p_trace.first + 1) detour_fwd.push_back('D');\n                    else if (trace.second == p_trace.second - 1) detour_fwd.push_back('L');\n                    else if (trace.second == p_trace.second + 1) detour_fwd.push_back('R');\n                    \n                    detour_cells_fwd.push_back(trace);\n                    trace = p_trace;\n                }\n                reverse(detour_fwd.begin(), detour_fwd.end());\n                reverse(detour_cells_fwd.begin(), detour_cells_fwd.end());\n\n                // Add detour path to cells list\n                for(char move : detour_fwd) {\n                    path_cells.push_back({r_target,c_target}); // add target cell\n                    if (move == 'U') path_cells.push_back({path_cells.back().first - 1, path_cells.back().second});\n                    else if (move == 'D') path_cells.push_back({path_cells.back().first + 1, path_cells.back().second});\n                    else if (move == 'L') path_cells.push_back({path_cells.back().first, path_cells.back().second - 1});\n                    else if (move == 'R') path_cells.push_back({path_cells.back().first, path_cells.back().second + 1});\n                }\n                \n                // Add the final (r_target, c_target) cell itself\n                path_cells.push_back({r_target, c_target});\n                \n                // Now add path back to original current position (cur_r, cur_c)\n                // This is BFS from (r_target, c_target) to (cur_r, cur_c)\n                queue<pair<int, int>> q_ret;\n                q_ret.push({r_target, c_target});\n                vector<vector<pair<int, int>>> parent_ret(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited_ret(N, vector<bool>(N, false));\n                visited_ret[r_target][c_target] = true;\n                found = false;\n\n                while (!q_ret.empty()) {\n                    pair<int, int> curr = q_ret.front();\n                    q_ret.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == cur_r && c_curr == cur_c) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited_ret[nr][nc]) {\n                            visited_ret[nr][nc] = true;\n                            parent_ret[nr][nc] = {r_curr, c_curr};\n                            q_ret.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen */ continue; }\n\n                // Reconstruct path back\n                trace = {cur_r, cur_c};\n                while(trace.first != r_target || trace.second != c_target) {\n                     pair<int, int> p_trace = parent_ret[trace.first][trace.second];\n                     if (p_trace.first == -1) break;\n\n                     if (trace.first == p_trace.first - 1) path_cells.push_back({p_trace.first - 1, p_trace.second});\n                     else if (trace.first == p_trace.first + 1) path_cells.push_back({p_trace.first + 1, p_trace.second});\n                     else if (trace.second == p_trace.second - 1) path_cells.push_back({p_trace.second - 1, p_trace.second});\n                     else if (trace.second == p_trace.second + 1) path_cells.push_back({p_trace.second + 1, p_trace.second});\n                     trace = p_trace;\n                }\n\n                // Update current path length and position\n                current_path_len = path_cells.size() - 1;\n                if (current_path_len > 100000) { // Cap path length\n                    path_cells.resize(100000 + 1); // Keep start and end for length 100000\n                    current_path_len = 100000;\n                }\n            }\n        }\n    }\n\n    // Convert path_cells back to moves string, truncated if necessary\n    final_path = \"\";\n    for (size_t i = 0; i < path_cells.size() - 1; ++i) {\n        if (final_path.length() >= 100000) break;\n\n        int r1 = path_cells[i].first;\n        int c1 = path_cells[i].second;\n        int r2 = path_cells[i+1].first;\n        int c2 = path_cells[i+1].second;\n\n        if (r2 == r1 - 1) final_path += 'U';\n        else if (r2 == r1 + 1) final_path += 'D';\n        else if (c2 == c1 - 1) final_path += 'L';\n        else if (c2 == c1 + 1) final_path += 'R';\n    }\n\n    cout << final_path << endl;\n\n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <map>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nint N;\nchar grid[15][15];\nvector<string> t;\nint start_r, start_c;\n\n// For Dijkstra to find path for one string\n// dp[p][r][c]: min cost to type first p characters of target string, ending at (r,c)\n// where grid[r][c] matches the p-th character.\n// p from 1 to 5.\nlong long dp[6][15][15];\npair<int, int> pred[6][15][15]; // Stores previous coordinates to reconstruct path\n\n// Directions for BFS/Dijkstra\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nstruct State {\n    long long cost;\n    int r, c;\n\n    bool operator>(const State& other) const {\n        return cost > other.cost;\n    }\n};\n\n// Computes the minimum cost and path to type target_str starting from (sr, sc)\n// Returns {min_total_cost, end_r, end_c, sequence_of_operations}\ntuple<long long, int, int, vector<pair<int, int>>> compute_path(const string& target_str, int sr, int sc) {\n    for (int p = 0; p <= 5; ++p) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                dp[p][r][c] = INF;\n                pred[p][r][c] = {-1, -1};\n            }\n        }\n    }\n\n    char first_char = target_str[0];\n    \n    // Base case: p=1 (typing the first character)\n    // dp[1][r][c] = min cost to type first character (target_str[0]) ending at (r,c)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] == first_char) {\n                dp[1][r][c] = abs(r - sr) + abs(c - sc) + 1;\n                // pred[1][r][c] remains {-1, -1} to signify start\n            }\n        }\n    }\n\n    // Fill DP table for p = 2 to 5\n    for (int p = 2; p <= 5; ++p) {\n        char current_char_needed = target_str[p - 1];\n        \n        priority_queue<State, vector<State>, greater<State>> pq;\n        vector<vector<long long>> dist(N, vector<long long>(N, INF));\n        vector<vector<pair<int, int>>> layer_pred(N, vector<pair<int, int>>(N, {-1,-1}));\n\n        // Initialize Dijkstra PQ with costs from previous step (p-1)\n        // States in PQ are (cost_to_type_p-1_chars_ending_here, r, c)\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (dp[p - 1][r][c] != INF) {\n                    pq.push({dp[p - 1][r][c], r, c});\n                    dist[r][c] = dp[p - 1][r][c]; // dist here is min cost to reach (r,c) having typed p-1 chars\n                }\n            }\n        }\n\n        // Run Dijkstra\n        // We want to find min cost to reach any cell (nr, nc) for current_char_needed\n        // from any cell (r,c) which is a valid end for p-1 characters.\n        while (!pq.empty()) {\n            State current = pq.top();\n            pq.pop();\n\n            long long d = current.cost;\n            int r = current.r;\n            int c = current.c;\n\n            if (d > dist[r][c]) continue;\n\n            // Explore neighbors\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i];\n                int nc = c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    // Cost to move from (r,c) to (nr,nc) AND append grid[nr][nc]\n                    long long move_cost = abs(nr - r) + abs(nc - c) + 1;\n                    \n                    // If the neighbor cell (nr, nc) has the character needed for the current step (p)\n                    if (grid[nr][nc] == current_char_needed) {\n                        if (dist[r][c] + move_cost < dist[nr][nc]) {\n                            dist[nr][nc] = dist[r][c] + move_cost;\n                            layer_pred[nr][nc] = {r, c}; // Store predecessor for path reconstruction\n                            pq.push({dist[nr][nc], nr, nc});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Update DP table for step p\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (grid[r][c] == current_char_needed && dist[r][c] != INF) {\n                    dp[p][r][c] = dist[r][c];\n                    pred[p][r][c] = layer_pred[r][c]; // Store predecessor for path reconstruction\n                }\n            }\n        }\n    }\n\n    // Find the minimum cost to type the whole string (length 5)\n    long long min_total_cost = INF;\n    int final_r = -1, final_c = -1;\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[5][r][c] < min_total_cost) {\n                min_total_cost = dp[5][r][c];\n                final_r = r;\n                final_c = c;\n            }\n        }\n    }\n\n    // Reconstruct path\n    vector<pair<int, int>> path_ops;\n    if (final_r != -1) {\n        int curr_r = final_r;\n        int curr_c = final_c;\n        for (int p = 5; p >= 1; --p) {\n            path_ops.push_back({curr_r, curr_c});\n            if (p > 1) { // For p=1, pred is {-1,-1}\n                pair<int, int> prev_pos = pred[p][curr_r][curr_c];\n                curr_r = prev_pos.first;\n                curr_c = prev_pos.second;\n            }\n        }\n        reverse(path_ops.begin(), path_ops.end());\n    }\n    \n    return {min_total_cost, final_r, final_c, path_ops};\n}\n\n// Helper to check if string 'needle' is a substring of 'haystack'\nbool contains(const string& haystack, const string& needle) {\n    return haystack.find(needle) != string::npos;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M >> start_r >> start_c;\n    --start_r; --start_c; // 0-indexed\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    t.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> t[i];\n    }\n\n    vector<pair<int, int>> operations;\n    set<int> uncovered_indices;\n    for (int i = 0; i < M; ++i) {\n        uncovered_indices.insert(i);\n    }\n\n    int current_r = start_r;\n    int current_c = start_c;\n    long long total_cost = 0;\n    \n    // We can perform at most 5000 operations.\n    // Our strategy is to greedily type the cheapest full string that is not yet covered.\n    // Each typed string requires 5 operations.\n    // We continue this until we have typed 1000 strings (total 5000 operations)\n    // or until all strings are covered.\n\n    int max_strings_to_type = 1000; \n\n    for (int iter = 0; iter < max_strings_to_type; ++iter) {\n        if (uncovered_indices.empty()) break; // All strings are covered\n\n        long long min_iter_cost = INF;\n        int best_t_idx = -1;\n        int best_end_r = -1, best_end_c = -1;\n        vector<pair<int, int>> ops_for_best_t;\n\n        // Find the cheapest string to type among the currently uncovered ones\n        for (int idx : uncovered_indices) {\n            auto [cost, end_r, end_c, current_ops] = compute_path(t[idx], current_r, current_c);\n            \n            if (cost < min_iter_cost) {\n                min_iter_cost = cost;\n                best_t_idx = idx;\n                best_end_r = end_r;\n                best_end_c = end_c;\n                ops_for_best_t = current_ops;\n            }\n        }\n\n        // If no string can be typed (e.g., required chars not on grid, which is guaranteed not to happen)\n        if (best_t_idx == -1) { \n            break;\n        }\n\n        // Append operations for the chosen string\n        operations.insert(operations.end(), ops_for_best_t.begin(), ops_for_best_t.end());\n        current_r = best_end_r;\n        current_c = best_end_c;\n        total_cost += min_iter_cost;\n        \n        // Remove the typed string from the set of uncovered indices\n        uncovered_indices.erase(best_t_idx);\n    }\n\n    // Output the operations\n    cout << operations.size() << endl;\n    for (const auto& op : operations) {\n        cout << op.first + 1 << \" \" << op.second + 1 << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath> // Included for completeness, though not directly used in the final strategy.\n#include <iomanip> // Included for completeness, though not directly used in the final strategy.\n#include <utility> // Required for std::pair.\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // This can significantly speed up input/output operations, which is crucial\n    // for problems with large I/O or strict time limits.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // The size of the island grid (N x N). Constraints: 10 <= N <= 20.\n    int m; // The number of unexplored oil fields. Constraints: 2 <= M <= 20.\n    double epsilon; // The error parameter for the noisy divine query operation. Constraints: 0.01 <= epsilon <= 0.2.\n\n    // Read the initial problem parameters from standard input.\n    std::cin >> n >> m >> epsilon;\n\n    // Read the shapes of the M oil fields.\n    // Each shape is defined by its area (d) and a list of relative coordinates\n    // for the squares it occupies.\n    // For the chosen strategy (drilling every square), this information is not directly used.\n    // A more complex heuristic or optimization strategy might leverage these shapes\n    // to infer potential locations or prune search spaces.\n    for (int k = 0; k < m; ++k) {\n        int d; // The number of squares in the k-th oil field (area).\n        std::cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int r, c; // Relative coordinates (row, column) of a square within the k-th oil field shape.\n            std::cin >> r >> c;\n            // The current strategy ignores these shapes.\n        }\n    }\n\n    // This vector will store the coordinates (row, column) of all squares\n    // that are found to contain oil reserves (i.e., v(i,j) > 0).\n    // This list will form the basis of our final \"guess\" operation.\n    std::vector<std::pair<int, int>> positive_oil_squares;\n\n    // --- Chosen Strategy: Drill every square on the island ---\n    //\n    // This is a deterministic, brute-force approach. It queries each of the N*N squares\n    // individually to reveal its exact oil reserve value v(i,j).\n    //\n    // Cost Analysis:\n    // - Operation Type: \"Drill\" (q 1 i j). Cost per operation: 1.\n    // - Total number of squares on the island: N*N.\n    // - Total cost for performing N*N drill operations: N*N.\n    //\n    // Operation Limit Analysis:\n    // - The problem statement allows a maximum of 2*N*N operations in total.\n    // - For the maximum island size N=20, N*N = 400 operations, and 2*N*N = 800 operations.\n    // - The N*N cost of this strategy is well within the allowed operation limit.\n    //\n    // Correctness Guarantee:\n    // - By drilling every square, we obtain the exact value of v(i,j) for every cell.\n    // - This guarantees that we can precisely identify *all* squares where v(i,j) > 0.\n    // - The final \"guess\" operation will therefore be 100% accurate, leading to a successful completion.\n    //\n    // Justification for ignoring the \"divine\" operation:\n    // - The \"divine\" operation (querying a set S of k squares) has a cost of 1/sqrt(k) but returns a noisy sum.\n    // - The noise (variance) increases with k, making it difficult to obtain precise information about individual v(i,j) values,\n    //   especially small values or distinguishing v(i,j)=0 from v(i,j)=1.\n    // - To guarantee identifying *all* squares with v(i,j) > 0, definitive information is required. Drilling provides this.\n    // - Given the small constraints on N (N <= 20), the total cost of N*N is sufficiently low. The guaranteed correctness\n    //   and simplicity of the drilling strategy make it a robust choice for achieving a high score. More complex strategies\n    //   involving divine queries might offer marginal benefits only for much larger grid sizes.\n    //\n    // Implementation Loop:\n    // - We iterate through each row 'i' from 0 to N-1.\n    // - Within each row, we iterate through each column 'j' from 0 to N-1.\n    // - For every square (i, j), we issue a \"drill\" query.\n    // - We then read the revealed oil reserves for that square.\n    // - If the reserves are positive, we record the square's coordinates.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            // Output the drill query command: \"q 1 <row> <column>\"\n            // std::endl automatically flushes the output buffer.\n            std::cout << \"q 1 \" << i << \" \" << j << std::endl;\n\n            int reserves; // The value v(i, j) revealed for the current square.\n            std::cin >> reserves; // Read the result from standard input.\n\n            // If the square contains oil (reserves > 0), store its coordinates.\n            if (reserves > 0) {\n                positive_oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // --- Output the Final Guess ---\n    //\n    // Once all squares have been drilled, the 'positive_oil_squares' vector contains\n    // the exact set of squares that have oil reserves. We now form the final \"guess\" operation.\n    //\n    // The format for the guess operation is: \"a <d> <i1> <j1> <i2> <j2> ...\"\n    // where 'd' is the total number of squares guessed to have oil.\n    std::cout << \"a \" << positive_oil_squares.size();\n    for (const auto& p : positive_oil_squares) {\n        std::cout << \" \" << p.first << \" \" << p.second;\n    }\n    std::cout << std::endl; // Flush the output buffer to ensure the guess is sent.\n\n    // --- Read Confirmation from Judge ---\n    //\n    // The judge will respond with '1' if our guess is correct and '0' if it is incorrect.\n    // Given the deterministic nature of the drilling strategy, we expect this to always be '1'.\n    int correct;\n    std::cin >> correct;\n\n    // If the guess was correct, the program has successfully completed its task.\n    if (correct == 1) {\n        return 0; // Exit with a success code.\n    } else {\n        // If the guess was incorrect (correct == 0), this indicates an unexpected issue.\n        // The N^2 drilling strategy is designed to be infallible for this problem.\n        // If this branch is reached, it might point to a subtle problem interpretation error\n        // or an extremely rare edge case. We exit with a non-zero code to signal abnormal termination.\n        return 1; \n    }\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n#include <string> // For structure names\n\nusing namespace std;\n\nlong long W;\nint D, N;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    long long area;\n};\n\n// Structure to hold a list of N rectangles and their total cost for a particular partition layout.\nstruct PartitionStructure {\n    vector<Rect> rects; // The N generated rectangles for this structure. Order might not be important initially.\n    long long total_cost = -1; // The total area cost over all days using this structure and greedy assignment.\n    string name; // A descriptive name for the structure (e.g., \"VerticalStrips\").\n\n    // Comparator for sorting Rects by area in descending order.\n    static bool compareRects(const Rect& a, const Rect& b) {\n        return a.area > b.area;\n    }\n};\n\n// --- Partition Generation Functions ---\n\n// Recursive helper function to generate rectangles for a balanced subdivision.\n// It splits the current bounding box (x0,y0)-(x1,y1) into `count_needed` rectangles.\n// The split is always along the larger dimension to try and maintain aspect ratios closer to 1.\nvoid generate_recursive_helper(vector<Rect>& rects, int x0, int y0, int x1, int y1, int count_needed) {\n    if (count_needed == 0) return;\n\n    // Base case: if only one rectangle is needed, create it.\n    if (count_needed == 1) {\n        rects.push_back({x0, y0, x1, y1, (long long)(x1 - x0) * (y1 - y0)});\n        return;\n    }\n\n    long long total_width = x1 - x0;\n    long long total_height = y1 - y0;\n\n    // Divide `count_needed` into two parts for the children.\n    int num_left_child = count_needed / 2;\n    int num_right_child = count_needed - num_left_child;\n\n    // Split along the larger dimension.\n    if (total_width >= total_height) { // Split vertically\n        // Calculate the split point `mid_x` such that the resulting child areas are proportional to the number of rectangles they will hold.\n        long long mid_x = x0 + total_width * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, mid_x, y1, num_left_child);\n        generate_recursive_helper(rects, mid_x, y0, x1, y1, num_right_child);\n    } else { // Split horizontally\n        long long mid_y = y0 + total_height * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, x1, mid_y, num_left_child);\n        generate_recursive_helper(rects, x0, mid_y, x1, y1, num_right_child);\n    }\n}\n\n// Initializes the generation of N rectangles using the recursive subdivision strategy.\nvoid generate_recursive_rects(vector<Rect>& rects, int num_rects) {\n    generate_recursive_helper(rects, 0, 0, W, W, num_rects);\n}\n\n// Generates N vertical strips of as equal width as possible.\nvoid generate_vertical_strips(vector<Rect>& rects, int num_strips) {\n    long long base_w = W / num_strips;\n    long long remainder_w = W % num_strips; // Number of strips that will get an extra pixel of width.\n    int current_x = 0;\n    for (int i = 0; i < num_strips; ++i) {\n        long long w = base_w + (i < remainder_w ? 1 : 0);\n        if (w > 0) { // Ensure width is positive (important if N > W, though constraints prevent this).\n            rects.push_back({current_x, 0, current_x + (int)w, (int)W, w * W});\n            current_x += w;\n        }\n    }\n}\n\n// Generates N horizontal strips of as equal height as possible.\nvoid generate_horizontal_strips(vector<Rect>& rects, int num_strips) {\n    long long base_h = W / num_strips;\n    long long remainder_h = W % num_strips; // Number of strips that will get an extra pixel of height.\n    int current_y = 0;\n    for (int i = 0; i < num_strips; ++i) {\n        long long h = base_h + (i < remainder_h ? 1 : 0);\n        if (h > 0) { // Ensure height is positive.\n            rects.push_back({0, current_y, (int)W, current_y + (int)h, W * h});\n            current_y += h;\n        }\n    }\n}\n\n// --- Cost Calculation ---\n\n// Calculates the total area cost for a given partition structure across all days.\n// It uses greedy assignment: the i-th largest desired area is assigned to the i-th largest available base rectangle area.\n// This strategy assumes a fixed partition layout for all days, thus partition change cost is effectively zero.\nlong long calculate_total_cost(const vector<Rect>& base_rects_for_structure, const vector<vector<pair<int, int>>>& a_d_k_sorted_by_area) {\n    // Create a mutable copy of the base rectangles and sort them by area in descending order.\n    vector<Rect> sorted_base_rects = base_rects_for_structure;\n    sort(sorted_base_rects.begin(), sorted_base_rects.end(), PartitionStructure::compareRects);\n\n    // Extract just the sorted areas of the base rectangles.\n    vector<long long> sorted_base_areas(N);\n    for (int i = 0; i < N; ++i) {\n        sorted_base_areas[i] = sorted_base_rects[i].area;\n    }\n\n    long long current_total_area_cost = 0;\n    // Iterate through each day to calculate its area cost.\n    for (int d = 0; d < D; ++d) {\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; // This is already sorted by area descending.\n\n        // Greedily assign the i-th largest desired area to the i-th largest available base rectangle area.\n        for (int i = 0; i < N; ++i) {\n            long long required_area = daily_reservations_sorted[i].first;\n            long long assigned_area = sorted_base_areas[i];\n            current_total_area_cost += 100LL * max(0LL, required_area - assigned_area);\n        }\n    }\n    \n    return current_total_area_cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> W >> D >> N;\n\n    // Store desired areas for each reservation on each day.\n    // `a_d_k_sorted_by_area[d][i]` will store {area, original_k} for the reservation\n    // that has the i-th largest area on day `d`.\n    vector<vector<pair<int, int>>> a_d_k_sorted_by_area(D, vector<pair<int, int>>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a_d_k_sorted_by_area[d][k].first;\n            a_d_k_sorted_by_area[d][k].second = k; // Store original index (0 to N-1).\n        }\n        // Sort reservations for day `d` by area in descending order.\n        sort(a_d_k_sorted_by_area[d].rbegin(), a_d_k_sorted_by_area[d].rend());\n    }\n\n    vector<PartitionStructure> candidate_structures;\n\n    // --- Generate candidate partition structures ---\n\n    // Structure 1: Recursive balanced subdivision.\n    vector<Rect> rects1;\n    generate_recursive_rects(rects1, N);\n    candidate_structures.push_back({rects1, -1, \"RecursiveBalanced\"});\n\n    // Structure 2: Vertical strips.\n    vector<Rect> rects2;\n    generate_vertical_strips(rects2, N);\n    candidate_structures.push_back({rects2, -1, \"VerticalStrips\"});\n\n    // Structure 3: Horizontal strips.\n    vector<Rect> rects3;\n    generate_horizontal_strips(rects3, N);\n    candidate_structures.push_back({rects3, -1, \"HorizontalStrips\"});\n\n    // --- Evaluate each structure ---\n    long long min_total_cost = -1;\n    int best_structure_idx = -1;\n\n    // Iterate through all candidate structures, calculate their total cost, and find the best one.\n    for (int i = 0; i < candidate_structures.size(); ++i) {\n        candidate_structures[i].total_cost = calculate_total_cost(candidate_structures[i].rects, a_d_k_sorted_by_area);\n        \n        // Update best structure if this one is better.\n        if (best_structure_idx == -1 || candidate_structures[i].total_cost < min_total_cost) {\n            min_total_cost = candidate_structures[i].total_cost;\n            best_structure_idx = i;\n        }\n    }\n\n    // --- Output the best structure ---\n    const auto& best_structure = candidate_structures[best_structure_idx];\n    \n    // The output requires rectangles for each day, in the order of the original input reservations for that day.\n    // We need to determine which of the N base rectangles from the best structure is assigned to which original reservation `k` for each day `d`.\n\n    // Get the N base rectangles from the chosen best structure.\n    vector<Rect> N_base_rects_from_best_structure = best_structure.rects;\n\n    // Sort these N rectangles by area in descending order. This sorted list represents the available slots\n    // when applying the greedy assignment strategy (i-th largest area slot is sorted_base_rects_by_area[i]).\n    vector<Rect> sorted_base_rects_by_area = N_base_rects_from_best_structure;\n    sort(sorted_base_rects_by_area.begin(), sorted_base_rects_by_area.end(), PartitionStructure::compareRects);\n\n    // `assignments_per_day[d][k]` will store the Rect object (coordinates) assigned to the original reservation `k` on day `d`.\n    vector<vector<Rect>> assignments_per_day(D, vector<Rect>(N));\n\n    // For each day, map the sorted reservations to the sorted base rectangles.\n    for (int d = 0; d < D; ++d) {\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; // Sorted by area descending ({area, original_k})\n        \n        // Iterate through the ranks of reservations by area (i=0 is largest area reservation).\n        for (int i = 0; i < N; ++i) {\n            // Get the original index of the reservation that has the i-th largest area on day `d`.\n            int original_reservation_k = daily_reservations_sorted[i].second; \n            \n            // Assign the i-th largest base rectangle (sorted_base_rects_by_area[i])\n            // to this reservation `original_reservation_k` for day `d`.\n            assignments_per_day[d][original_reservation_k] = sorted_base_rects_by_area[i];\n        }\n    }\n\n    // Output the assignments in the required format: N lines for day 0, then N for day 1, etc.,\n    // where the k-th line corresponds to the k-th original reservation for that day.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) { // Output for reservation k (original index) on day d.\n            const Rect& r = assignments_per_day[d][k];\n            cout << r.x0 << \" \" << r.y0 << \" \" << r.x1 << \" \" << r.y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <tuple>\n#include <algorithm>\n\nusing namespace std;\n\n// Use long long for N, M, K to be safe, though they are small in constraints.\n// Renamed to avoid potential conflicts or confusion with problem-defined variables if problem used N, M, K directly in context.\nlong long N_val, M_val, K_val; \nlong long MOD = 998244353;\n\n// The board values can grow large, so use long long.\nvector<vector<long long>> board;\n// Stamp values are given and used, also use long long for consistency.\nvector<vector<vector<long long>>> stamps;\n// Stores the chosen operations: {stamp_index, row_p, col_q}\nvector<tuple<int, int, int>> operations;\n\n// Function to calculate the gain of applying a specific stamp at a specific position.\n// Gain is defined as the total increase in the sum of (cell_value mod MOD) over all affected cells.\n// This sum can be negative if applying the stamp decreases the total score modulo MOD.\nlong long calculate_gain(int stamp_idx, int p, int q) {\n    long long current_gain_sum = 0; // This sum can be negative.\n    \n    // Iterate over the 3x3 area of the stamp.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int r = p + i; // Row on the board\n            int c = q + j; // Column on the board\n\n            // Current score contribution of the cell (r, c)\n            // This is board[r][c] modulo MOD.\n            long long current_score_contrib = board[r][c] % MOD;\n            \n            // Value from the stamp at (i, j)\n            long long stamp_val = stamps[stamp_idx][i][j];\n            \n            // New score contribution of the cell (r, c) after adding the stamp value.\n            // (board[r][c] + stamp_val) can be large, but % MOD brings it to the score range.\n            long long new_score_contrib = (board[r][c] + stamp_val) % MOD;\n            \n            // The change in score for this specific cell.\n            // This difference can be negative if new_score_contrib < current_score_contrib (due to modulo wrap-around).\n            long long delta = new_score_contrib - current_score_contrib;\n            \n            // Add the cell's score change to the total gain for this stamp operation.\n            current_gain_sum += delta;\n        }\n    }\n    return current_gain_sum;\n}\n\n// Applies a chosen stamp to the board and records the operation.\nvoid apply_stamp(int stamp_idx, int p, int q) {\n    operations.emplace_back(stamp_idx, p, q);\n    \n    // Update the board values by adding the stamp values.\n    // Note: board[r][c] stores the accumulated sum, not modulo MOD.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            board[p + i][q + j] += stamps[stamp_idx][i][j];\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input values for N, M, K.\n    cin >> N_val >> M_val >> K_val;\n\n    // Initialize the board with given values.\n    board.resize(N_val, vector<long long>(N_val));\n    for (int i = 0; i < N_val; ++i) {\n        for (int j = 0; j < N_val; ++j) {\n            cin >> board[i][j];\n        }\n    }\n\n    // Read stamp definitions.\n    stamps.resize(M_val, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M_val; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n\n    // Greedy strategy:\n    // In each step, select the stamp operation that yields the maximum immediate score increase.\n    // We can perform AT MOST K_val operations.\n    // If the best operation provides a non-positive gain (i.e., zero or negative),\n    // it means no further score improvement is possible with this greedy approach, so we stop.\n    for (int k = 0; k < K_val; ++k) {\n        // Initialize max_gain to a very small value. A sufficiently small negative number\n        // guarantees that any actual gain (positive, zero, or negative) will be greater.\n        long long max_gain = -4e18; // Using a very small number to ensure any gain is larger.\n        int best_m = -1, best_p = -1, best_q = -1;\n\n        // Iterate over all possible stamp types (M_val).\n        for (int m = 0; m < M_val; ++m) {\n            // Iterate over all possible top-left positions (p, q) for the stamp.\n            // A 3x3 stamp can be placed with its top-left corner at (p, q)\n            // such that p ranges from 0 to N_val-3, and q ranges from 0 to N_val-3.\n            for (int p = 0; p <= N_val - 3; ++p) {\n                for (int q = 0; q <= N_val - 3; ++q) {\n                    // Calculate the score gain if we apply stamp 'm' at position (p, q).\n                    long long current_gain = calculate_gain(m, p, q);\n                    \n                    // If this operation gives a better gain than any seen so far, update our best choice.\n                    if (current_gain > max_gain) {\n                        max_gain = current_gain;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // After checking all possible operations, if the maximum gain found is strictly positive,\n        // apply the best operation. Otherwise, stop.\n        if (max_gain > 0) {\n            apply_stamp(best_m, best_p, best_q);\n        } else {\n            // No operation yields a positive score increase.\n            // Adhering to \"at most K times\" and aiming to maximize score, we terminate.\n            break; \n        }\n    }\n\n    // Output the number of operations performed.\n    cout << operations.size() << endl;\n    // Output each operation: stamp index, board row, board column.\n    for (const auto& op : operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << endl;\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int MAX_TURNS = 10000;\nint N;\n\n// Grid state\nvector<vector<int>> grid; // container ID, -1 if empty\nvector<vector<int>> crane_id_at; // crane ID, -1 if empty\n\n// Crane state\nstruct Crane {\n    int id;\n    pair<int, int> pos;\n    int holding_container_id; // -1 if not holding\n    bool is_large;\n    int base_priority; // For task assignment logic\n};\nvector<Crane> cranes;\n\n// Container state is implicitly managed by grid and crane_holding_id\n\n// Receiving Gate state\nvector<int> receiving_gate_next_container_idx; // For each receiving gate i, index into A[i]\n\n// Dispatch Gate state\nvector<int> dispatch_gate_expected_container; // For each dispatch gate i, the ID of the next container to be dispatched. -1 if all dispatched.\n\n// Container to Target Gate mapping\nvector<int> container_target_gate;\n\n// Temporary storage cells\nvector<pair<int, int>> temp_storage_cells;\n\n// Helper to check if a cell is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Helper to get target dispatch gate for a container\nint get_target_gate(int container_id) {\n    if (container_id < 0) return -1; // Should not happen for valid containers\n    return container_id / N;\n}\n\n// Greedy best-step pathfinding to target_pos\npair<int, int> get_next_step(pair<int, int> current_pos, pair<int, int> target_pos) {\n    if (current_pos == target_pos) return current_pos;\n\n    int r = current_pos.first;\n    int c = current_pos.second;\n    int tr = target_pos.first;\n    int tc = target_pos.second;\n\n    int dr = tr - r;\n    int dc = tc - c;\n\n    // Prioritize moving vertically if difference is larger or equal, otherwise horizontally.\n    if (abs(dr) >= abs(dc)) { \n        if (dr > 0) return {r + 1, c}; // D\n        else if (dr < 0) return {r - 1, c}; // U\n    }\n    // If vertical difference is smaller or zero, prioritize horizontal movement.\n    if (abs(dc) > abs(dr)) {\n        if (dc > 0) return {r, c + 1}; // R\n        else if (dc < 0) return {r, c - 1}; // L\n    }\n    \n    // Fallback: This should ideally not be reached if current_pos != target_pos.\n    // It means dr=0 and dc=0, which is handled by the initial check.\n    return current_pos; \n}\n\n// Crane Task types for priority\nenum TaskType {\n    WAIT,\n    PICKUP_REC,       // Pickup from Receiving Gate\n    PICKUP_TEMP,      // Pickup from Temporary Storage\n    STORE_CONTAINER,  // Store container in Temporary Storage\n    DELIVER_TO_GATE   // Deliver container to Dispatch Gate\n};\n\n// Structure to hold a crane's task and its priority\nstruct CraneTask {\n    TaskType type;\n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n};\n\n// Function to determine the crane's highest priority task\nCraneTask determine_crane_task(int crane_idx) {\n    Crane& crane = cranes[crane_idx];\n    pair<int, int> current_pos = crane.pos;\n\n    // Assign base priority. Large crane has highest base priority.\n    // Small cranes have priority decreasing with their initial index.\n    // Adjusted priorities for better separation and SC distinctiveness.\n    int current_base_priority = crane.is_large ? 1000 : 100 * (N - 1 - crane_idx); \n\n    // Task 4: DELIVER_TO_GATE\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n        \n        // Check if the container is the *next expected* for its target dispatch gate\n        if (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]) {\n            pair<int, int> deliver_pos = {target_gate, N - 1};\n            // Highest priority task: DELIVER_TO_GATE\n            return {DELIVER_TO_GATE, deliver_pos, current_base_priority + 100}; // Very high priority\n        }\n    }\n\n    // Task 1 & 2: PICKUP_REQ (from Receiving Gate or Temp Storage) for required containers\n    if (crane.holding_container_id == -1) { // Only pick up if not holding anything\n        // Check for required containers at dispatch gates\n        for (int i = 0; i < N; ++i) { // Iterate through dispatch gates\n            int expected_container_id = dispatch_gate_expected_container[i];\n            if (expected_container_id != -1) { // If a container is still expected for this gate\n                // Check if this container belongs to gate i (redundant check but good for clarity)\n                if (get_target_gate(expected_container_id) == i) {\n                    // Find its current location\n                    // Check Receiving Gates (Task 1: PICKUP_REC)\n                    if (grid[i][0] == expected_container_id) {\n                        // High priority: PICKUP_REC for required container\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 80}; // High priority\n                    }\n                    // Check Temporary Storage Cells (Task 2: PICKUP_TEMP)\n                    for (const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == expected_container_id) {\n                            // High priority: PICKUP_TEMP for required container\n                            return {PICKUP_TEMP, cell, current_base_priority + 70}; // High priority\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 3: STORE_CONTAINER\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n\n        // If the container is NOT the next one needed for its dispatch gate, and we have somewhere to store it.\n        bool is_needed_now = (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]);\n        if (!is_needed_now) {\n            pair<int, int> temp_storage_target = {-1, -1};\n            for (const auto& cell : temp_storage_cells) {\n                // Cell must be empty (no container, no crane)\n                if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                    temp_storage_target = cell;\n                    break;\n                }\n            }\n            if (temp_storage_target != make_pair(-1, -1)) {\n                // Medium priority: STORE_CONTAINER\n                return {STORE_CONTAINER, temp_storage_target, current_base_priority + 50}; // Medium priority\n            }\n        }\n    }\n    \n    // Task 1 (low priority): Proactive fetch from Receiving Gates\n    // Only if not holding a container and not already going to pick up a *required* container\n    if (crane.holding_container_id == -1) {\n        for (int i = 0; i < N; ++i) { // Iterate through receiving gates\n            if (receiving_gate_next_container_idx[i] < N) { // If containers are still arriving\n                // Check if cell (i,0) has an arrived container and is not occupied by a crane\n                if (grid[i][0] != -1 && crane_id_at[i][0] == -1) { \n                    // Check if there's an available temporary storage cell to move it to\n                    pair<int, int> temp_storage_target = {-1, -1};\n                    for(const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                            temp_storage_target = cell;\n                            break;\n                        }\n                    }\n                    if (temp_storage_target != make_pair(-1, -1)) {\n                        // Low priority: PICKUP_REC (proactive)\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 20}; // Low priority\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 0: WAIT\n    return {WAIT, current_pos, current_base_priority}; // Default to WAIT\n}\n\n// Structure to hold a crane's requested move for collision resolution\nstruct MoveRequest {\n    int crane_idx;\n    // Renamed 'type' to 'task_kind' to avoid potential compiler issues with reserved names or conflicts.\n    TaskType task_kind; \n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n\n    bool operator<(const MoveRequest& other) const {\n        // Sort by priority descending. If priorities are equal, sort by crane_idx ascending\n        // to ensure deterministic behavior.\n        if (priority != other.priority) {\n            return priority > other.priority;\n        }\n        return crane_idx < other.crane_idx; \n    }\n};\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    grid.assign(N, vector<int>(N, -1));\n    crane_id_at.assign(N, vector<int>(N, -1));\n    receiving_gate_next_container_idx.assign(N, 0);\n    dispatch_gate_expected_container.assign(N, -1); // Initialize with -1\n\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n        }\n    }\n\n    // Initialize container_target_gate mapping\n    container_target_gate.resize(N * N);\n    for (int i = 0; i < N * N; ++i) {\n        container_target_gate[i] = get_target_gate(i);\n    }\n\n    // Initialize dispatch gate expected containers\n    for (int i = 0; i < N; ++i) {\n        dispatch_gate_expected_container[i] = N * i;\n    }\n\n    // Initialize cranes\n    cranes.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].id = i;\n        cranes[i].pos = {i, 0};\n        cranes[i].holding_container_id = -1;\n        cranes[i].is_large = (i == 0);\n        // Base priority: LC highest, SCs decreasing.\n        cranes[i].base_priority = (i == 0) ? 1000 : 100 * (N - 1 - i); \n\n        crane_id_at[i][0] = i; // Place cranes on grid\n    }\n\n    // Initialize temporary storage cells. Aim for inner cells, away from edges.\n    // Prioritize cells further from receiving/dispatch gates.\n    for (int r = 1; r < N - 1; ++r) {\n        for (int c = 1; c < N - 1; ++c) {\n            temp_storage_cells.push_back({r, c});\n        }\n    }\n    // If N is small (e.g., N=1, N=2), the inner grid might not exist. Add cells from other rows/columns if available.\n    // Add cells on inner columns (not edges) first.\n    if (temp_storage_cells.empty() && N > 1) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 1; c < N - 1; ++c) { // Cells not on the left edge (receiving gates)\n                temp_storage_cells.push_back({r, c});\n            }\n        }\n    }\n    // Add remaining cells if still empty (e.g., N=1 or N=2).\n    if (temp_storage_cells.empty() && N > 1) { // Avoid adding (0,0) which is LC start\n         for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Avoid receiving gates (c=0), dispatch gates (c=N-1), and LC start position for initial temp cells\n                // Prefer inner cells (c=1 to N-2).\n                if (c > 0 && c < N-1) { \n                     temp_storage_cells.push_back({r,c});\n                }\n            }\n        }\n    }\n    // Sort temp storage cells by distance from LC start {0,0} to potentially prioritize closer ones first for initial storage.\n    sort(temp_storage_cells.begin(), temp_storage_cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n        int dist_a = abs(a.first - 0) + abs(a.second - 0);\n        int dist_b = abs(b.first - 0) + abs(b.second - 0);\n        return dist_a < dist_b;\n    });\n\n\n    vector<string> output_ops(N, \"\");\n\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        // Step 1: Container Arrival\n        for (int i = 0; i < N; ++i) { // For each receiving gate row i\n            if (receiving_gate_next_container_idx[i] < N) {\n                // Place container if receiving gate cell (i,0) is empty (no container, no crane)\n                if (grid[i][0] == -1 && crane_id_at[i][0] == -1) {\n                    int container_id = A[i][receiving_gate_next_container_idx[i]];\n                    grid[i][0] = container_id;\n                    receiving_gate_next_container_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        vector<MoveRequest> requests;\n        \n        // Determine desired tasks for all cranes\n        for (int i = 0; i < N; ++i) {\n            CraneTask task = determine_crane_task(i);\n            requests.push_back({i, task.type, task.target_pos, task.priority});\n        }\n\n        // Sort requests by priority (highest first). The operator< in MoveRequest handles this.\n        sort(requests.begin(), requests.end());\n\n        // `next_crane_id_at` stores the state of crane positions *after* all actions in this turn are resolved.\n        vector<vector<int>> next_crane_id_at = crane_id_at; \n        \n        // Keep track of the final state for each crane after its action for this turn.\n        vector<pair<int, int>> final_crane_pos(N);\n        vector<int> final_crane_holding(N);\n        vector<char> final_crane_action(N);\n        vector<bool> crane_action_committed(N, false); // Track if crane committed to an action/move\n\n        // Initialize with current state, assuming no action initially.\n        for(int i=0; i<N; ++i) {\n            final_crane_pos[i] = cranes[i].pos;\n            final_crane_holding[i] = cranes[i].holding_container_id;\n            final_crane_action[i] = '.';\n        }\n\n        // Iterate through sorted requests to resolve conflicts.\n        for (const auto& req : requests) {\n            int k = req.crane_idx; // Current crane index\n\n            // If crane k has already committed to an action (e.g., due to higher priority or being part of a prior committed move), skip.\n            if (crane_action_committed[k]) continue;\n\n            Crane& current_crane_state = cranes[k]; // Reference to the actual crane object\n            pair<int, int> current_pos = current_crane_state.pos; // Its position BEFORE this turn's action\n            \n            // Determine the intended next position and action based on the request.\n            pair<int, int> intended_next_pos = current_pos;\n            char intended_action_char = '.';\n            bool action_possible = true;\n\n            // Assign intended action based on task type\n            if (req.task_kind == DELIVER_TO_GATE || req.task_kind == STORE_CONTAINER) { // Tasks involving releasing a container\n                if (current_pos == req.target_pos) { // Already at target for Q action\n                    intended_action_char = 'Q';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to eventually drop\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target (already there or blocked by logic)\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else if (req.task_kind == PICKUP_REC || req.task_kind == PICKUP_TEMP) { // Tasks involving picking up a container\n                if (current_pos == req.target_pos) { // Already at target for P action\n                    intended_action_char = 'P';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to pick up\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else { // WAIT or other task not requiring specific movement now\n                intended_action_char = '.';\n                intended_next_pos = current_pos;\n            }\n\n            // --- Collision and Constraint Checking ---\n            \n            // 1. Basic validity of destination\n            if (!is_valid(intended_next_pos.first, intended_next_pos.second)) {\n                action_possible = false; // Cannot move out of bounds\n            }\n\n            // 2. Check for crane-crane conflicts at destination (intended_next_pos)\n            // This check depends on the state *after* higher priority cranes have committed their moves.\n            // `next_crane_id_at` stores committed crane positions for the next turn.\n            if (action_possible && intended_next_pos != current_pos && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1) {\n                // Destination is occupied by another crane. Since `next_crane_id_at` is updated progressively,\n                // if it's occupied by `occupying_crane_id` != `k`, it means `occupying_crane_id` has higher or equal priority and has already committed to being there.\n                // Thus, crane `k` cannot move to `intended_next_pos`.\n                action_possible = false; \n            }\n\n            // 3. Small crane carrying container to a cell with a container (not allowed)\n            if (action_possible && !current_crane_state.is_large && current_crane_state.holding_container_id != -1) {\n                if (grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Small crane carrying cannot move to cell with a container\n                }\n            }\n            \n            // 4. If intended action is Pick/Drop, check if the cell itself is valid for the action\n            if (action_possible && (intended_action_char == 'P' || intended_action_char == 'Q')) {\n                // Cell must contain the container for 'P', and be empty for 'Q' (except for the crane)\n                // Check if the cell has a container if trying to pick up\n                if (intended_action_char == 'P' && grid[current_pos.first][current_pos.second] == -1) {\n                    action_possible = false; // Cannot pick up from empty cell\n                }\n                // Check if the cell is already occupied by a container if trying to drop\n                // This check must consider the state *after* crane movement, so check `grid` at `intended_next_pos`.\n                if (intended_action_char == 'Q' && grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Cannot drop into an occupied cell\n                }\n                // If attempting P/Q, the destination cell must not be occupied by another crane.\n                // This is already handled by point 2 for movement, but P/Q is an action at the *current* pos or *intended_next_pos*.\n                // If action is 'P', current_pos = intended_next_pos.\n                // If action is 'Q', intended_next_pos is the target.\n                if (next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1 && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != k) {\n                     action_possible = false; // Cannot P/Q if destination cell occupied by other crane\n                }\n            }\n\n\n            if (action_possible) {\n                // Crane k successfully commits to its action and move.\n                final_crane_action[k] = intended_action_char;\n                final_crane_pos[k] = intended_next_pos;\n                crane_action_committed[k] = true;\n\n                // Update crane's holding status and grid state if 'P' or 'Q'\n                if (intended_action_char == 'P') {\n                    // Crane picks up container from its current cell.\n                    int container_id = grid[current_pos.first][current_pos.second]; \n                    grid[current_pos.first][current_pos.second] = -1; // Remove container from cell\n                    final_crane_holding[k] = container_id; // Crane now holds it\n                } else if (intended_action_char == 'Q') {\n                    // Crane drops container at its intended next position.\n                    int container_id = current_crane_state.holding_container_id;\n                    grid[intended_next_pos.first][intended_next_pos.second] = container_id; // Place container in destination cell\n                    final_crane_holding[k] = -1; // Crane no longer holds it\n                }\n                \n                // Update `next_crane_id_at` for collision detection for *subsequent* (lower priority) cranes in this turn.\n                // Mark old position as empty, new position as occupied by crane k.\n                if (current_pos != intended_next_pos) { // Only update if crane actually moved\n                    next_crane_id_at[current_pos.first][current_pos.second] = -1; \n                    next_crane_id_at[intended_next_pos.first][intended_next_pos.second] = k;\n                } else {\n                    // If crane stayed put (action '.' or 'P'/'Q' at same spot), its position in next_crane_id_at is already correct from initialization.\n                    // If P/Q happened at current_pos, it still occupies current_pos.\n                }\n            } else {\n                // Crane k is blocked or action is impossible. It stays put and does nothing.\n                final_crane_action[k] = '.';\n                final_crane_pos[k] = current_pos; // Stays at current position\n                final_crane_holding[k] = current_crane_state.holding_container_id; // Holding status unchanged\n                // crane_action_committed[k] remains false. Its position in next_crane_id_at is unchanged.\n            }\n        }\n        \n        // Apply the final state changes for all cranes after conflict resolution.\n        for(int i=0; i<N; ++i) {\n            cranes[i].pos = final_crane_pos[i];\n            cranes[i].holding_container_id = final_crane_holding[i];\n            output_ops[i] += final_crane_action[i];\n        }\n        // Update crane_id_at to reflect the final positions for the START of the next turn.\n        crane_id_at = next_crane_id_at; \n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; ++i) { // For each dispatch gate row i\n            if (dispatch_gate_expected_container[i] != -1 && grid[i][N - 1] != -1) {\n                if (grid[i][N - 1] == dispatch_gate_expected_container[i]) {\n                    // Dispatch container\n                    grid[i][N - 1] = -1; // Remove from dispatch gate\n                    \n                    // Update expected container for this dispatch gate\n                    dispatch_gate_expected_container[i]++;\n                    if (dispatch_gate_expected_container[i] >= N * (i + 1)) {\n                        dispatch_gate_expected_container[i] = -1; // All containers for this gate dispatched\n                    }\n                }\n            }\n        }\n        \n        // Optional: Early exit condition if all containers are dispatched.\n        // This might save time if the simulation finishes before MAX_TURNS.\n        bool all_dispatched = true;\n        for(int i=0; i<N; ++i) {\n            if (dispatch_gate_expected_container[i] != -1) {\n                all_dispatched = false;\n                break;\n            }\n        }\n        if (all_dispatched && turn > 0) { // Check if all were dispatched in this turn or previous\n             // Break loop, padding will handle the rest.\n             // However, the problem states output length must be between 1 and 10000.\n             // So, we must ensure padding up to MAX_TURNS if we break early.\n             // The padding at the end handles this.\n             break; \n        }\n    }\n\n    // Pad output strings with '.' if they are shorter than MAX_TURNS\n    for (int i = 0; i < N; ++i) {\n        while (output_ops[i].length() < MAX_TURNS) {\n            output_ops[i] += '.';\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << output_ops[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n\nusing namespace std;\n\nint N;\nvector<vector<int>> current_height;\npair<int, int> current_pos;\nlong long truck_load;\nvector<string> operations;\n\n// Helper to add an operation to the list.\nvoid add_op(const string& op) {\n    operations.push_back(op);\n}\n\n// Helper to add a load ('+') or unload ('-') operation with a specified amount 'd'.\nvoid add_load_unload(char type, long long d) {\n    // The problem statement specifies d > 0 for load/unload.\n    // Our logic derives d from height differences, which are at most 100, so d will always be > 0 if called.\n    add_op(string(1, type) + to_string(d));\n}\n\n// Helper function to move the truck from its current position to a target cell.\n// It generates the sequence of move operations ('U', 'D', 'L', 'R') and updates current_pos.\nvoid move_to(int target_r, int target_c) {\n    // Move vertically: Up or Down\n    while (current_pos.first < target_r) {\n        add_op(\"D\");\n        current_pos.first++;\n    }\n    while (current_pos.first > target_r) {\n        add_op(\"U\");\n        current_pos.first--;\n    }\n    // Move horizontally: Left or Right\n    while (current_pos.second < target_c) {\n        add_op(\"R\");\n        current_pos.second++;\n    }\n    while (current_pos.second > target_c) {\n        add_op(\"L\");\n        current_pos.second--;\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output, crucial for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the grid size N.\n    cin >> N;\n\n    // Initialize the current_height grid with input heights. This grid will be modified as soil is moved.\n    current_height.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> current_height[i][j];\n        }\n    }\n\n    // Initialize truck state: starting at (0,0) with an empty load.\n    current_pos = {0, 0};\n    truck_load = 0;\n\n    // --- Define a systematic traversal path (Snake Pattern) ---\n    // This path visits every cell in the grid exactly once. It's chosen as a heuristic\n    // to ensure all cells are processed and to provide a structured, deterministic movement.\n    // The path order is (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> (1,N-2) -> ... -> (1,0) -> (2,0) -> ...\n    vector<pair<int, int>> snake_path;\n    snake_path.reserve(N * N); // Reserve memory to avoid reallocations for efficiency.\n    for (int r = 0; r < N; ++r) {\n        if (r % 2 == 0) { // Even rows: traverse from left to right.\n            for (int c = 0; c < N; ++c) {\n                snake_path.push_back({r, c});\n            }\n        } else { // Odd rows: traverse from right to left.\n            for (int c = N - 1; c >= 0; --c) {\n                snake_path.push_back({r, c});\n            }\n        }\n    }\n\n    // --- Pass 1: Collect all positive soil ---\n    // The goal of this pass is to visit all cells that initially have positive height\n    // and load all of their soil onto the truck. This ensures all soil that needs to be\n    // moved out of positive cells is gathered before distribution.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell in the snake path.\n\n        // If the cell has excess soil (positive height), load it onto the truck.\n        if (current_height[r][c] > 0) {\n            long long amount_to_load = current_height[r][c]; // The amount to load is the entire positive height.\n            add_load_unload('+', amount_to_load); // Add the load operation.\n            truck_load += amount_to_load; // Update truck's current load.\n            current_height[r][c] = 0; // The cell's height becomes zero after its excess soil is loaded.\n        }\n    }\n\n    // --- Pass 2: Distribute soil to negative cells ---\n    // After collecting all available soil in Pass 1, this pass aims to unload soil\n    // into cells that need it (have negative height).\n    // The truck's position `current_pos` is already at the end of the last move from Pass 1,\n    // allowing for continuous movement through the grid for this pass.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If the cell needs soil (has negative height).\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c]; // Calculate how much soil is needed (absolute value of negative height).\n            // Unload the minimum of what's needed for this cell and what's currently available on the truck.\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) { // If we can unload any soil (i.e., truck has soil and cell needs it).\n                add_load_unload('-', to_unload); // Add the unload operation.\n                truck_load -= to_unload; // Update truck's load.\n                current_height[r][c] += to_unload; // Add soil to the cell, reducing its deficit.\n            }\n        }\n    }\n\n    // --- Pass 3: Deliver any remaining truck load ---\n    // This is a crucial cleanup pass designed to resolve any remaining imbalances.\n    // It addresses two potential scenarios:\n    // 1. If `truck_load` is still positive after Pass 2, it means there's soil left on the truck\n    //    that needs to be delivered to some cell.\n    // 2. If some cells still have negative height after Pass 2, they still require soil.\n    // The snake path is traversed for a third time. This ensures that any remaining soil on the truck\n    // is delivered to cells that still have a deficit, thereby bringing all cell heights to zero.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If this cell still needs soil, unload from the truck.\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c];\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) {\n                add_load_unload('-', to_unload);\n                truck_load -= to_unload;\n                current_height[r][c] += to_unload;\n            }\n        }\n    }\n\n    // The problem statement guarantees that the sum of initial heights across the grid is exactly 0.\n    // This fundamental property ensures that the total amount of soil loaded in Pass 1 will be\n    // exactly equal to the total amount of soil that needs to be unloaded into negative-height cells.\n    // Therefore, after these three passes, `truck_load` is guaranteed to be 0, and all `current_height` values\n    // are guaranteed to be 0. No further loops or checks are needed to ensure all cells are leveled.\n    // The `min(needed, truck_load)` logic in Passes 2 and 3 handles the distribution correctly.\n\n    // Output all the generated operations, one per line.\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <numeric> // Not strictly necessary as sum is manual, but good practice to include if using numeric algorithms.\n#include <algorithm> // For std::sort\n\n// Use long long for sums to avoid potential overflow.\n// With M=15 and max value 100 per component, the max sum for a single seed is 15*100 = 1500,\n// which fits in a 32-bit integer. However, using `long long` is safer practice and has no performance penalty here.\nusing ll = long long;\n\n// Structure to hold seed information: its identifier, evaluation vector, and sum of values.\nstruct Seed {\n    int id; // Identifier of the seed within the current generation (0 to seed_count-1).\n    std::vector<int> evaluation_vector;\n    ll sum_v;\n\n    // Custom comparison operator for sorting seeds by sum_v in descending order.\n    // std::sort uses operator< to sort in ascending order. By defining it such that\n    // `a < b` if `a.sum_v > b.sum_v`, we achieve descending order sorting.\n    bool operator<(const Seed& other) const {\n        return sum_v > other.sum_v;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // Disables synchronization with C stdio and unties cin from cout for faster I/O.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, T;\n    std::cin >> N >> M >> T;\n\n    // Total number of seeds in each generation.\n    // For N=6, this is 2 * 6 * (6 - 1) = 2 * 6 * 5 = 60 seeds.\n    int seed_count = 2 * N * (N - 1);\n\n    // Vector to hold the current generation of seeds.\n    std::vector<Seed> current_seeds(seed_count);\n\n    // Read initial seeds. Their initial indices are implicitly 0, 1, ..., seed_count-1.\n    for (int i = 0; i < seed_count; ++i) {\n        current_seeds[i].id = i; // Assign initial ID for this seed.\n        current_seeds[i].evaluation_vector.resize(M);\n        ll current_sum = 0;\n        for (int j = 0; j < M; ++j) {\n            std::cin >> current_seeds[i].evaluation_vector[j];\n            current_sum += current_seeds[i].evaluation_vector[j];\n        }\n        current_seeds[i].sum_v = current_sum;\n    }\n\n    // Main loop for T turns of the operation.\n    for (int t = 0; t < T; ++t) {\n        // 1. Sort the current seeds based on their sum_v in descending order.\n        // The `std::sort` function uses the `operator<` defined in the `Seed` struct.\n        std::sort(current_seeds.begin(), current_seeds.end());\n\n        // 2. Select the top N*N seeds for planting.\n        // These are the first N*N seeds in the sorted `current_seeds` vector.\n        // We need to output their `id`s arranged in the N*N grid.\n        std::vector<std::vector<int>> A(N, std::vector<int>(N));\n        \n        // Assign selected seeds to grid cells in row-major order.\n        // The seed placed at A[i][j] is the (i*N + j)-th best seed from the sorted list.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                // `current_seeds[i * N + j]` refers to the Seed struct which is the (i*N + j)-th best.\n                // Its `id` field holds the identifier of this seed within the current generation.\n                A[i][j] = current_seeds[i * N + j].id;\n            }\n        }\n\n        // 3. Output the grid assignment to standard output.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                std::cout << A[i][j] << (j == N - 1 ? \"\" : \" \"); // Space separated values, no space after last element in a row.\n            }\n            std::cout << std::endl; // Newline after each row.\n        }\n        std::cout.flush(); // Ensure the output is sent immediately to the judge.\n\n        // 4. Read the evaluation vectors of the newly generated seeds for the next generation.\n        std::vector<Seed> next_seeds(seed_count);\n        for (int i = 0; i < seed_count; ++i) {\n            // Assign new sequential IDs (0 to seed_count-1) for the seeds in the next generation.\n            next_seeds[i].id = i; \n            next_seeds[i].evaluation_vector.resize(M);\n            ll current_sum = 0;\n            for (int j = 0; j < M; ++j) {\n                std::cin >> next_seeds[i].evaluation_vector[j];\n                current_sum += next_seeds[i].evaluation_vector[j];\n            }\n            next_seeds[i].sum_v = current_sum;\n        }\n\n        // 5. Replace the current seeds with the newly generated ones.\n        // `std::move` is used for efficiency, as it transfers ownership of the\n        // `next_seeds` vector's internal buffer to `current_seeds` without copying elements.\n        current_seeds = std::move(next_seeds);\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <numeric> // For std::iota\n\n// Global variables for grid and arm parameters\nint N_GRID, M_TAKOYAKI, V_ARM;\n\n// Structure for 2D points\nstruct Point {\n    int r, c;\n    // Equality operators for comparisons\n    bool operator==(const Point& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Manhattan distance for grid movement cost\nint manhattan_distance(Point p1, Point p2) {\n    return std::abs(p1.r - p2.r) + std::abs(p1.c - p2.c);\n}\n\n// --- Arm Design Parameters ---\nint V_prime; // Actual number of vertices in the arm (<= V_ARM)\nstd::vector<int> parent_map; // parent_map[i] is parent of vertex i+1 (0-indexed for edge array)\nstd::vector<int> edge_lengths; // edge_lengths[i] is length of edge connected to vertex i+1\nstd::vector<int> edge_orientations; // Current orientation of edges: 0:R(0,+1), 1:D(+1,0), 2:L(0,-1), 3:U(-1,0)\n\nPoint root_pos; // Current position of the arm's root\nstd::vector<Point> vertex_pos; // Stores current positions of all arm vertices\nstd::vector<int> fingertip_vertex_ids; // Vertex IDs that are fingertips\nstd::vector<int> joint_vertex_ids; // Vertex IDs that are joints (internal nodes, can rotate subtrees)\n\n// Direction vectors for R, D, L, U\nint dr[] = {0, 1, 0, -1}; // Corresponds to orientations 0, 1, 2, 3\nint dc[] = {1, 0, -1, 0}; // Corresponds to orientations 0, 1, 2, 3\n\n// Function to calculate the positions of all vertices based on root_pos and edge_orientations\nvoid calculate_vertex_positions() {\n    vertex_pos.assign(V_prime, {0, 0});\n    vertex_pos[0] = root_pos;\n\n    // Use BFS-like approach to calculate positions layer by layer\n    // For a tree, we can use a queue or simply iterate based on parent-child relationships.\n    // Let's build adjacency list for easier traversal.\n    std::vector<std::vector<std::pair<int, int>>> adj(V_prime); // {child_vertex_id, edge_index}\n    std::vector<int> edge_idx_for_child(V_prime, -1); // edge_idx_for_child[v] gives index for edge (p,v)\n\n    for (int i = 0; i < V_prime - 1; ++i) {\n        int p = parent_map[i];\n        int child = i + 1; // Vertex ID of child in path graph\n        adj[p].push_back({child, i});\n        edge_idx_for_child[child] = i;\n    }\n\n    std::vector<int> q;\n    q.push_back(0);\n    std::vector<bool> visited(V_prime, false);\n    visited[0] = true;\n\n    int head = 0;\n    while(head < q.size()) {\n        int u = q[head++];\n        \n        // Iterate through children of u\n        for (auto& edge_info : adj[u]) {\n            int v = edge_info.first;\n            int edge_idx = edge_info.second;\n\n            if (!visited[v]) {\n                int orientation = edge_orientations[edge_idx];\n                int length = edge_lengths[edge_idx];\n                \n                vertex_pos[v].r = vertex_pos[u].r + dr[orientation] * length;\n                vertex_pos[v].c = vertex_pos[u].c + dc[orientation] * length;\n                \n                q.push_back(v);\n                visited[v] = true;\n            }\n        }\n    }\n}\n\n// --- Takoyaki and Target Management ---\nstruct Takoyaki {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_taken; // Whether this takoyaki is currently held by a fingertip\n};\nstruct Target {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_filled; // Whether this target square is occupied by a takoyaki\n};\n\nstd::vector<Takoyaki> takoyaki_list;\nstd::vector<Target> target_list;\n\n// --- Fingertip State Management ---\nstruct Fingertip {\n    int vertex_id; // The vertex ID of this fingertip in the arm\n    bool is_holding; // True if currently holding a takoyaki\n    int holding_takoyaki_idx; // Index in takoyaki_list if holding, -1 otherwise\n    int assigned_pickup_source_idx; // Index in takoyaki_list for planned pickup, -1 if none\n    int assigned_drop_target_idx; // Index in target_list for planned drop, -1 if none\n};\nstd::vector<Fingertip> fingertips;\n\n// --- Operation String Generation ---\n// Generates the operation string for the current turn.\nstd::string generate_operation_string(int current_turn) {\n    std::string S(2 * V_prime, '.'); // Initialize with no operations\n\n    // 1. Update Arm Positions: Calculate current positions of all vertices.\n    calculate_vertex_positions();\n\n    // 2. Task Assignment: Assign takoyaki to free fingertips and targets to holding fingertips.\n    // Reset previous assignments for this turn.\n    for (auto& ft : fingertips) {\n        ft.assigned_pickup_source_idx = -1;\n        ft.assigned_drop_target_idx = -1;\n    }\n    \n    // Greedily assign pickups to fingertips that are not holding anything.\n    std::vector<bool> source_assigned_for_pickup(takoyaki_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (!ft.is_holding) { // If fingertip is empty\n            int best_takoyaki_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2; // Initialize with a large distance\n\n            // Find the closest available takoyaki\n            for (size_t j = 0; j < takoyaki_list.size(); ++j) {\n                if (!takoyaki_list[j].is_taken && !source_assigned_for_pickup[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], takoyaki_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_takoyaki_idx = j;\n                    }\n                }\n            }\n            // Assign the best takoyaki if found\n            if (best_takoyaki_idx != -1) {\n                ft.assigned_pickup_source_idx = best_takoyaki_idx;\n                source_assigned_for_pickup[best_takoyaki_idx] = true;\n            }\n        }\n    }\n\n    // Greedily assign drops to fingertips that are holding a takoyaki.\n    std::vector<bool> target_assigned_for_drop(target_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (ft.is_holding) { // If fingertip is holding\n            int best_target_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2;\n\n            // Find the closest available target\n            for (size_t j = 0; j < target_list.size(); ++j) {\n                if (!target_list[j].is_filled && !target_assigned_for_drop[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], target_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_target_idx = j;\n                    }\n                }\n            }\n            // Assign the best target if found\n            if (best_target_idx != -1) {\n                ft.assigned_drop_target_idx = best_target_idx;\n                target_assigned_for_drop[best_target_idx] = true;\n            }\n        }\n    }\n    \n    // 3. Determine Root Move (S[0])\n    int total_delta_r = 0;\n    int total_delta_c = 0;\n    int num_tasks_with_goal = 0;\n\n    // Calculate the aggregated movement required by all fingertips towards their goals\n    for (auto& ft : fingertips) {\n        Point current_pos = vertex_pos[ft.vertex_id];\n        Point goal_pos = {-1, -1}; // Sentinel value indicating no assigned goal\n\n        if (ft.is_holding) { // If holding, the goal is to reach its assigned drop target\n            if (ft.assigned_drop_target_idx != -1) {\n                goal_pos = target_list[ft.assigned_drop_target_idx].pos;\n            }\n        } else { // If not holding, the goal is to reach its assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1) {\n                goal_pos = takoyaki_list[ft.assigned_pickup_source_idx].pos;\n            }\n        }\n\n        // If a goal is assigned, contribute its delta to the total\n        if (goal_pos.r != -1) {\n            total_delta_r += (goal_pos.r - current_pos.r);\n            total_delta_c += (goal_pos.c - current_pos.c);\n            num_tasks_with_goal++;\n        }\n    }\n\n    // Determine the dominant direction for root movement\n    char root_move = '.'; // Default to no movement\n    if (num_tasks_with_goal > 0) {\n        int abs_delta_r = std::abs(total_delta_r);\n        int abs_delta_c = std::abs(total_delta_c);\n\n        // Prioritize movement in the direction with larger displacement sum\n        if (abs_delta_r > abs_delta_c) {\n            if (total_delta_r > 0) root_move = 'D'; // Move Down if total delta_r is positive\n            else if (total_delta_r < 0) root_move = 'U'; // Move Up if total delta_r is negative\n        } else if (abs_delta_c > abs_delta_r) {\n            if (total_delta_c > 0) root_move = 'R'; // Move Right if total delta_c is positive\n            else if (total_delta_c < 0) root_move = 'L'; // Move Left if total delta_c is negative\n        } else { // If tied, pick one direction, e.g., prefer vertical then horizontal\n            if (total_delta_r > 0) root_move = 'D';\n            else if (total_delta_r < 0) root_move = 'U';\n            else if (total_delta_c > 0) root_move = 'R';\n            else if (total_delta_c < 0) root_move = 'L';\n        }\n    }\n    S[0] = root_move; // Set the root movement character\n\n    // 4. Rotations (S[1] to S[V_prime-1])\n    // Currently, this strategy does NOT implement rotations for simplicity and speed.\n    // All rotation characters remain '.'\n    // If performance is insufficient, rotations for joints (vertices 1 to V_prime-2) could be added.\n\n    // 5. Fingertip Actions (S[V_prime] to S[2*V_prime-1])\n    // The action for vertex `vid` is at index `V_prime + vid` in string S.\n    for (const auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = '.'; // Default to no action\n        Point current_pos = vertex_pos[vid];\n        \n        if (ft.is_holding) { // If currently holding a takoyaki\n            // Check if at the assigned drop target\n            if (ft.assigned_drop_target_idx != -1 && current_pos == target_list[ft.assigned_drop_target_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        } else { // If not holding any takoyaki\n            // Check if at the assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1 && current_pos == takoyaki_list[ft.assigned_pickup_source_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        }\n        S[V_prime + vid] = action; // Set the action character for this vertex\n    }\n\n    return S;\n}\n\n// --- State Update Function ---\n// Applies the operations from the generated string and updates the game state.\nvoid apply_operation(const std::string& op_string) {\n    // Update root position based on the first character (root move)\n    char root_move = op_string[0];\n    if (root_move == 'U') root_pos.r--;\n    else if (root_move == 'D') root_pos.r++;\n    else if (root_move == 'L') root_pos.c--;\n    else if (root_move == 'R') root_pos.c++;\n\n    // Update rotations - THIS PART IS NOT IMPLEMENTED FOR NOW.\n    // The logic would go here if rotations were to be used.\n\n    // Apply fingertip actions ('P' for pickup/drop)\n    for (auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = op_string[V_prime + vid]; // Action character for this vertex\n        \n        if (action == 'P') {\n            if (ft.is_holding) { // Finger was holding, attempting to drop\n                int target_idx = ft.assigned_drop_target_idx;\n                // Check if the fingertip is at the assigned target location\n                if (target_idx != -1 && target_list[target_idx].pos == vertex_pos[vid]) {\n                    // Successfully dropped takoyaki\n                    target_list[target_idx].is_filled = true; // Mark target as filled\n                    takoyaki_list[ft.holding_takoyaki_idx].is_taken = false; // Release the takoyaki from being \"taken\"\n                    \n                    ft.is_holding = false; // Fingertip is now empty\n                    ft.holding_takoyaki_idx = -1; // No longer holding a takoyaki\n                    ft.assigned_drop_target_idx = -1; // Clear the drop assignment\n                } else {\n                    // If 'P' action occurs but not at target, it's an invalid/ineffective action.\n                    // This indicates a potential issue in assignment or movement logic.\n                }\n            } else { // Finger was not holding, attempting to pick up\n                int source_idx = ft.assigned_pickup_source_idx;\n                // Check if the fingertip is at the assigned source location\n                if (source_idx != -1 && takoyaki_list[source_idx].pos == vertex_pos[vid]) {\n                    // Successfully picked up takoyaki\n                    takoyaki_list[source_idx].is_taken = true; // Mark takoyaki as taken\n                    ft.is_holding = true; // Fingertip is now holding\n                    ft.holding_takoyaki_idx = source_idx; // Record which takoyaki is held\n                    ft.assigned_pickup_source_idx = -1; // Clear the pickup assignment\n                } else {\n                    // If 'P' action occurs but not at source, it's an invalid/ineffective action.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Read input parameters\n    std::cin >> N_GRID >> M_TAKOYAKI >> V_ARM;\n\n    // Read initial takoyaki positions\n    takoyaki_list.resize(M_TAKOYAKI);\n    int current_takoyaki_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store takoyaki: {position, initial_index, is_taken=false}\n                takoyaki_list[current_takoyaki_idx] = {{i, j}, current_takoyaki_idx, false};\n                current_takoyaki_idx++;\n            }\n        }\n    }\n\n    // Read target positions\n    target_list.resize(M_TAKOYAKI);\n    int current_target_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store target: {position, initial_index, is_filled=false}\n                target_list[current_target_idx] = {{i, j}, current_target_idx, false};\n                current_target_idx++;\n            }\n        }\n    }\n\n    // --- Design the Robotic Arm ---\n    V_prime = V_ARM; // Use the maximum available vertices\n    parent_map.resize(V_prime - 1);\n    edge_lengths.resize(V_prime - 1);\n    edge_orientations.resize(V_prime - 1);\n    vertex_pos.resize(V_prime); // Pre-allocate space for vertex positions\n    fingertips.clear();\n    joint_vertex_ids.clear();\n\n    // Arm Design: Path graph 0-1-2-...-V-1\n    // Parent of vertex i+1 is vertex i.\n    // Edge lengths are uniformly 1.\n    // Initial edge orientations are all 0 (Right).\n    for (int i = 0; i < V_prime - 1; ++i) {\n        parent_map[i] = i;          // Parent of vertex i+1 is vertex i\n        edge_lengths[i] = 1;        // Edge length is 1\n        edge_orientations[i] = 0;   // Initial orientation is Right (0)\n    }\n\n    // Initial root position: Center of the grid.\n    root_pos = {N_GRID / 2, N_GRID / 2};\n\n    // Identify fingertips and joints based on the path graph structure.\n    if (V_prime == 1) {\n        // If only one vertex, it's the root and also a fingertip. No joints.\n        fingertip_vertex_ids.push_back(0);\n    } else {\n        // For V' > 1, vertices 0 and V'-1 are leaves (fingertips).\n        fingertip_vertex_ids.push_back(0);\n        fingertip_vertex_ids.push_back(V_prime - 1);\n        // Vertices 1 to V'-2 are internal nodes (joints) where rotations can occur.\n        for (int i = 1; i < V_prime - 1; ++i) {\n            joint_vertex_ids.push_back(i);\n        }\n    }\n\n    // Initialize fingertip state trackers.\n    fingertips.resize(fingertip_vertex_ids.size());\n    for (size_t i = 0; i < fingertip_vertex_ids.size(); ++i) {\n        fingertips[i].vertex_id = fingertip_vertex_ids[i];\n        fingertips[i].is_holding = false;\n        fingertips[i].holding_takoyaki_idx = -1; // Tracks index in takoyaki_list IF holding\n        fingertips[i].assigned_pickup_source_idx = -1; // Tracks index in takoyaki_list for planned pickup\n        fingertips[i].assigned_drop_target_idx = -1; // Tracks index in target_list for planned drop\n    }\n\n    // Output the designed robotic arm structure.\n    std::cout << V_prime << std::endl;\n    for (int i = 0; i < V_prime - 1; ++i) {\n        std::cout << parent_map[i] << \" \" << edge_lengths[i] << std::endl;\n    }\n    std::cout << root_pos.r << \" \" << root_pos.c << std::endl;\n\n    // --- Operation Phase ---\n    int delivered_count = 0;\n    int max_turns = 100000; // Set a limit to prevent TLE.\n\n    // Main loop for executing turns.\n    for (int turn = 0; turn < max_turns; ++turn) {\n        // If all takoyaki are delivered, stop early.\n        if (delivered_count == M_TAKOYAKI) {\n            break;\n        }\n\n        // Generate the operation string for the current turn.\n        std::string op_string = generate_operation_string(turn);\n        \n        // Output the operation string.\n        std::cout << op_string << std::endl;\n        \n        // Apply the generated operations to update the game state.\n        apply_operation(op_string);\n\n        // Recalculate the number of delivered takoyaki after applying operations.\n        delivered_count = 0;\n        for(const auto& target : target_list) {\n            if (target.is_filled) {\n                delivered_count++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <map>\n\nstruct Point {\n    int x, y;\n    int type; // 0 for mackerel, 1 for sardine\n};\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n;\n    std::cin >> n;\n\n    std::vector<Point> points(2 * n);\n    std::vector<int> x_coords_all, y_coords_all;\n    x_coords_all.reserve(2 * n);\n    y_coords_all.reserve(2 * n);\n\n    for (int i = 0; i < 2 * n; ++i) {\n        points[i].type = (i < n) ? 0 : 1;\n        std::cin >> points[i].x >> points[i].y;\n        x_coords_all.push_back(points[i].x);\n        y_coords_all.push_back(points[i].y);\n    }\n\n    // Sort and unique coordinates to get candidate boundary points.\n    std::sort(x_coords_all.begin(), x_coords_all.end());\n    x_coords_all.erase(std::unique(x_coords_all.begin(), x_coords_all.end()), x_coords_all.end());\n    std::sort(y_coords_all.begin(), y_coords_all.end());\n    y_coords_all.erase(std::unique(y_coords_all.begin(), y_coords_all.end()), y_coords_all.end());\n\n    // K_cand is the number of candidate coordinate values to consider along each axis.\n    // A larger K_cand increases the chances of finding an optimal rectangle but also increases runtime.\n    // K_cand = 100 is chosen to balance search space and performance.\n    int K_cand = 100; \n\n    std::vector<int> sx, sy;\n    sx.reserve(K_cand);\n    sy.reserve(K_cand);\n\n    // Always include the bounding box coordinates 0 and 100000.\n    sx.push_back(0);\n    sx.push_back(100000);\n    sy.push_back(0);\n    sy.push_back(100000);\n\n    // Select K_cand-2 points from all unique x-coordinates, attempting to space them evenly.\n    // This ensures candidate boundaries cover the distribution of points.\n    if (x_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            // Select index: (i * (total_unique - 1)) / (num_points_to_select - 1)\n            // This samples points from the available unique coordinates.\n            sx.push_back(x_coords_all[(i * (x_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (x_coords_all.size() > 0) {\n        // If there are fewer than 2 unique coordinates (excluding 0 and 100000 if they are not present),\n        // add some of the existing unique coordinates to ensure some variation.\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, x_coords_all.size()); ++i) {\n            sx.push_back(x_coords_all[i]);\n        }\n    }\n    \n    // Select K_cand-2 points from all unique y-coordinates, similar to x-coordinates.\n    if (y_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            sy.push_back(y_coords_all[(i * (y_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (y_coords_all.size() > 0) {\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, y_coords_all.size()); ++i) {\n            sy.push_back(y_coords_all[i]);\n        }\n    }\n    \n    // Sort and remove duplicates from candidate coordinates to ensure valid intervals.\n    std::sort(sx.begin(), sx.end());\n    sx.erase(std::unique(sx.begin(), sx.end()), sx.end());\n    std::sort(sy.begin(), sy.end());\n    sy.erase(std::unique(sy.begin(), sy.end()), sy.end());\n\n    int num_sx = sx.size();\n    int num_sy = sy.size();\n\n    // `grid_diff` is a 2D difference array.\n    // `grid_diff[i][j]` stores the value that starts contributing to cells starting at `sx[i]` and `sy[j]`.\n    // Specifically, it applies a value change to the grid cell starting at `[sx[i], sx[i+1]) x [sy[j], sy[j+1])`.\n    // The size is `num_sx` x `num_sy` to handle points correctly.\n    std::vector<std::vector<int>> grid_diff(num_sx, std::vector<int>(num_sy, 0));\n\n    for (const auto& p : points) {\n        // Determine the grid cell index `ix` for point `p.x`.\n        // `ix` should be the index `i` such that `sx[i] <= p.x < sx[i+1]`.\n        // `std::upper_bound(sx.begin(), sx.end(), p.x)` finds the first element `sx[k]` strictly greater than `p.x`.\n        // The index `k` indicates that `p.x` is in the interval `[sx[k-1], sx[k])`. So `ix = k-1`.\n        auto it_x = std::upper_bound(sx.begin(), sx.end(), p.x);\n        int ix = (it_x - sx.begin()) - 1;\n        \n        // Similarly, determine the grid cell index `iy` for point `p.y`.\n        auto it_y = std::upper_bound(sy.begin(), sy.end(), p.y);\n        int iy = (it_y - sy.begin()) - 1;\n        \n        int val = (p.type == 0 ? 1 : -1); // +1 for mackerel, -1 for sardine.\n\n        // Apply the difference array update.\n        // `val` is added at the top-left corner of the cell `(ix, iy)`.\n        // It's subtracted at `(ix+1, iy)` and `(ix, iy+1)` to limit its effect to the cell `(ix, iy)`.\n        // It's added back at `(ix+1, iy+1)` to correct the double subtraction.\n        // Indices must be within bounds.\n        if (ix < num_sx && iy < num_sy) {\n            grid_diff[ix][iy] += val;\n            if (ix + 1 < num_sx) grid_diff[ix + 1][iy] -= val;\n            if (iy + 1 < num_sy) grid_diff[ix][iy + 1] -= val;\n            if (ix + 1 < num_sx && iy + 1 < num_sy) grid_diff[ix + 1][iy + 1] += val;\n        }\n    }\n    \n    // `grid_ps[i][j]` will store the cumulative sum for the rectangle `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n    // This is computed using 2D prefix sums on `grid_diff`.\n    std::vector<std::vector<int>> grid_ps(num_sx, std::vector<int>(num_sy, 0));\n    for (int i = 0; i < num_sx; ++i) {\n        for (int j = 0; j < num_sy; ++j) {\n            grid_ps[i][j] = grid_diff[i][j];\n            if (i > 0) grid_ps[i][j] += grid_ps[i-1][j];\n            if (j > 0) grid_ps[i][j] += grid_ps[i][j-1];\n            if (i > 0 && j > 0) grid_ps[i][j] -= grid_ps[i-1][j-1];\n        }\n    }\n\n    // Lambda function `get_ps_val` to safely retrieve prefix sum values.\n    // It handles out-of-bounds indices (e.g., for calculations involving `index-1`) by returning 0.\n    // `grid_ps[r_idx][c_idx]` stores the sum of points `p` such that `p.x < sx[r_idx+1]` and `p.y < sy[c_idx+1]`.\n    auto get_ps_val = [&](int r_idx, int c_idx) {\n        if (r_idx < 0 || c_idx < 0) return 0;\n        // Clamp indices to be within the bounds of grid_ps.\n        // This handles cases where calculation might exceed max index.\n        r_idx = std::min(r_idx, num_sx - 1);\n        c_idx = std::min(c_idx, num_sy - 1);\n        return grid_ps[r_idx][c_idx];\n    };\n\n    long long max_score_diff = -2e18; // Initialize with a very small value to find the maximum.\n    int best_x1_idx = -1, best_x2_idx = -1, best_y1_idx = -1, best_y2_idx = -1;\n\n    // Iterate through all possible rectangles defined by pairs of candidate coordinates.\n    // A rectangle is defined by its bottom-left corner (sx[i1], sy[j1]) and top-right corner (sx[i2], sy[j2]).\n    for (int i1 = 0; i1 < num_sx; ++i1) {\n        for (int i2 = i1; i2 < num_sx; ++i2) {\n            for (int j1 = 0; j1 < num_sy; ++j1) {\n                for (int j2 = j1; j2 < num_sy; ++j2) {\n                    \n                    // Variable to store the score difference (mackerels - sardines) for the current rectangle.\n                    long long current_score_diff = 0; \n\n                    // Calculate the score for the rectangle defined by [sx[i1], sx[i2]] x [sy[j1], sy[j2]].\n                    // This score is calculated using the 2D prefix sums for a rectangle query:\n                    // Sum(X_max, Y_max) - Sum(X_min-1, Y_max) - Sum(X_max, Y_min-1) + Sum(X_min-1, Y_min-1)\n                    // Here, Sum(X, Y) denotes the sum of points `p` such that `p.x <= X` and `p.y <= Y`.\n                    // Using `grid_ps`:\n                    // Sum(sx[i2], sy[j2]) corresponds to `get_ps_val(i2, j2)`\n                    // Sum(sx[i1]-1, sy[j2]) corresponds to `get_ps_val(i1-1, j2)`\n                    // Sum(sx[i2], sy[j1]-1) corresponds to `get_ps_val(i2, j1-1)`\n                    // Sum(sx[i1]-1, sy[j1]-1) corresponds to `get_ps_val(i1-1, j1-1)`\n                    current_score_diff = get_ps_val(i2, j2) \n                                       - get_ps_val(i1 - 1, j2) \n                                       - get_ps_val(i2, j1 - 1) \n                                       + get_ps_val(i1 - 1, j1 - 1);\n\n                    // Calculate the perimeter of the rectangle.\n                    long long current_perimeter = 2LL * ((long long)(sx[i2] - sx[i1]) + (long long)(sy[j2] - sy[j1]));\n\n                    // Check if the perimeter constraint is satisfied.\n                    if (current_perimeter <= 400000LL) {\n                        // If the current rectangle has a better score difference, update the best found rectangle.\n                        if (current_score_diff > max_score_diff) {\n                            max_score_diff = current_score_diff;\n                            best_x1_idx = i1;\n                            best_x2_idx = i2;\n                            best_y1_idx = j1;\n                            best_y2_idx = j2;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If no valid rectangle was found (e.g., all rectangles exceeded perimeter, or all had non-positive score diff),\n    // default to a minimal valid rectangle: a single point at (0,0) if (0,0) is a candidate.\n    // The indices sx[0], sy[0] are always 0. So this effectively picks (0,0) as the rectangle.\n    // This rectangle has perimeter 0 and a score difference of 0 if no points are at (0,0),\n    // resulting in a score of max(0, 0+1)=1, which is a valid baseline.\n    if (best_x1_idx == -1) {\n        best_x1_idx = 0;\n        best_x2_idx = 0;\n        best_y1_idx = 0;\n        best_y2_idx = 0;\n    }\n    \n    // Output the 4 vertices of the best rectangle found.\n    // The vertices are (sx[best_x1_idx], sy[best_y1_idx]), (sx[best_x2_idx], sy[best_y1_idx]),\n    // (sx[best_x2_idx], sy[best_y2_idx]), and (sx[best_x1_idx], sy[best_y2_idx}).\n    std::cout << 4 << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y2_idx] << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y2_idx] << std::endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <utility> // for std::pair\n\n// Structure to hold noisy dimensions for a rectangle\nstruct Rect {\n    long long w_prime, h_prime;\n};\n\n// Structure to hold information about a rectangle after placement\nstruct PlacedRect {\n    int id; // original index of the rectangle\n    long long x, y, w, h; // position (top-left) and dimensions\n};\n\n// Structure to represent an entry in the output placement sequence for a turn\nstruct OutputEntry {\n    int p; // rectangle index\n    int r; // rotation (0: original, 1: 90 deg rotated)\n    char d; // direction ('U' for Up, 'L' for Left)\n    int b; // reference rectangle index (-1 for origin, or index in current_placed_rects)\n};\n\nint main() {\n    // Improve I/O performance\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N; // Number of rectangles\n    int T; // Number of turns\n    long long sigma; // Standard deviation of measurement error\n    std::cin >> N >> T >> sigma;\n\n    // Read noisy dimensions for each rectangle\n    std::vector<Rect> rects(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> rects[i].w_prime >> rects[i].h_prime;\n    }\n\n    // Pre-calculate the sum of (w'_i + h'_i) for all suffixes of rectangles.\n    // penalty_sum[k] will store sum_{i=k to N-1} (rects[i].w_prime + rects[i].h_prime).\n    // This is used to quickly calculate the penalty for unused rectangles.\n    std::vector<long long> penalty_sum(N + 1, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        penalty_sum[i] = penalty_sum[i + 1] + rects[i].w_prime + rects[i].h_prime;\n    }\n\n    // Main loop for each turn\n    for (int t = 0; t < T; ++t) {\n        // Variables to store the best placement strategy found for the current turn\n        std::vector<OutputEntry> best_output_sequence;\n        int best_n = 0; // Number of rectangles to place in this turn\n        long long best_turn_score = -1; // Score for the best strategy in this turn\n\n        // Iterate through all possible numbers of rectangles to place, from N down to 0.\n        // We try to place `num_to_place` rectangles, specifically indices 0, 1, ..., num_to_place - 1.\n        // This is because rectangles must be placed in ascending order of their original indices.\n        for (int num_to_place = N; num_to_place >= 0; --num_to_place) {\n            // Case: placing 0 rectangles.\n            if (num_to_place == 0) {\n                // The score is 0 (W+H) + penalty for all N unused rectangles.\n                long long current_score = 0 + 0 + penalty_sum[0];\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = 0;\n                    best_output_sequence.clear(); // Empty sequence\n                }\n                continue; // Move to the next iteration of `num_to_place`\n            }\n\n            // State for placing `num_to_place` rectangles:\n            std::vector<PlacedRect> current_placed_rects; // Stores info about rectangles placed so far in this attempt.\n            std::vector<OutputEntry> current_output_sequence; // Stores the placement instructions for this attempt.\n            bool possible_to_place_all = true; // Flag to check if all `num_to_place` can be placed validly.\n\n            long long current_max_W = 0; // Current bounding box width after placing rectangles so far.\n            long long current_max_H = 0; // Current bounding box height after placing rectangles so far.\n\n            // Attempt to place rectangles 0, 1, ..., num_to_place - 1 in order.\n            for (int i = 0; i < num_to_place; ++i) {\n                int current_rect_idx = i; // The original index of the rectangle being considered for placement.\n\n                // Define the two possible dimensions (original and rotated) for the current rectangle.\n                std::pair<long long, long long> dims[2];\n                dims[0] = {rects[current_rect_idx].w_prime, rects[current_rect_idx].h_prime}; // r = 0 (no rotation)\n                dims[1] = {rects[current_rect_idx].h_prime, rects[current_rect_idx].w_prime}; // r = 1 (rotated 90 degrees)\n\n                // Variables to track the best placement found for the current rectangle `i`.\n                long long best_x = -1, best_y = -1; // Best position (top-left corner)\n                int best_r = -1; // Best rotation option (0 or 1)\n                char best_d_char = ' '; // Best direction ('U' or 'L')\n                int best_b_idx_in_placed = -1; // Index of the reference rectangle in `current_placed_rects` (-1 if origin).\n                long long min_placement_cost = -1; // The cost (W+H) of the best found placement for this rectangle.\n\n                // Iterate through all possible reference rectangles.\n                // `b_place_idx` is the index in `current_placed_rects`. -1 refers to the origin (0,0).\n                for (int b_place_idx = -1; b_place_idx < current_placed_rects.size(); ++b_place_idx) {\n                    // Get reference rectangle's properties if b_place_idx is valid.\n                    long long ref_x = 0, ref_y = 0, ref_w = 0, ref_h = 0;\n                    if (b_place_idx != -1) {\n                        ref_x = current_placed_rects[b_place_idx].x;\n                        ref_y = current_placed_rects[b_place_idx].y;\n                        ref_w = current_placed_rects[b_place_idx].w;\n                        ref_h = current_placed_rects[b_place_idx].h;\n                    }\n\n                    // Iterate through rotation options (0 or 1).\n                    for (int r_opt = 0; r_opt < 2; ++r_opt) {\n                        long long W = dims[r_opt].first; // Width of the rectangle in this orientation.\n                        long long H = dims[r_opt].second; // Height of the rectangle in this orientation.\n\n                        // Iterate through placement directions ('U' or 'L').\n                        for (char d_char : {'U', 'L'}) {\n                            long long cur_x, cur_y; // Proposed position for the top-left corner.\n\n                            if (d_char == 'U') {\n                                // Place upwards: align left edge with ref's right edge, top edge with ref's bottom edge.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x + ref_w);\n                                cur_y = (b_place_idx == -1) ? 0 : (ref_y + ref_h);\n                            } else { // d_char == 'L'\n                                // Place leftwards: align right edge with ref's left edge, top edge with ref's top edge.\n                                // The resulting x-coordinate must be non-negative.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x - W);\n                                cur_y = (b_place_idx == -1) ? 0 : ref_y;\n                                \n                                // Constraint: rectangles must be placed in x >= 0 and y >= 0.\n                                // For 'L' placement, if `ref_x - W` results in a negative x-coordinate,\n                                // this specific alignment with `ref_x` is not possible without going left of the origin.\n                                // The rule implies stopping at x=0. If `ref_x < W`, the rectangle cannot be placed \n                                // such that its right edge is at `ref_x` AND its left edge is >= 0.\n                                // Thus, `ref_x` must be at least `W` for this alignment to be possible.\n                                if (cur_x < 0) { \n                                    continue; // This placement combination is invalid.\n                                }\n                            }\n\n                            // Calculate the resulting bounding box dimensions if this rectangle is placed at (cur_x, cur_y).\n                            // `current_max_W` and `current_max_H` store the bounding box of already placed rectangles.\n                            long long candidate_W = std::max(current_max_W, cur_x + W);\n                            long long candidate_H = std::max(current_max_H, cur_y + H);\n                            \n                            // The cost for this placement is the sum of the bounding box dimensions.\n                            long long current_placement_cost = candidate_W + candidate_H;\n\n                            // If this is the first valid placement found, or if it yields a better (smaller) cost, update best found.\n                            if (min_placement_cost == -1 || current_placement_cost < min_placement_cost) {\n                                min_placement_cost = current_placement_cost;\n                                best_x = cur_x;\n                                best_y = cur_y;\n                                best_r = r_opt;\n                                best_d_char = d_char;\n                                best_b_idx_in_placed = b_place_idx;\n                            }\n                        } // End of loop for `d_char`\n                    } // End of loop for `r_opt`\n                } // End of loop for `b_place_idx`\n\n                // If no valid placement was found for the current rectangle `i` with the current `num_to_place` setting.\n                if (best_x == -1) {\n                    possible_to_place_all = false; // This `num_to_place` strategy is not feasible.\n                    break; // Stop trying to place more rectangles for this `num_to_place` value.\n                }\n\n                // Record the best placement found for rectangle `i`.\n                current_placed_rects.push_back({current_rect_idx, best_x, best_y, dims[best_r].first, dims[best_r].second});\n                current_output_sequence.push_back({current_rect_idx, best_r, best_d_char, best_b_idx_in_placed});\n                \n                // Update the overall bounding box dimensions with the newly placed rectangle.\n                current_max_W = std::max(current_max_W, best_x + dims[best_r].first);\n                current_max_H = std::max(current_max_H, best_y + dims[best_r].second);\n\n            } // End of loop for `i` (placing rectangles 0 to num_to_place - 1)\n\n            // If we successfully placed all `num_to_place` rectangles:\n            if (possible_to_place_all) {\n                // Calculate the total score for this specific `num_to_place` strategy.\n                // Score = (final W + final H of placed rectangles) + (penalty sum of unused rectangles).\n                long long current_score = current_max_W + current_max_H + penalty_sum[num_to_place];\n                \n                // If this score is better than the best score found so far for this turn, update bests.\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = num_to_place;\n                    best_output_sequence = current_output_sequence;\n                }\n            }\n        } // End of loop for `num_to_place` (trying different counts of rectangles to place)\n\n        // Output the chosen placement strategy for the current turn.\n        std::cout << best_n << std::endl;\n        for (const auto& p : best_output_sequence) {\n            std::cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << std::endl;\n        }\n        std::cout << std::flush; // Ensure output is sent immediately.\n\n        // Read the measured bounding box dimensions for this turn.\n        // These are not used by the current strategy, but are required by the problem protocol.\n        long long measured_W_prime, measured_H_prime;\n        std::cin >> measured_W_prime >> measured_H_prime;\n    } // End of loop for turns `t`\n\n    return 0; // Program finished successfully.\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\n// Structure to store information about a representative of a DSU set.\n// Each representative corresponds to the root of a tree in our problem.\nstruct DSU_Rep_Info {\n    int root_vertex;    // The actual vertex ID that is the root of this tree.\n    int max_height;     // The maximum height among all vertices in this tree, relative to root_vertex.\n    long long sum_beauty; // The sum of beauty values of all vertices in this tree.\n};\n\nvector<int> dsu_parent; // Standard DSU parent array. dsu_parent[i] stores the parent of vertex i in the DSU structure.\nvector<DSU_Rep_Info> rep_info; // Stores information about each representative. Indexed by the representative's vertex ID.\n\n// Finds the representative of the set containing vertex v.\n// Implements path compression for efficiency.\nint find_set(int v) {\n    if (v == dsu_parent[v])\n        return v;\n    return dsu_parent[v] = find_set(dsu_parent[v]);\n}\n\n// Merges the set represented by root_c_repr into the set represented by root_p_repr.\n// This function is called when we decide to make the tree rooted at root_c_vertex a child\n// of the tree rooted at root_p_vertex.\n// root_p_repr: DSU representative of the parent tree.\n// root_c_repr: DSU representative of the child tree.\n// root_p_vertex: Actual vertex ID that is the root of the parent tree.\n// root_c_vertex: Actual vertex ID that is the root of the child tree.\n// H: Maximum allowed height for any vertex in any tree.\n// adj: Adjacency list of the graph. (Not strictly needed in union_sets for this problem logic, but kept for consistency)\n// p: The final parent array to be constructed. p[v] will store the parent of vertex v, or -1 if v is a root.\n// rep_info: Reference to the vector storing DSU representative information.\n// dsu_parent: Reference to the DSU parent array.\nvoid union_sets(int root_p_repr, int root_c_repr, int root_p_vertex, int root_c_vertex, int H, const vector<vector<int>>& adj, vector<int>& p, vector<DSU_Rep_Info>& rep_info, vector<int>& dsu_parent) {\n    \n    // Perform the union in DSU structure: make root_c_repr's DSU tree point to root_p_repr.\n    dsu_parent[root_c_repr] = root_p_repr;\n    \n    // Update the parent pointer for the actual root of the child tree.\n    // The root of the child tree (root_c_vertex) now becomes a child of the root of the parent tree (root_p_vertex).\n    p[root_c_vertex] = root_p_vertex;\n\n    // Update the information for the new representative (root_p_repr).\n    // The sum of beauties is the sum of beauties of both trees.\n    rep_info[root_p_repr].sum_beauty += rep_info[root_c_repr].sum_beauty;\n    // The new maximum height is the maximum of the parent tree's height and the child tree's height increased by 1.\n    // When root_c_vertex becomes a child of root_p_vertex, its height becomes 1.\n    // Any node w in the child tree was at height h_old(w) from root_c_vertex. Its new height from root_p_vertex will be h_old(w) + 1.\n    // So the max height in the combined tree from root_p_vertex is max(current max height from root_p_vertex, max height from root_c_vertex + 1).\n    rep_info[root_p_repr].max_height = max(rep_info[root_p_repr].max_height, rep_info[root_c_repr].max_height + 1);\n    \n    // The actual root vertex of the merged component remains root_p_vertex.\n    // This assignment is mainly for conceptual clarity; root_p_vertex should already be rep_info[root_p_repr].root_vertex.\n    rep_info[root_p_repr].root_vertex = root_p_vertex; \n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n; // Number of vertices\n    int m; // Number of edges\n    int h_limit; // Maximum allowed height\n    cin >> n >> m >> h_limit;\n\n    vector<long long> a(n); // Beauty values of vertices\n    for (int i = 0; i < n; ++i) {\n        cin >> a[i];\n    }\n\n    vector<vector<int>> adj(n); // Adjacency list for the graph\n    vector<pair<int, int>> edges; // List of all edges\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        edges.push_back({u, v});\n    }\n\n    // Initialize DSU structure. Initially, each vertex is in its own set.\n    dsu_parent.resize(n);\n    iota(dsu_parent.begin(), dsu_parent.end(), 0); // dsu_parent[i] = i for all i\n    \n    rep_info.resize(n);\n    for (int i = 0; i < n; ++i) {\n        // Initially, each vertex is a root of its own tree:\n        // root_vertex is itself, max_height is 0, sum_beauty is its own beauty value.\n        rep_info[i] = {i, 0, a[i]}; \n    }\n\n    // Priority queue to store potential merges.\n    // Stores tuples: {gain, -child_max_h, -parent_max_h, parent_root_repr_id, child_root_repr_id}.\n    // - gain: The sum of beauties of the component being merged (primary greedy criterion).\n    // - -child_max_h: Negative of the maximum height of the child component (secondary criterion: prefer shallower children).\n    // - -parent_max_h: Negative of the maximum height of the parent component (tertiary criterion: prefer shallower parents if child heights are equal).\n    // - parent_root_repr_id: Vertex ID of the representative of the parent component.\n    // - child_root_repr_id: Vertex ID of the representative of the child component.\n    priority_queue<tuple<long long, int, int, int, int>> pq;\n\n    // Populate the priority queue with initial merge candidates.\n    // For each edge (u, v), consider merging the tree rooted at v into the tree rooted at u,\n    // and vice versa, provided the height constraint is met.\n    for (const auto& edge : edges) {\n        int u_vtx = edge.first;\n        int v_vtx = edge.second;\n\n        // Get current representatives for u_vtx and v_vtx\n        int root_u_repr = find_set(u_vtx);\n        int root_v_repr = find_set(v_vtx);\n\n        // If they are already in the same component, this edge doesn't form a new merge candidate between components.\n        if (root_u_repr == root_v_repr) continue;\n\n        // Option 1: Make v's component a child of u's component.\n        // The parent's representative is root_u_repr, child's representative is root_v_repr.\n        // The actual root vertices are rep_info[root_u_repr].root_vertex and rep_info[root_v_repr].root_vertex.\n        if (rep_info[root_v_repr].max_height + 1 <= h_limit) {\n            long long gain = rep_info[root_v_repr].sum_beauty;\n            pq.push({gain, -rep_info[root_v_repr].max_height, -rep_info[root_u_repr].max_height, root_u_repr, root_v_repr});\n        }\n        // Option 2: Make u's component a child of v's component.\n        // The parent's representative is root_v_repr, child's representative is root_u_repr.\n        if (rep_info[root_u_repr].max_height + 1 <= h_limit) {\n            long long gain = rep_info[root_u_repr].sum_beauty;\n            pq.push({gain, -rep_info[root_u_repr].max_height, -rep_info[root_v_repr].max_height, root_v_repr, root_u_repr});\n        }\n    }\n\n    // Initialize the final parent array. -1 indicates a root vertex.\n    vector<int> p(n, -1); \n\n    // Greedily process merges from the priority queue.\n    while (!pq.empty()) {\n        auto [gain, neg_h_child, neg_h_parent, parent_root_id, child_root_id] = pq.top();\n        pq.pop();\n\n        // Find current representatives. These might be different from parent_root_id and child_root_id\n        // if their components have been merged into other components already.\n        int current_parent_repr = find_set(parent_root_id);\n        int current_child_repr = find_set(child_root_id);\n\n        // If they are already in the same set, this merge is redundant.\n        if (current_parent_repr == current_child_repr) continue;\n        \n        // Crucial check: If the stored representative IDs are no longer the actual representatives,\n        // this PQ entry is stale because the components it referred to have been merged.\n        // This happens if parent_root_id's component was merged into another, or child_root_id's component was merged.\n        // We check if the vertex ID stored in PQ is still its own representative after path compression.\n        if (current_parent_repr != parent_root_id || current_child_repr != child_root_id) {\n             continue; // Stale entry.\n        }\n\n        // Now we know `parent_root_id` and `child_root_id` are the actual current representatives.\n        // `rep_info` is indexed by these representative IDs.\n        // We must re-check the height constraint using the current max heights from `rep_info`.\n        // `rep_info[child_root_id].max_height` is the current max height of the child component.\n        if (rep_info[child_root_id].max_height + 1 > h_limit) {\n            continue; // Height limit violated with the current configuration.\n        }\n\n        // Perform the union.\n        // `parent_root_id` and `child_root_id` are the current DSU representatives.\n        // `rep_info[parent_root_id].root_vertex` is the actual vertex ID that serves as the root of the parent component.\n        // `rep_info[child_root_id].root_vertex` is the actual vertex ID that serves as the root of the child component.\n        union_sets(parent_root_id, child_root_id, rep_info[parent_root_id].root_vertex, rep_info[child_root_id].root_vertex, h_limit, adj, p, rep_info, dsu_parent);\n    }\n\n    // Output the resulting parent array.\n    for (int i = 0; i < n; ++i) {\n        cout << p[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    cin >> n;\n\n    // Read the initial board configuration.\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> board[i];\n    }\n\n    // Precompute safety information for each cell.\n    // has_fuku_above[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k < r.\n    // has_fuku_below[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k > r.\n    // has_fuku_left[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k < c.\n    // has_fuku_right[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k > c.\n    // These precomputed values allow O(1) safety checks for each direction.\n    vector<vector<bool>> has_fuku_above(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_below(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_left(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_right(n, vector<bool>(n, false));\n\n    // Compute has_fuku_above and has_fuku_below for all columns.\n    for (int c = 0; c < n; ++c) {\n        bool found_fuku_in_col = false;\n        // Scan downwards: for each cell (r, c), check if any Fuku was found in previous rows (k < r).\n        for (int r = 0; r < n; ++r) {\n            has_fuku_above[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column above current row.\n            }\n        }\n        \n        found_fuku_in_col = false; // Reset for scanning downwards to compute has_fuku_below.\n        // Scan upwards: for each cell (r, c), check if any Fuku was found in subsequent rows (k > r).\n        for (int r = n - 1; r >= 0; --r) {\n            has_fuku_below[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column below current row.\n            }\n        }\n    }\n\n    // Compute has_fuku_left and has_fuku_right for all rows.\n    for (int r = 0; r < n; ++r) {\n        bool found_fuku_in_row = false;\n        // Scan rightwards: for each cell (r, c), check if any Fuku was found in previous columns (k < c).\n        for (int c = 0; c < n; ++c) {\n            has_fuku_left[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the left of current column.\n            }\n        }\n        \n        found_fuku_in_row = false; // Reset for scanning rightwards to compute has_fuku_right.\n        // Scan leftwards: for each cell (r, c), check if any Fuku was found in subsequent columns (k > c).\n        for (int c = n - 1; c >= 0; --c) {\n            has_fuku_right[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the right of current column.\n            }\n        }\n    }\n\n    // Stores the sequence of operations to be performed.\n    vector<pair<char, int>> operations;\n    const int INF = 1e9; // A large enough value to represent infinity for costs.\n\n    // Iterate through each cell of the board.\n    for (int r = 0; r < n; ++r) {\n        for (int c = 0; c < n; ++c) {\n            // If the cell contains an Oni ('x').\n            if (board[r][c] == 'x') {\n                // Find the safest and cheapest direction to remove this specific Oni.\n                // The goal is to minimize operations (T) for the score 8N^2 - T.\n                int min_cost = INF;\n                char best_op_char = ' ';\n                int best_op_idx = -1;\n\n                // --- Evaluate Upward push ---\n                // Cost: r + 1 operations. An Oni at (r,c) moves up to (0,c) in 'r' steps, and then is removed by the (r+1)th UP shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k < r. This is checked by !has_fuku_above[r][c].\n                if (!has_fuku_above[r][c]) {\n                    int cost = r + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'U'; // Upward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Downward push ---\n                // Cost: N - r operations. An Oni at (r,c) moves down to (N-1,c) in (N-1)-r steps, and then is removed by the (N-r)th DOWN shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k > r. This is checked by !has_fuku_below[r][c].\n                if (!has_fuku_below[r][c]) {\n                    int cost = n - r;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'D'; // Downward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Leftward push ---\n                // Cost: c + 1 operations. An Oni at (r,c) moves left to (r,0) in 'c' steps, and then is removed by the (c+1)th LEFT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k < c. This is checked by !has_fuku_left[r][c].\n                if (!has_fuku_left[r][c]) {\n                    int cost = c + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'L'; // Leftward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // --- Evaluate Rightward push ---\n                // Cost: N - c operations. An Oni at (r,c) moves right to (r,N-1) in (N-1)-c steps, and then is removed by the (N-c)th RIGHT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k > c. This is checked by !has_fuku_right[r][c].\n                if (!has_fuku_right[r][c]) {\n                    int cost = n - c;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'R'; // Rightward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // The problem guarantees that for every Oni, at least one direction is safe.\n                // Thus, min_cost will be less than INF and greater than or equal to 1.\n                // We add 'min_cost' operations of the chosen type. This ensures each Oni is removed.\n                // The total number of operations T will be the sum of these minimum costs for each Oni.\n                // This greedy strategy aims to minimize T by making the locally optimal choice for each Oni.\n                for (int k = 0; k < min_cost; ++k) {\n                    operations.push_back({best_op_char, best_op_idx});\n                }\n            }\n        }\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output each operation in the specified format.\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N; // Number of employees\nlong long L; // Total number of weeks\nvector<long long> T; // Target counts for each employee\n\n// l_counts[i] = ceil(T[i] / 2.0)\n// r_counts[i] = floor(T[i] / 2.0)\n// These represent the number of times employee i directs the process\n// to a_i (if its count becomes odd) or b_i (if its count becomes even).\nvector<long long> l_counts; \nvector<long long> r_counts; \n\n// current_O[j] stores the total count of \"odd-parity\" assignments directed to employee j.\n// This sum comes from all i such that a_i = j, contributing l_counts[i].\nvector<long long> current_O; \n// current_E[j] stores the total count of \"even-parity\" assignments directed to employee j.\n// This sum comes from all i such that b_i = j, contributing r_counts[i].\nvector<long long> current_E; \n\n// a[i] and b[i] store the chosen successors for employee i.\nvector<int> a;\nvector<int> b;\n\n// Calculates the total error based on current O and E counts.\n// Error is sum of absolute differences between target T_j and actual assignments (O_j + E_j).\nlong long calculate_total_error() {\n    long long error = 0;\n    for (int j = 0; j < N; ++j) {\n        error += abs((current_O[j] + current_E[j]) - T[j]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Precompute l_counts and r_counts for each employee\n    l_counts.resize(N);\n    r_counts.resize(N);\n    for (int i = 0; i < N; ++i) {\n        l_counts[i] = (T[i] + 1) / 2; // Equivalent to ceil(T[i] / 2.0)\n        r_counts[i] = T[i] / 2;      // Equivalent to floor(T[i] / 2.0)\n    }\n\n    current_O.resize(N, 0);\n    current_E.resize(N, 0);\n    a.resize(N);\n    b.resize(N);\n\n    // Initialize: each employee i initially directs assignments to itself.\n    // a[i] = i, b[i] = i.\n    // Update current_O and current_E based on this initial assignment.\n    for (int i = 0; i < N; ++i) {\n        a[i] = i;\n        b[i] = i;\n        current_O[i] += l_counts[i];\n        current_E[i] += r_counts[i];\n    }\n\n    // Calculate initial total error\n    long long current_total_error = calculate_total_error();\n\n    // The core of the solution is a local search heuristic.\n    // We iterate a fixed number of times. In each iteration, for each employee i,\n    // we try to find the best pair (u, v) for (a[i], b[i]) that minimizes the total error.\n    // The total number of iterations is a hyperparameter. For N=100, N^3 complexity per iteration\n    // implies a limit around 1000-2000 iterations to stay within time limits.\n    // We chose 1500 iterations as a balance between exploration and performance.\n    int num_iterations = 1500; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        bool improved_in_iter = false; // Flag to check if any improvement was made in this iteration\n\n        // Iterate through each employee i to potentially change their a[i] and b[i]\n        for (int i = 0; i < N; ++i) {\n            int old_a = a[i]; // Store old assignment for a[i]\n            int old_b = b[i]; // Store old assignment for b[i]\n            \n            // Keep track of the best assignment found so far for employee i in this iteration\n            int best_new_a = old_a;\n            int best_new_b = old_b;\n            long long min_err_for_i = current_total_error; // Minimum error achievable by changing a[i], b[i]\n\n            // Try all possible pairs (u, v) for (a[i], b[i])\n            for (int u = 0; u < N; ++u) { // New target for a[i]\n                for (int v = 0; v < N; ++v) { // New target for b[i]\n                    \n                    // Store current counts before modification for backtracking\n                    long long temp_O_old_a = current_O[old_a];\n                    long long temp_O_u = current_O[u];\n                    long long temp_E_old_b = current_E[old_b];\n                    long long temp_E_v = current_E[v];\n\n                    // --- Calculate potential new total error if a[i] becomes u and b[i] becomes v ---\n                    // We need to efficiently update current_O and current_E.\n                    // If old_a != u, the contribution of l_counts[i] shifts from old_a to u.\n                    // If old_b != v, the contribution of r_counts[i] shifts from old_b to v.\n                    \n                    // Revert contributions of old assignments\n                    if (old_a != u) {\n                        current_O[old_a] -= l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] -= r_counts[i];\n                    }\n                    \n                    // Apply new contributions\n                    if (old_a != u) {\n                        current_O[u] += l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[v] += r_counts[i];\n                    }\n\n                    // Handle cases where u == old_a or v == old_b.\n                    // If u == old_a, the l_counts[i] contribution remains at old_a, so current_O[old_a] and current_O[u] are unchanged relative to each other for THIS i's contribution.\n                    // The logic above handles this correctly: if old_a == u, we do not subtract from old_a and do not add to u, keeping them as they were.\n                    // Same applies for b[i] and v.\n                    // If u == v == old_a == old_b, no changes happen.\n\n                    // Calculate the new total error with these tentative assignments\n                    long long temp_error = calculate_total_error();\n\n                    // If this new assignment (u, v) results in a lower total error, update best found for i\n                    if (temp_error < min_err_for_i) {\n                        min_err_for_i = temp_error;\n                        best_new_a = u;\n                        best_new_b = v;\n                        improved_in_iter = true; // Mark that an improvement has been made\n                    }\n                    \n                    // --- Backtrack: restore counts to their state before trying this (u,v) pair ---\n                    // This is crucial because current_O and current_E are global and used for next (u,v) pair.\n                    if (old_a != u) {\n                        current_O[old_a] = temp_O_old_a; // Restore old_a's count\n                        current_O[u] = temp_O_u;         // Restore u's count\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] = temp_E_old_b; // Restore old_b's count\n                        current_E[v] = temp_E_v;         // Restore v's count\n                    }\n                }\n            }\n            \n            // After trying all (u,v) for employee i, apply the best found assignment\n            if (min_err_for_i < current_total_error) {\n                // Update the global counts based on the best move for employee i\n                // First, remove the contribution of the old assignment\n                if (old_a != best_new_a) {\n                    current_O[old_a] -= l_counts[i];\n                    current_O[best_new_a] += l_counts[i];\n                }\n                if (old_b != best_new_b) {\n                    current_E[old_b] -= r_counts[i];\n                    current_E[best_new_b] += r_counts[i];\n                }\n                \n                // Update a[i] and b[i] to the best choice\n                a[i] = best_new_a;\n                b[i] = best_new_b;\n                current_total_error = min_err_for_i; // Update the global minimum error\n            }\n        }\n        // If no improvement was made in this iteration for any employee, we can stop early.\n        if (!improved_in_iter) {\n            break;\n        }\n    }\n\n    // Output the resulting a[i] and b[i] values\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n#include <numeric>\n#include <set>\n\n// Structure to hold city information\nstruct City {\n    int id;\n    long long lx, rx, ly, ry;\n    double est_x, est_y; // Estimated coordinates (center of bounding box)\n};\n\n// Structure to represent an edge with estimated weight for sorting\nstruct Edge {\n    int u, v;\n    long long weight; // Use estimated distance as weight\n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) {\n            return weight < other.weight;\n        }\n        if (u != other.u) {\n            return u < other.u;\n        }\n        return v < other.v;\n    }\n};\n\n// Disjoint Set Union (DSU) data structure for Kruskal's algorithm\nstruct DSU {\n    std::vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        std::iota(parent.begin(), parent.end(), 0); // Initialize each node as its own parent\n    }\n    // Find the root of the set containing element i\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n    // Unite the sets containing elements i and j\n    void unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j; // Union by rank/size can be added for optimization, but N is not extremely large\n        }\n    }\n};\n\n// Function to query MST for a subset of cities\n// Returns a vector of pairs (u, v) representing MST edges, sorted lexicographically.\nstd::vector<std::pair<int, int>> query_mst(const std::vector<int>& cities) {\n    std::cout << \"? \" << cities.size();\n    for (int city_idx : cities) {\n        std::cout << \" \" << city_idx;\n    }\n    std::cout << std::endl;\n\n    std::vector<std::pair<int, int>> mst_edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; ++i) {\n        int u, v;\n        std::cin >> u >> v;\n        if (u > v) std::swap(u, v); // Ensure lexicographical order (u < v)\n        mst_edges.push_back({u, v});\n    }\n    // The problem states response is sorted lexicographically by (u,v) pair.\n    // No need to sort here.\n    return mst_edges;\n}\n\n// Calculate estimated Euclidean distance between two cities using their estimated coordinates\nlong long estimated_dist(const City& c1, const City& c2) {\n    long long dx = static_cast<long long>(std::round(c1.est_x)) - static_cast<long long>(std::round(c2.est_x));\n    long long dy = static_cast<long long>(std::round(c1.est_y)) - static_cast<long long>(std::round(c2.est_y));\n    return static_cast<long long>(std::sqrt(dx * dx + dy * dy));\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    std::cin >> N >> M >> Q >> L >> W;\n\n    std::vector<int> G(M); // Target sizes for each group\n    for (int i = 0; i < M; ++i) {\n        std::cin >> G[i];\n    }\n\n    std::vector<City> cities(N);\n    std::vector<int> p(N); // Permutation for sorting cities by estimated position\n    for (int i = 0; i < N; ++i) {\n        cities[i].id = i;\n        std::cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        // Estimate city coordinates as the center of its bounding box\n        cities[i].est_x = (cities[i].lx + cities[i].rx) / 2.0;\n        cities[i].est_y = (cities[i].ly + cities[i].ry) / 2.0;\n        p[i] = i; // Initialize permutation with city indices\n    }\n\n    // Sort cities based on their estimated coordinates (lexicographically by x, then y)\n    std::sort(p.begin(), p.end(), [&](int i, int j) {\n        if (cities[i].est_x != cities[j].est_x) {\n            return cities[i].est_x < cities[j].est_x;\n        }\n        return cities[i].est_y < cities[j].est_y;\n    });\n\n    // Initial grouping: Assign cities greedily to groups based on sorted estimated positions\n    // This is a heuristic and may not be optimal, but provides a starting point.\n    std::vector<std::vector<int>> final_groups(M); // Stores city IDs for each group\n    std::vector<int> city_to_group_idx(N); // Maps city ID to its group index\n    int current_city_p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < G[k]; ++i) {\n            int city_id = p[current_city_p_idx++];\n            final_groups[k].push_back(city_id);\n            city_to_group_idx[city_id] = k;\n        }\n    }\n\n    // Store all discovered edges from queries. We don't get true weights, only pairs.\n    // We use estimated distance as a proxy weight for sorting and prioritization.\n    std::vector<Edge> collected_queried_edges;\n    std::set<std::pair<int, int>> queried_edge_pairs_set; // To efficiently check if an edge was queried\n\n    int queries_used = 0;\n\n    // Phase 1: Query groups that are small enough (size <= L) to get their exact MST edges.\n    // This uses one query per such group.\n    for (int k = 0; k < M; ++k) {\n        if (final_groups[k].size() <= L && queries_used < Q) {\n            std::vector<std::pair<int, int>> mst_edges = query_mst(final_groups[k]);\n            for (const auto& edge_pair : mst_edges) {\n                int u = edge_pair.first;\n                int v = edge_pair.second;\n                collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n                queried_edge_pairs_set.insert({u, v});\n            }\n            queries_used++;\n        }\n    }\n\n    // Phase 2: Use remaining queries to get more edges by querying overlapping windows.\n    // This strategy aims to cover all cities and discover relationships.\n    int num_windows_to_query = Q - queries_used;\n    for (int i = 0; i < num_windows_to_query; ++i) {\n        std::vector<int> subset;\n        // Create a subset of size L by taking L consecutive cities from the sorted list 'p'.\n        // Use modulo arithmetic for cyclic access to 'p' to ensure all cities can be part of some subset.\n        for (int j = 0; j < L; ++j) {\n            subset.push_back(p[(i + j) % N]);\n        }\n        // Ensure subset size is at least 2 for a valid query\n        if (subset.size() < 2) continue;\n        \n        std::vector<std::pair<int, int>> mst_edges = query_mst(subset);\n        for (const auto& edge_pair : mst_edges) {\n            int u = edge_pair.first;\n            int v = edge_pair.second;\n            collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n            queried_edge_pairs_set.insert({u, v});\n        }\n    }\n\n    // Sort all collected queried edges based on their estimated distances.\n    // This heuristic prioritizes queried edges that are likely to be shorter (and thus better for MST).\n    std::sort(collected_queried_edges.begin(), collected_queried_edges.end());\n\n    // Collect candidate edges for MST construction for each group.\n    // This includes all queried edges and all pairs not covered by queries, using estimated distances.\n    std::vector<Edge> all_candidate_edges;\n    for(const auto& edge : collected_queried_edges) {\n        all_candidate_edges.push_back(edge);\n    }\n\n    // Add edges based on estimated distances for pairs not covered by queries.\n    for(int i=0; i<N; ++i) {\n        for(int j=i+1; j<N; ++j) {\n            if(queried_edge_pairs_set.find({i, j}) == queried_edge_pairs_set.end()) {\n                 all_candidate_edges.push_back({i, j, static_cast<int>(estimated_dist(cities[i], cities[j]))});\n            }\n        }\n    }\n    // Sort all candidate edges by estimated weight\n    std::sort(all_candidate_edges.begin(), all_candidate_edges.end());\n\n    // Build the final MST for each group using the sorted candidate edges.\n    std::vector<std::vector<std::pair<int, int>>> final_group_edges(M);\n    for (int k = 0; k < M; ++k) {\n        DSU dsu(N); // Initialize DSU for all N cities to correctly track components across groups\n        \n        // Add edges greedily using Kruskal's algorithm\n        for (const auto& edge : all_candidate_edges) {\n            // We need G[k]-1 edges for group k. Stop if we have enough.\n            if (final_group_edges[k].size() >= G[k] - 1) break;\n\n            int u = edge.u;\n            int v = edge.v;\n\n            // Check if both cities belong to the current group k\n            if (city_to_group_idx[u] == k && city_to_group_idx[v] == k) {\n                // If adding this edge does not create a cycle within group k's MST\n                if (dsu.find(u) != dsu.find(v)) {\n                    dsu.unite(u, v);\n                    final_group_edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n\n    // Output the final answer: groups and their MST edges\n    std::cout << \"!\" << std::endl;\n    for (int k = 0; k < M; ++k) {\n        // Output cities in the group\n        for (int city_id : final_groups[k]) {\n            std::cout << city_id << \" \";\n        }\n        std::cout << std::endl;\n        // Output edges for the group's MST\n        for (const auto& edge : final_group_edges[k]) {\n            std::cout << edge.first << \" \" << edge.second << std::endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Global variables to store game state and parameters\nint N; // Size of the skating rink (N x N)\nint M; // Total number of points given in input (start position + M-1 targets)\nvector<pair<int, int>> all_points; // Stores all M points: start and targets\nset<pair<int, int>> blocks; // Stores coordinates of all placed blocks\npair<int, int> current_pos; // Current position of the player\n\n// --- Helper Functions ---\n\n// Checks if a given coordinate (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Returns the change in (row, column) for a given direction character.\npair<int, int> get_delta(char dir) {\n    if (dir == 'U') return {-1, 0}; // Up: decrease row\n    if (dir == 'D') return {1, 0};  // Down: increase row\n    if (dir == 'L') return {0, -1}; // Left: decrease column\n    if (dir == 'R') return {0, 1};  // Right: increase column\n    return {0, 0}; // Should not happen with valid input\n}\n\n// --- Game Simulation and Action Execution ---\n\n// Executes a chosen action and direction.\n// This function simulates the action's effect on the game state (current_pos, blocks)\n// and prints the action to standard output for the judge system.\nvoid execute_action(char action, char dir) {\n    pair<int, int> delta = get_delta(dir);\n    int dx = delta.first;\n    int dy = delta.second;\n\n    if (action == 'M') { // Move action\n        // Update current position by one step in the given direction.\n        current_pos.first += dx;\n        current_pos.second += dy;\n        cout << action << ' ' << dir << endl;\n    } else if (action == 'A') { // Alter action\n        // Calculate the coordinates of the adjacent square to alter.\n        int alter_r = current_pos.first + dx;\n        int alter_c = current_pos.second + dy;\n        \n        // Ensure the target square for alteration is within bounds.\n        if (is_valid(alter_r, alter_c)) {\n            // If a block exists, remove it. Otherwise, place a new block.\n            if (blocks.count({alter_r, alter_c})) {\n                blocks.erase({alter_r, alter_c});\n            } else {\n                blocks.insert({alter_r, alter_c});\n            }\n        }\n        cout << action << ' ' << dir << endl;\n        // The player's position (current_pos) does not change during an Alter action.\n    } else if (action == 'S') { // Slide action\n        int cx = current_pos.first;\n        int cy = current_pos.second;\n        int slide_dist = 0;\n        \n        // Simulate the slide step-by-step to determine how far it goes.\n        // The slide stops just before hitting a block or going out of bounds.\n        for (int k = 1; ; ++k) {\n            int r = cx + k * dx;\n            int c = cy + k * dy;\n            \n            // Stop if the next square is out of bounds or contains a block.\n            if (!is_valid(r, c) || blocks.count({r, c})) {\n                slide_dist = k - 1; // The actual distance slid is k-1 squares.\n                break;\n            }\n            // Note: The problem states \"If you slide over a target square without stopping on it, it is not considered visited.\"\n            // This means the slide continues until a block/boundary, even if it passes targets.\n            // Our simulation accurately finds the stopping point.\n        }\n        \n        // Update current position by the calculated slide distance.\n        current_pos.first += slide_dist * dx;\n        current_pos.second += slide_dist * dy;\n        cout << action << ' ' << dir << endl;\n    }\n}\n\n// --- Main Logic ---\n\nint main() {\n    // Optimize standard I/O operations.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input parameters: grid size N and number of points M.\n    cin >> N >> M; \n    // M points are provided: (i_0, j_0) is the starting position,\n    // and (i_1, j_1) through (i_{M-1}, j_{M-1}) are the M-1 targets to visit in sequence.\n    all_points.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> all_points[i].first >> all_points[i].second;\n    }\n\n    // Initialize the player's current position to the starting point.\n    current_pos = all_points[0]; \n\n    // Iterate through each target point that needs to be visited.\n    // The targets are all_points[1] up to all_points[M-1].\n    for (int target_idx = 1; target_idx < M; ++target_idx) {\n        pair<int, int> target_pos = all_points[target_idx]; // The current target to reach.\n\n        // Keep planning and executing actions until the current position matches the target position.\n        while (current_pos != target_pos) {\n            int cx = current_pos.first;\n            int cy = current_pos.second;\n            int tx = target_pos.first;\n            int ty = target_pos.second;\n\n            // --- Determine Primary Direction to Move ---\n            char dir_char = ' ';\n            int dr = tx - cx; // Row difference\n            int dc = ty - cy; // Column difference\n\n            // Decide the primary direction:\n            // If the row difference is larger, prioritize vertical movement (Up/Down).\n            // Otherwise, prioritize horizontal movement (Left/Right).\n            // If row and column differences are equal, prioritize horizontal movement.\n            if (abs(dr) > abs(dc)) {\n                if (dr > 0) dir_char = 'D'; // Target is below\n                else dir_char = 'U';        // Target is above\n            } else { \n                if (dc > 0) dir_char = 'R'; // Target is to the right\n                else dir_char = 'L';        // Target is to the left\n            }\n\n            pair<int, int> delta = get_delta(dir_char);\n            int dx = delta.first;\n            int dy = delta.second;\n\n            // Calculate the position of the immediate next square in the chosen direction.\n            int next_r = cx + dx;\n            int next_c = cy + dy;\n\n            // Check if the target square itself contains a block.\n            bool is_target_blocked = blocks.count({tx, ty});\n            char action_to_take = ' '; // Variable to store the determined action.\n\n            // --- Decision Logic for Choosing Action ---\n\n            // Case 1: The target square is blocked AND we are exactly one step away from it.\n            // To visit the target, we must first remove the block.\n            if ((next_r == tx && next_c == ty) && is_target_blocked) {\n                action_to_take = 'A'; // Use Alter to remove the block at the target.\n            }\n            // Case 2: The very next square in our primary direction is blocked.\n            // This means there's an intermediate obstacle. We must clear it to proceed.\n            else if (blocks.count({next_r, next_c})) {\n                action_to_take = 'A'; // Use Alter to remove the intermediate block.\n            }\n            // Case 3: The next square is clear.\n            else {\n                // Calculate the Manhattan distance to the target.\n                int distance_to_target = abs(tx - cx) + abs(ty - cy);\n\n                // Heuristic strategy:\n                // For longer distances (heuristic threshold of 4), and if the target is clear,\n                // using Slide is more efficient for covering ground quickly.\n                // For shorter distances, or if the target is blocked (and we are not adjacent),\n                // using Move provides better precision and control.\n                if (distance_to_target > 4 && !is_target_blocked) {\n                    action_to_take = 'S'; // Prefer Slide for longer distances.\n                } else {\n                    action_to_take = 'M'; // Prefer Move for shorter distances or when target is blocked.\n                }\n            }\n            \n            // Execute the chosen action. This prints the action/direction and updates the game state.\n            execute_action(action_to_take, dir_char);\n        }\n    }\n\n    return 0; // Program finishes after all targets are visited.\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\n// Use long long for area and large coordinates if needed.\n// For this problem, coordinates are up to 10000, area up to 10^8.\n// int is fine for coordinates. long long for area.\nusing ll = long long;\n\n// Represents an axis-aligned rectangle. Coordinates are [x1, x2) x [y1, y2).\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const { return (ll)(x2 - x1) * (y2 - y1); }\n    int width() const { return x2 - x1; }\n    int height() const { return y2 - y1; }\n};\n\n// Represents a company with its desired location and area.\nstruct Company {\n    int id;\n    int x, y; // Desired point is (x+0.5, y+0.5)\n    ll r;     // Desired area\n};\n\n// Global random number generators for reproducibility and better distribution.\n// Seeded with current time for different runs.\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> dist_01(0.0, 1.0);\n\n// Function to calculate satisfaction for a single company.\n// p_i = 1 - (1 - min(r_i, s_i) / max(r_i, s_i))^2\ndouble calculate_satisfaction(ll r_i, ll s_i) {\n    if (s_i == 0) return 0.0; // Should not happen with positive area constraint\n    double ratio = (double)min(r_i, s_i) / max(r_i, s_i);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Function to find all divisors of a number n.\n// Returns divisors in ascending order.\nvector<ll> get_divisors(ll n) {\n    vector<ll> divisors;\n    for (ll i = 1; i * i <= n; ++i) {\n        if (n % i == 0) {\n            divisors.push_back(i);\n            if (i * i != n) {\n                divisors.push_back(n / i);\n            }\n        }\n    }\n    sort(divisors.begin(), divisors.end());\n    return divisors;\n}\n\n// Structure to hold the result of one complete assignment attempt (one iteration).\nstruct AssignmentResult {\n    // Stores (a, b, c, d) for each company's assigned rectangle.\n    vector<tuple<int, int, int, int>> assignments; \n    // Total satisfaction achieved in this assignment.\n    double total_satisfaction = -1.0; // Initialize to a value lower than any possible satisfaction (0.0).\n};\n\nint N; // Number of companies\nvector<Company> companies_data; // Stores input data for each company.\nvector<Rect> initial_available_regions; // The initial bounding box for space partitioning.\n\n// Number of random trials to perform. This is a key parameter for randomized algorithms.\n// More iterations generally lead to better results but take more time.\nconst int NUM_ITERATIONS = 200; \n\n// The main solver function implementing a randomized recursive partitioning strategy.\nAssignmentResult solve() {\n    AssignmentResult overall_best_result;\n    overall_best_result.assignments.resize(N); // Pre-size for N companies.\n\n    // Indices of companies, used for shuffling and tracking.\n    vector<int> company_indices(N);\n    iota(company_indices.begin(), company_indices.end(), 0); // Fill with 0, 1, ..., N-1.\n\n    // Perform multiple independent trials to explore different random choices.\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<Rect> available_regions = initial_available_regions; // Start with the full 10000x10000 area.\n        vector<int> current_unassigned_companies = company_indices; // Companies yet to be assigned in this iteration.\n        vector<tuple<int, int, int, int>> current_assignments(N); // Stores assignments for this iteration.\n        double current_total_satisfaction = 0.0;\n        bool iteration_failed = false; // Flag to mark if this iteration produced an invalid state.\n\n        // Shuffle companies to process them in a random order for this iteration.\n        shuffle(current_unassigned_companies.begin(), current_unassigned_companies.end(), rng);\n\n        // Assign companies one by one until all are assigned.\n        while (!current_unassigned_companies.empty()) {\n            // Pick the next company to assign. It's the last one in the shuffled list.\n            int company_idx = current_unassigned_companies.back();\n            current_unassigned_companies.pop_back();\n            \n            const Company& company = companies_data[company_idx];\n            ll r_i = company.r;\n\n            // Pick an available region to place this company's ad.\n            // Heuristic: Randomly choose an available region. Other heuristics could be min area, etc.\n            if (available_regions.empty()) {\n                 // This scenario implies an issue: unassigned companies but no space left.\n                 // It suggests the partitioning logic or previous choices were flawed.\n                 iteration_failed = true; \n                 break; // Abandon this iteration.\n            }\n            \n            uniform_int_distribution<int> region_dist(0, available_regions.size() - 1);\n            int region_to_use_idx = region_dist(rng);\n            Rect region = available_regions[region_to_use_idx];\n\n            // Find all possible integer (width, height) pairs that form the desired area r_i\n            // and fit within the chosen region.\n            vector<pair<int, int>> valid_dims;\n            vector<ll> r_i_divisors = get_divisors(r_i); // Get divisors of desired area.\n\n            // Check each divisor 'w' to see if corresponding 'h' fits.\n            for (ll w_ll : r_i_divisors) {\n                int w = static_cast<int>(w_ll); // Cast is safe as w is limited by region.width() <= 10000.\n                if (w > 0 && w <= region.width()) {\n                    ll h_ll = r_i / w;\n                    if (h_ll > 0 && h_ll <= region.height()) {\n                        // If both width and height fit, this is a valid dimension pair.\n                        valid_dims.push_back({w, static_cast<int>(h_ll)}); // Cast is safe as h is limited by region.height() <= 10000.\n                    }\n                }\n            }\n\n            if (valid_dims.empty()) {\n                // If no valid (w, h) pair can form area r_i and fit in the region,\n                // this indicates that the chosen region is too small or has incompatible dimensions for r_i.\n                // Since sum of r_i equals total area, an exact fit should ideally be possible with proper partitioning.\n                // This means the current random choices led to an unresolvable state for this iteration.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose dimensions (w, h) from the list of valid options.\n            // Heuristic: Pick a random pair from valid_dims to explore different shapes.\n            uniform_int_distribution<int> dims_dist(0, valid_dims.size() - 1);\n            pair<int, int> dim = valid_dims[dims_dist(rng)];\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Determine the valid range for the top-left corner (a, b) of the rectangle.\n            // The rectangle [a, a+w) x [b, b+h) must cover the point (company.x+0.5, company.y+0.5).\n            // This means: a <= company.x < a+w AND b <= company.y < b+h.\n            // With integer coordinates, this translates to:\n            // a <= company.x AND a+w >= company.x + 1  => a >= company.x + 1 - w\n            // b <= company.y AND b+h >= company.y + 1  => b >= company.y + 1 - h\n            // Additionally, the rectangle must be within the selected region:\n            // region.x1 <= a AND a+w <= region.x2  => a <= region.x2 - w\n            // region.y1 <= b AND b+h <= region.y2  => b <= region.y2 - h\n            \n            // Combining these constraints to find the valid range for 'a' and 'b'.\n            int min_a = max(region.x1, company.x + 1 - w);\n            int max_a = min(region.x2 - w, company.x);\n            int min_b = max(region.y1, company.y + 1 - h);\n            int max_b = min(region.y2 - h, company.y);\n\n            if (min_a > max_a || min_b > max_b) {\n                // If the valid ranges are empty, it means no position 'a' or 'b' exists\n                // to satisfy all conditions simultaneously. This should ideally not happen\n                // if previous steps (finding valid_dims) were correct and the point is indeed within the region.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose the placement (a, b).\n            // Heuristic: Push the rectangle to the top-left corner (min_a, min_b) of its valid placement range.\n            // This aims to leave larger contiguous areas in the remaining space, potentially aiding future assignments.\n            int a = min_a;\n            int b = min_b;\n            \n            // Assign the rectangle [a, a+w) x [b, b+h) to the company.\n            current_assignments[company_idx] = {a, b, a + w, b + h};\n            ll s_i = (ll)w * h; // Actual area assigned.\n            // Accumulate satisfaction for this company.\n            current_total_satisfaction += calculate_satisfaction(r_i, s_i);\n\n            // Update the list of available regions.\n            // Remove the region that was just used.\n            available_regions.erase(available_regions.begin() + region_to_use_idx);\n\n            // Add the new regions created by partitioning the used region R with the assigned rectangle R_idx.\n            Rect assigned_rect = {a, b, a + w, b + h};\n            \n            // Add region to the left of the assigned rectangle, if it has positive width.\n            if (region.x1 < assigned_rect.x1) {\n                available_regions.push_back({region.x1, region.y1, assigned_rect.x1, region.y2});\n            }\n            // Add region to the right, if it has positive width.\n            if (assigned_rect.x2 < region.x2) {\n                available_regions.push_back({assigned_rect.x2, region.y1, region.x2, region.y2});\n            }\n            // Add region below the assigned rectangle, if it has positive height.\n            if (region.y1 < assigned_rect.y1) {\n                available_regions.push_back({assigned_rect.x1, region.y1, assigned_rect.x2, assigned_rect.y1});\n            }\n            // Add region above the assigned rectangle, if it has positive height.\n            if (assigned_rect.y2 < region.y2) {\n                available_regions.push_back({assigned_rect.x1, assigned_rect.y2, assigned_rect.x2, region.y2});\n            }\n        } // End of while loop: assigning companies within one iteration.\n\n        // After assigning all companies for this iteration, check if it was successful and if it's better than the overall best found so far.\n        if (!iteration_failed && current_total_satisfaction > overall_best_result.total_satisfaction) {\n            overall_best_result.total_satisfaction = current_total_satisfaction;\n            overall_best_result.assignments = current_assignments;\n        }\n    } // End of loop: performing multiple iterations.\n\n    // The problem implies a valid solution is always achievable. If overall_best_result.total_satisfaction is still -1.0,\n    // it means all iterations failed, indicating a potential issue with the algorithm or heuristics.\n    // However, with enough iterations and a reasonable algorithm, at least one should yield a valid assignment.\n\n    return overall_best_result;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n    companies_data.resize(N);\n    ll total_r_sum = 0; // For verification, though problem guarantees sum r_i = 10^8.\n    for (int i = 0; i < N; ++i) {\n        companies_data[i].id = i;\n        cin >> companies_data[i].x >> companies_data[i].y >> companies_data[i].r;\n        total_r_sum += companies_data[i].r;\n    }\n\n    // The problem statement guarantees that the sum of desired areas equals the total area of the 10000x10000 space.\n    // This is a strong hint that an optimal solution involves no wasted space (sum of assigned areas = total area).\n\n    // Initialize the initial available region: the entire 10000x10000 canvas.\n    initial_available_regions.push_back({0, 0, 10000, 10000});\n\n    // Run the solver to get the best assignment found.\n    AssignmentResult final_assignment = solve();\n\n    // Output the resulting rectangle coordinates for each company.\n    for (int i = 0; i < N; ++i) {\n        cout << get<0>(final_assignment.assignments[i]) << \" \"\n             << get<1>(final_assignment.assignments[i]) << \" \"\n             << get<2>(final_assignment.assignments[i]) << \" \"\n             << get<3>(final_assignment.assignments[i]) << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <vector> // Included for general utility, though not strictly used by the final greedy logic\n#include <algorithm> // Included for general utility, e.g., std::fill could be used for initialization\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 50;\n\n// Global arrays for grid data and visited status.\n// Static allocation is used as the grid size is fixed and memory limits are generous.\nint grid[N][N]; // Stores the score p_ij for each square (0 <= p_ij <= 99)\nint tile_map[N][N]; // Stores the tile ID t_ij for each square (0 <= t_ij <= M-1)\nint max_tile_id_plus_1 = 0; // Tracks the total number of unique tiles (M). M is max_tile_id + 1.\n\nbool visited_squares[N][N]; // Boolean matrix to ensure path simplicity (no revisiting squares).\n// The maximum possible tile ID is N*N - 1 (e.g., if all tiles are 1x1 and N*N distinct tiles exist).\n// Thus, an array of size N*N is sufficient to cover all possible tile IDs from 0 to N*N-1.\nbool used_tiles[N * N]; \n\n// Movement directions: Up, Down, Left, Right.\n// These arrays define the change in row (dr) and column (dc) for each of the four cardinal directions.\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\n// Corresponding characters for outputting the path. 'U' for Up, 'D' for Down, 'L' for Left, 'R' for Right.\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize C++ standard streams for faster input/output operations, crucial in competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial position (si, sj) from standard input.\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read the grid scores p_ij for all 50x50 squares.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Read the tile map t_ij for all squares and determine the total number of unique tiles (M).\n    // The problem states that tile IDs range from 0 to M-1, so M is `max_tile_id + 1`.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile_map[i][j];\n            // Update `max_tile_id_plus_1` if a tile ID implies a larger total number of tiles.\n            if (tile_map[i][j] + 1 > max_tile_id_plus_1) {\n                max_tile_id_plus_1 = tile_map[i][j] + 1;\n            }\n        }\n    }\n\n    // Initialize `visited_squares` matrix. Initially, no squares have been visited.\n    // A simple nested loop is efficient for initializing fixed-size arrays.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_squares[i][j] = false;\n        }\n    }\n    \n    // Initialize `used_tiles` array. Initially, no tiles are considered used.\n    // We only need to initialize entries corresponding to actual tile IDs, from 0 up to M-1.\n    for(int i = 0; i < max_tile_id_plus_1; ++i) {\n        used_tiles[i] = false;\n    }\n\n    string path_string = \"\"; // This string will store the sequence of moves (e.g., \"UDLRU\").\n    int current_r = si;    // Initialize current row position to the starting row.\n    int current_c = sj;    // Initialize current column position to the starting column.\n\n    // Mark the starting square as visited and its corresponding tile as used.\n    // This is because Takahashi starts on this square, and it counts as being stepped on.\n    visited_squares[current_r][current_c] = true;\n    // The tile ID at the starting position is guaranteed to be a valid index into `used_tiles`.\n    used_tiles[tile_map[current_r][current_c]] = true;\n\n    // Main loop for constructing the path using a greedy strategy.\n    // The loop continues as long as there are valid moves to make.\n    while (true) {\n        int best_neighbor_score = -1; // Stores the score of the best valid neighbor found. Initialized to -1 to ensure any non-negative score is considered better.\n        int best_dr = -1, best_dc = -1; // Stores the row and column delta for the best move.\n        char best_move_char = ' ';      // Stores the character representation ('U', 'D', 'L', 'R') of the best move.\n\n        // Explore all 4 possible adjacent squares from the current position.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current_r + dr[i]; // Calculate the row of the neighboring square.\n            int nc = current_c + dc[i]; // Calculate the column of the neighboring square.\n\n            // Constraint 1: Boundary Check.\n            // Ensure the neighboring square is within the 50x50 grid limits.\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n                continue; // Skip this neighbor if it's out of bounds.\n            }\n\n            // Constraint 2: Path Simplicity Check.\n            // Ensure the neighboring square has not been visited before in the current path.\n            if (visited_squares[nr][nc]) {\n                continue; // Skip if the square is already visited.\n            }\n\n            // Constraint 3: Tile Usage Check.\n            // Ensure the tile covering this neighboring square has not been used yet.\n            // `tile_map[nr][nc]` is a valid index because `max_tile_id_plus_1` was determined from all tile IDs present in the input.\n            if (used_tiles[tile_map[nr][nc]]) {\n                continue; // Skip if the tile is already used.\n            }\n\n            // If the move to (nr, nc) is valid according to all constraints:\n            // Apply the greedy heuristic: Select the valid neighbor that offers the highest score (`grid[nr][nc]`).\n            if (grid[nr][nc] > best_neighbor_score) {\n                best_neighbor_score = grid[nr][nc]; // Update the highest score found so far.\n                best_dr = dr[i];                    // Record the direction of this best move.\n                best_dc = dc[i];\n                best_move_char = move_char[i];      // Record the character for this best move.\n            }\n        } // End of loop exploring neighbors.\n\n        // If `best_neighbor_score` remained -1, it means no valid moves were found from the current position.\n        // This signifies the end of the path.\n        if (best_neighbor_score == -1) {\n            break; // Exit the path construction loop.\n        }\n\n        // Execute the best move identified:\n        // Update the current position to the coordinates of the chosen neighbor.\n        current_r += best_dr;\n        current_c += best_dc;\n        // Mark the newly entered square as visited to maintain path simplicity.\n        visited_squares[current_r][current_c] = true; \n        // Mark the tile covering this new square as used, enforcing the tile constraint.\n        used_tiles[tile_map[current_r][current_c]] = true; \n        // Append the character representing this move to the output path string.\n        path_string += best_move_char; \n    }\n\n    // Output the generated path string to standard output.\n    cout << path_string << endl;\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cmath>\n#include <iomanip>\n#include <limits>\n#include <algorithm> // For std::reverse\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 30;\n// Represents infinity for distances\nconst double INF = numeric_limits<double>::infinity();\n\n// --- Edge Weights ---\n// h_weights[i][j] stores the weight of the horizontal edge between (i, j) and (i, j+1).\n// i: row index (0 to 29), j: column index (0 to 28).\ndouble h_weights[N][N - 1];\n// v_weights[i][j] stores the weight of the vertical edge between (i, j) and (i+1, j).\n// i: row index (0 to 28), j: column index (0 to 29).\ndouble v_weights[N - 1][N];\n\n// --- Dijkstra's Algorithm Data Structures ---\n// Stores the predecessor vertex for path reconstruction. pred[r][c] = {pr, pc}\npair<int, int> pred[N][N];\n// Stores the shortest estimated distance from the start node to (r, c).\ndouble dist[N][N];\n\n// --- Helper Functions ---\n\n// Gets the weight of the edge between two adjacent vertices (r1, c1) and (r2, c2).\n// Assumes (r1, c1) and (r2, c2) are indeed adjacent.\ndouble get_weight(int r1, int c1, int r2, int c2) {\n    if (r1 == r2) { // Horizontal edge: same row, different columns\n        // Ensure c_min is the smaller column index for array access\n        int c_min = min(c1, c2);\n        return h_weights[r1][c_min];\n    } else { // Vertical edge: same column, different rows\n        // Ensure r_min is the smaller row index for array access\n        int r_min = min(r1, r2);\n        return v_weights[r_min][c1]; // c1 == c2 for vertical edges\n    }\n}\n\n// Updates the weight of the edge between (r1, c1) and (r2, c2) by adding 'delta'.\n// Ensures the weight does not drop below 1.0.\nvoid update_weight(int r1, int c1, int r2, int c2, double delta) {\n    if (r1 == r2) { // Horizontal edge\n        int c_min = min(c1, c2);\n        h_weights[r1][c_min] = max(1.0, h_weights[r1][c_min] + delta);\n    } else { // Vertical edge\n        int r_min = min(r1, r2);\n        v_weights[r_min][c1] = max(1.0, v_weights[r_min][c1] + delta);\n    }\n}\n\n// Dijkstra's algorithm to find the shortest path from start_node to end_node\n// using the current estimated edge weights.\nvoid dijkstra(pair<int, int> start_node, pair<int, int> end_node) {\n    // Initialize distances to infinity and predecessors to an invalid state.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dist[i][j] = INF;\n            pred[i][j] = {-1, -1}; // Sentinel value indicating no predecessor\n        }\n    }\n\n    // Distance to the start node is 0.\n    dist[start_node.first][start_node.second] = 0;\n\n    // Priority queue stores {negative_distance, {row, col}}.\n    // Using negative distance simulates a min-priority queue with std::priority_queue.\n    priority_queue<pair<double, pair<int, int>>> pq;\n    pq.push({0.0, start_node});\n\n    // Possible moves: Up, Down, Left, Right.\n    int dr[] = {-1, 1, 0, 0}; \n    int dc[] = {0, 0, -1, 1};\n\n    while (!pq.empty()) {\n        // Get the node with the smallest distance from the priority queue.\n        auto [d, curr_node] = pq.top();\n        pq.pop();\n        d = -d; // Convert negative distance back to positive.\n\n        int r = curr_node.first;\n        int c = curr_node.second;\n\n        // If the extracted distance is greater than the known shortest distance, skip.\n        if (d > dist[r][c]) {\n            continue;\n        }\n        \n        // If we have reached the destination, we can break.\n        // Since edge weights are positive, this path is guaranteed to be the shortest.\n        if (curr_node == end_node) {\n            break; \n        }\n\n        // Explore neighbors.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid boundaries.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = get_weight(r, c, nr, nc);\n                // If a shorter path to the neighbor is found, update distance and predecessor.\n                if (dist[r][c] + weight < dist[nr][nc]) {\n                    dist[nr][nc] = dist[r][c] + weight;\n                    pred[nr][nc] = {r, c}; // Set current node as predecessor for neighbor.\n                    pq.push({-dist[nr][nc], {nr, nc}}); // Add neighbor to priority queue.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // --- Initialization ---\n    // Initialize all edge weights to a starting guess.\n    // Edge generation values are typically in the range [1000, 9000].\n    // 5000.0 is a reasonable midpoint.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) { // Horizontal edges\n            h_weights[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) { // Vertical edges\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = 5000.0;\n        }\n    }\n\n    // --- Learning Rate Configuration ---\n    // initial_lr determines the magnitude of weight updates.\n    // It decays over time using 1/k.\n    double initial_lr = 1.0; \n\n    // --- Process Queries ---\n    for (int k = 1; k <= 1000; ++k) {\n        // Read start and end nodes for the current query.\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        pair<int, int> start_node = {si, sj};\n        pair<int, int> end_node = {ti, tj};\n\n        // Find the shortest path using Dijkstra with current estimated weights.\n        dijkstra(start_node, end_node);\n\n        // --- Path Reconstruction and Output ---\n        string path_str = \"\";\n        double estimated_path_length = 0.0;\n        vector<pair<int, int>> path_vertices; // Stores the sequence of vertices in the path.\n\n        // Trace back from the end_node to the start_node using predecessor pointers.\n        pair<int, int> curr = end_node;\n        while (!(curr.first == -1 && curr.second == -1)) { // Stop if predecessor is invalid (-1,-1)\n            path_vertices.push_back(curr);\n            if (curr == start_node) break; // Reached the start node\n            curr = pred[curr.first][curr.second];\n        }\n        // The path_vertices are collected in reverse order (end to start). Reverse them.\n        reverse(path_vertices.begin(), path_vertices.end());\n        \n        // If start and end nodes are different, generate the path string and calculate estimated length.\n        if (path_vertices.size() > 1) { \n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i]; // Current vertex\n                pair<int, int> v = path_vertices[i+1]; // Next vertex\n\n                // Add the weight of the edge (u, v) to the estimated path length.\n                estimated_path_length += get_weight(u.first, u.second, v.first, v.second);\n\n                // Determine the move direction and append to the path string.\n                if (u.first < v.first) path_str += 'D'; // Moved Down (row index increased)\n                else if (u.first > v.first) path_str += 'U'; // Moved Up (row index decreased)\n                else if (u.second < v.second) path_str += 'R'; // Moved Right (column index increased)\n                else if (u.second > v.second) path_str += 'L'; // Moved Left (column index decreased)\n            }\n        }\n        \n        // Output the generated path string.\n        cout << path_str << endl;\n        // Flush the output buffer. This is crucial for the judge to receive the output promptly.\n        cout << flush;\n\n        // --- Feedback and Weight Update ---\n        // Read the feedback integer from the judge. This is a noisy measurement of the path's actual length.\n        long long feedback_k_ll; \n        cin >> feedback_k_ll;\n        double feedback_k = static_cast<double>(feedback_k_ll);\n\n        // Calculate the number of edges in the found path.\n        int num_edges = path_vertices.size() - 1;\n        \n        // Only update weights if the path consists of at least one edge (start != end).\n        if (num_edges > 0) { \n            // Calculate the error: difference between observed feedback and estimated length.\n            double error = feedback_k - estimated_path_length;\n            \n            // Calculate the learning rate, which decays with the query number k.\n            double learning_rate = initial_lr / k; \n            \n            // Calculate the update amount to be applied to each edge in the path.\n            // This distributes the total error proportionally across all edges, scaled by the learning rate.\n            double delta_per_edge = learning_rate * error / num_edges;\n            \n            // Update the weights of all edges that constitute the found path.\n            for (size_t i = 0; i + 1 < path_vertices.size(); ++i) {\n                pair<int, int> u = path_vertices[i];\n                pair<int, int> v = path_vertices[i+1];\n                update_weight(u.first, u.second, v.first, v.second, delta_per_edge);\n            }\n        }\n    }\n\n    return 0; // Program finished successfully.\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <set>\n#include <tuple>\n#include <numeric> // For iota\n#include <chrono> // For time-based seed\n\nusing namespace std;\n\nint N;\nint M;\nvector<string> s;\n\n// Matrix characters\nconst char EMPTY = '.';\nconst vector<char> ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nstruct Placement {\n    int string_idx;\n    int r, c, dir; // dir: 0 for horizontal, 1 for vertical\n    vector<pair<int, int>> cells; // List of (row, col) for this placement\n    int id_in_string; // Unique ID for this placement within string_idx\n};\n\nvector<vector<Placement>> all_placements_for_string;\n// cell_users[r][c] stores a list of (string_idx, placement_id_in_string, pos_in_placement) for all placements using cell (r,c).\nvector<vector<vector<tuple<int, int, int>>>> cell_users; \n\n// State tracking variables\nvector<vector<bool>> placement_validity; // Stores validity for each placement in the current matrix A\nvector<int> valid_placement_count; // Stores total number of valid placements for each string\nvector<bool> is_matched; // Stores if a string is matched (has at least one valid placement)\nint num_matched; // Total number of matched strings\nlong long total_cells_filled; // Number of non-empty cells in the matrix\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Helper for toroidal coordinates\nint mod(int a, int b) {\n    return (a % b + b) % b;\n}\n\n// Calculate score based on current state\nlong double calculate_score_value() {\n    if (num_matched < M) {\n        // Score for not all strings matched: 10^8 * c / M\n        return 1e8 * (long double)num_matched / M;\n    } else {\n        // Score for all strings matched: 10^8 * 2 N^2 / (2 N^2 - d)\n        // d = N*N - total_cells_filled is the number of dots\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) { // Avoid division by zero or very small numbers\n            return 2e8; // Effectively max score, or a very high value\n        }\n        return 1e8 * term_numerator / term_denominator;\n    }\n}\n\n// Check if a specific placement is valid in the given matrix A\nbool is_placement_valid(const Placement& p, const vector<string>& A) {\n    for (size_t i = 0; i < p.cells.size(); ++i) {\n        int r_cell = p.cells[i].first;\n        int c_cell = p.cells[i].second;\n        // A cell is valid for this placement if it's empty or matches the required character\n        if (A[r_cell][c_cell] != EMPTY && A[r_cell][c_cell] != s[p.string_idx][i]) {\n            return false; // Conflict found\n        }\n    }\n    return true; // No conflicts\n}\n\n// Attempts to make a move by changing A[r][c] to new_char.\n// Returns true if the move is accepted and applied, false otherwise.\nbool try_move(vector<string>& A, int r, int c, char new_char) {\n    char old_char = A[r][c];\n    if (old_char == new_char) return false; // No change, skip.\n\n    // --- Store current state for comparison and potential revert ---\n    long double current_score_val = calculate_score_value();\n    // FIX: Store the current global num_matched before any changes.\n    int current_num_matched_snapshot = num_matched; \n    long long current_total_cells_filled = total_cells_filled;\n    \n    // Identify strings potentially affected by changing cell (r,c)\n    set<int> potentially_affected_string_indices;\n    for (const auto& user : cell_users[r][c]) {\n        potentially_affected_string_indices.insert(get<0>(user)); // string_idx\n    }\n\n    // Store old total valid counts for affected strings to revert if the move is rejected.\n    vector<pair<int, int>> old_valid_counts_for_affected;\n    for(int s_idx : potentially_affected_string_indices) {\n        old_valid_counts_for_affected.push_back({s_idx, valid_placement_count[s_idx]});\n    }\n\n    // --- Tentatively apply the change to A ---\n    A[r][c] = new_char;\n\n    // --- Calculate potential new state and score ---\n    // Start potential_num_matched from the snapshot of the current state.\n    int potential_num_matched = current_num_matched_snapshot; \n    long long potential_total_cells_filled = current_total_cells_filled;\n\n    // Update cell count\n    if (old_char == EMPTY && new_char != EMPTY) potential_total_cells_filled++;\n    if (old_char != EMPTY && new_char == EMPTY) potential_total_cells_filled--;\n\n    // Recalculate match status and valid_placement_count for affected strings\n    for (int s_idx : potentially_affected_string_indices) {\n        int new_total_valid_count = 0;\n        // Re-evaluate validity of ALL placements for this string in the *tentatively modified* grid A.\n        for(size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n            if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                new_total_valid_count++;\n            }\n        }\n        \n        // Check if the match status of the string changes.\n        bool was_matched = (valid_placement_count[s_idx] > 0); // Use current global count from before the move.\n        bool now_matched = (new_total_valid_count > 0);\n\n        if (was_matched && !now_matched) {\n            potential_num_matched--; // String becomes unmatched\n        } else if (!was_matched && now_matched) {\n            potential_num_matched++; // String becomes matched\n        }\n        // Tentatively update the global valid_placement_count for this s_idx for use in score calculation.\n        // This value will be restored if the move is rejected.\n        valid_placement_count[s_idx] = new_total_valid_count; \n    }\n\n    // Calculate potential score\n    long double potential_score_val;\n    if (potential_num_matched < M) {\n        potential_score_val = 1e8 * (long double)potential_num_matched / M;\n    } else {\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - potential_total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) {\n            potential_score_val = 2e8; // Max score\n        } else {\n            potential_score_val = 1e8 * term_numerator / term_denominator;\n        }\n    }\n\n    // --- Acceptance criteria ---\n    bool accept = false;\n    if (potential_score_val > current_score_val) {\n        accept = true; // Always accept if score improves\n    } else if (abs(potential_score_val - current_score_val) < 1e-9) { // Scores are approximately equal\n        // Tie-breaking: If all strings are matched (c=M), prefer fewer dots.\n        // FIX: Use the snapshot of current_num_matched here.\n        if (potential_num_matched == M && current_num_matched_snapshot == M) { \n            if (potential_total_cells_filled > current_total_cells_filled) { // Prefer filling more cells\n                accept = true;\n            }\n        }\n    }\n\n    if (accept) {\n        // Apply changes permanently\n        total_cells_filled = potential_total_cells_filled;\n        num_matched = potential_num_matched; // Update global num_matched.\n        \n        // Update `is_matched` based on the final `valid_placement_count` for affected strings.\n        for(int s_idx : potentially_affected_string_indices) {\n            is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n        }\n        return true;\n    } else {\n        // Revert changes if move is not accepted\n        A[r][c] = old_char; // Revert matrix cell\n        \n        // Revert `valid_placement_count` for affected strings.\n        for(const auto& state : old_valid_counts_for_affected) {\n            int s_idx_revert = state.first;\n            int old_count = state.second;\n            valid_placement_count[s_idx_revert] = old_count;\n        }\n        // num_matched and total_cells_filled are implicitly restored by not updating the global variables if not accepted.\n        return false;\n    }\n}\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M;\n    s.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n    }\n\n    // Precomputation: Generate all possible placements for all strings.\n    // For each string, a placement is defined by its starting row, starting column, and direction (horizontal/vertical).\n    all_placements_for_string.resize(M);\n    cell_users.resize(N, vector<vector<tuple<int, int, int>>>(N, vector<tuple<int, int, int>>()));\n    \n    for (int i = 0; i < M; ++i) {\n        int k = s[i].length();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Horizontal placement\n                Placement p_h;\n                p_h.string_idx = i;\n                p_h.r = r; p_h.c = c; p_h.dir = 0; // 0 for horizontal\n                p_h.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_h.cells[pi] = {r, mod(c + pi, N)};\n                }\n                p_h.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_h);\n\n                // Vertical placement\n                Placement p_v;\n                p_v.string_idx = i;\n                p_v.r = r; p_v.c = c; p_v.dir = 1; // 1 for vertical\n                p_v.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_v.cells[pi] = {mod(r + pi, N), c};\n                }\n                p_v.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_v);\n            }\n        }\n    }\n\n    // Populate cell_users: map each cell to which placements use it.\n    // This is crucial for efficiently finding affected strings when a cell changes.\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < all_placements_for_string[i].size(); ++j) {\n            const auto& p = all_placements_for_string[i][j];\n            for (size_t cell_idx = 0; cell_idx < p.cells.size(); ++cell_idx) {\n                int r_cell = p.cells[cell_idx].first;\n                int c_cell = p.cells[cell_idx].second;\n                cell_users[r_cell][c_cell].emplace_back(i, j, cell_idx); // Store (string_idx, placement_id_in_string, pos_in_placement)\n            }\n        }\n    }\n\n    // Initialize matrix and state tracking variables.\n    vector<string> A(N, string(N, EMPTY));\n    total_cells_filled = 0;\n\n    placement_validity.resize(M);\n    valid_placement_count.resize(M, 0);\n    is_matched.resize(M, false);\n    num_matched = 0;\n\n    // Initialize `placement_validity`, `valid_placement_count`, `is_matched` based on the initial empty matrix.\n    for (int i = 0; i < M; ++i) {\n        placement_validity[i].resize(all_placements_for_string[i].size(), false);\n        valid_placement_count[i] = 0; // Initially 0 valid placements for any string\n        is_matched[i] = false; // Initially no string is matched\n    }\n    num_matched = 0; // Initially 0 strings are matched\n\n    // --- Greedy Seeding Phase ---\n    // Iteratively fills the matrix to match as many strings as possible.\n    // Prioritizes placements that use fewer new cells (dots).\n    int max_greedy_passes = 5; // Limit passes to prevent infinite loops if greedy gets stuck.\n    for(int pass = 0; pass < max_greedy_passes; ++pass) {\n        bool new_match_made_in_pass = false;\n        \n        // Process strings in a random order to avoid consistent bias.\n        vector<int> string_order(M);\n        iota(string_order.begin(), string_order.end(), 0);\n        shuffle(string_order.begin(), string_order.end(), rng);\n\n        for (int s_idx : string_order) {\n            if (is_matched[s_idx]) continue; // Skip if already matched.\n\n            int best_p_id = -1;\n            int min_dots_used_for_best_p = N*N + 1; // Initialize with a value larger than possible\n\n            // Find the best valid placement for string `s_idx` in the current matrix `A`.\n            for (size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n                if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                    // Calculate how many currently empty cells this placement would fill.\n                    int current_dots_used = 0;\n                    for (const auto& cell : all_placements_for_string[s_idx][p_id].cells) {\n                        if (A[cell.first][cell.second] == EMPTY) {\n                            current_dots_used++;\n                        }\n                    }\n\n                    // Prioritize placements that require filling fewer empty cells.\n                    if (current_dots_used < min_dots_used_for_best_p) {\n                        min_dots_used_for_best_p = current_dots_used;\n                        best_p_id = p_id;\n                    }\n                }\n            }\n            \n            // If a valid placement was found, apply it to the matrix.\n            if (best_p_id != -1) {\n                const auto& p_to_apply = all_placements_for_string[s_idx][best_p_id];\n                for (const auto& cell : p_to_apply.cells) {\n                    if (A[cell.first][cell.second] == EMPTY) {\n                        // Find the character for this cell from the string `s[s_idx]`.\n                        int cell_pos = -1;\n                        for(size_t pi = 0; pi < p_to_apply.cells.size(); ++pi) {\n                            if (p_to_apply.cells[pi] == cell) {\n                                cell_pos = pi;\n                                break;\n                            }\n                        }\n                        A[cell.first][cell.second] = s[s_idx][cell_pos];\n                        total_cells_filled++; // Increment filled cell count.\n                    }\n                }\n                \n                // Update match status for `s_idx` and global `num_matched`.\n                bool string_s_was_matched = is_matched[s_idx];\n                // Re-evaluate validity for all placements of `s_idx` to get its new status.\n                valid_placement_count[s_idx] = 0;\n                for(size_t p_id_check = 0; p_id_check < all_placements_for_string[s_idx].size(); ++p_id_check) {\n                    placement_validity[s_idx][p_id_check] = is_placement_valid(all_placements_for_string[s_idx][p_id_check], A);\n                    if (placement_validity[s_idx][p_id_check]) {\n                        valid_placement_count[s_idx]++;\n                    }\n                }\n                is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n                \n                if (!string_s_was_matched && is_matched[s_idx]) {\n                    num_matched++; // A new string has become matched.\n                    new_match_made_in_pass = true; // Indicate that progress was made in this pass.\n                }\n                \n                // Propagate match status updates to other strings potentially affected by the newly filled cells.\n                // Collect all strings that use any of the cells that were just filled by `p_to_apply`.\n                set<int> strings_potentially_affected_by_fill;\n                for(const auto& cell : p_to_apply.cells) {\n                    // For each cell in the placement that was just filled:\n                    for (const auto& user : cell_users[cell.first][cell.second]) {\n                        strings_potentially_affected_by_fill.insert(get<0>(user)); // Add the string_idx of users.\n                    }\n                }\n                \n                // Re-evaluate match status for these potentially affected strings.\n                for(int affected_s_idx : strings_potentially_affected_by_fill) {\n                    if (affected_s_idx == s_idx) continue; // Skip the string that was just matched.\n\n                    bool was_matched_affected = is_matched[affected_s_idx];\n                    \n                    // Re-evaluate validity for all placements of `affected_s_idx`.\n                    valid_placement_count[affected_s_idx] = 0;\n                    for(size_t p_id_check = 0; p_id_check < all_placements_for_string[affected_s_idx].size(); ++p_id_check) {\n                        placement_validity[affected_s_idx][p_id_check] = is_placement_valid(all_placements_for_string[affected_s_idx][p_id_check], A);\n                        if (placement_validity[affected_s_idx][p_id_check]) {\n                            valid_placement_count[affected_s_idx]++;\n                        }\n                    }\n                    \n                    bool now_matched_affected = (valid_placement_count[affected_s_idx] > 0);\n\n                    // Update global `num_matched` and `is_matched` if the status changed.\n                    if (was_matched_affected && !now_matched_affected) {\n                        is_matched[affected_s_idx] = false;\n                        num_matched--;\n                        new_match_made_in_pass = true; // Progress made.\n                    } else if (!was_matched_affected && now_matched_affected) {\n                        is_matched[affected_s_idx] = true;\n                        num_matched++;\n                        new_match_made_in_pass = true; // Progress made.\n                    }\n                }\n            }\n        }\n        // If no new strings were matched in a full pass, the greedy phase is done.\n        if (!new_match_made_in_pass) break;\n    }\n\n    // --- Local Search Phase ---\n    // Use simulated annealing-like random walk to improve the solution.\n    // The number of iterations is adjusted based on M to balance exploration and time limit.\n    int ITER_COUNT = 100000;\n    if (M > 600) ITER_COUNT = 80000;\n    if (M > 700) ITER_COUNT = 60000;\n    if (M > 750) ITER_COUNT = 50000;\n    if (M > 780) ITER_COUNT = 40000; // Conservative for high M\n\n    uniform_int_distribution<int> dist_N(0, N - 1);\n    // Distribution for choosing character or EMPTY.\n    // FIX: Cast ALPHABET.size() to int for signed comparison.\n    int char_alphabet_size = static_cast<int>(ALPHABET.size());\n    uniform_int_distribution<int> dist_char_or_empty(0, char_alphabet_size); // Range [0, ALPHABET.size()] inclusive.\n\n    for (int iter = 0; iter < ITER_COUNT; ++iter) {\n        // Pick a random cell to modify.\n        int r = dist_N(rng);\n        int c = dist_N(rng);\n        char old_char = A[r][c];\n        \n        char new_char;\n        // Strategy for choosing the new character depends on whether all strings are matched.\n        if (num_matched == M) { \n            // If all strings are matched, the primary goal is to reduce dots (maximize filled cells).\n            // The best move is to change a character to EMPTY, if possible.\n            if (old_char != EMPTY) {\n                new_char = EMPTY;\n            } else {\n                // If the cell is already EMPTY, changing it to a character will increase dots and decrease score.\n                // So, we skip this iteration, as such a move is unlikely to be beneficial.\n                continue;\n            }\n        } else { \n            // If not all strings are matched, the priority is to match more strings.\n            // Try changing the cell to a random character from the alphabet or to EMPTY.\n            int char_choice = dist_char_or_empty(rng);\n            if (char_choice < char_alphabet_size) { // If not EMPTY index\n                new_char = ALPHABET[char_choice];\n            } else { // If chosen index corresponds to EMPTY\n                new_char = EMPTY;\n            }\n        }\n        \n        // Attempt the move. The `try_move` function handles score evaluation and state updates.\n        try_move(A, r, c, new_char);\n    }\n\n    // Output the final resulting matrix.\n    for (int i = 0; i < N; ++i) {\n        cout << A[i] << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <utility>\n#include <algorithm>\n#include <cmath>\n#include <iomanip> // For potential debugging\n#include <tuple>   // For std::tuple\n\nusing namespace std;\n\n// Use a large enough value for infinity for Dijkstra distances\nconst long long INF = 1e18;\n\nint N; // Grid size\nint si, sj; // Starting row and column\nvector<string> grid; // Stores the grid characters ('#', '5'-'9')\nvector<vector<int>> cost_grid; // Stores the cost to enter a road square\nvector<pair<int, int>> road_coords; // Stores {row, col} for all road squares\nmap<pair<int, int>, int> coord_to_id; // Maps {row, col} to a unique ID for road squares\nvector<vector<vector<int>>> visible_from; // visible_from[r][c] stores IDs of road squares visible from (r, c)\nvector<vector<pair<int, int>>> adj_grid; // adj_grid[r][c] stores {neighbor_r, neighbor_c} for road squares adjacent to (r,c)\nvector<bool> is_road_covered; // Boolean vector, true if road square with that ID is covered\npair<int, int> current_pos; // Current position of the patrol car\nlong long total_time = 0; // Total travel time of the route\nvector<pair<int, int>> route_path; // Stores the sequence of positions (coordinates) in the route\n\n// Directions for movement: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Function to check if a coordinate is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Function to reconstruct path from Dijkstra's parent pointers\nvector<pair<int, int>> reconstruct_path(const vector<vector<pair<int, int>>>& parent, pair<int, int> start_node, pair<int, int> end_node) {\n    vector<pair<int, int>> path;\n    pair<int, int> curr = end_node;\n\n    // Trace back from end_node to start_node using parent pointers\n    while (!(curr.first == start_node.first && curr.second == start_node.second)) {\n        path.push_back(curr);\n        curr = parent[curr.first][curr.second];\n        // If curr.first is -1, it means we reached an invalid parent, implying no path was found\n        if (curr.first == -1) {\n            // This case should ideally not be reached if a path exists\n            // If start_node and end_node are the same, this loop is skipped\n            break; \n        }\n    }\n    \n    // Add the start node itself to the path\n    // If start_node is same as end_node, the loop above is skipped, path is empty.\n    // We push start_node so path becomes [{start_node}]. This is correct.\n    if (!path.empty() || start_node == end_node) {\n        path.push_back(start_node);\n    } else {\n        // If path is empty and start_node != end_node, it implies start_node was unreachable from end_node.\n        // This scenario should not occur given the problem constraints (connected road graph).\n        // For safety, return an empty path if no path is found.\n        return {};\n    }\n   \n    reverse(path.begin(), path.end()); // Reverse to get path from start to end\n    return path;\n}\n\nvoid solve() {\n    // 1. Read input and initialize data structures\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    cost_grid.resize(N, vector<int>(N));\n    adj_grid.resize(N, vector<pair<int, int>>(N)); // Stores neighbors for each grid cell (only road neighbors)\n    visible_from.resize(N, vector<vector<int>>(N));\n\n    int road_id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') { // If it's a road square\n                cost_grid[i][j] = grid[i][j] - '0'; // Store its travel cost\n                road_coords.push_back({i, j}); // Add its coordinates to the list\n                coord_to_id[{i, j}] = road_id_counter++; // Map its coordinates to a unique ID\n            }\n        }\n    }\n\n    is_road_covered.resize(road_coords.size(), false); // Initialize all roads as not covered\n    current_pos = {si, sj}; // Set current position to the start\n    route_path.push_back(current_pos); // Add start position to the route path\n\n    // 2. Precompute visibility and adjacency for each road square\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] != '#') { // Process only road squares\n                int current_road_id = coord_to_id.at({r, c});\n\n                // A square is always visible from itself\n                visible_from[r][c].push_back(current_road_id);\n\n                // Scan in four directions to find all visible road squares\n                // Left\n                for (int k = c - 1; k >= 0; --k) {\n                    if (grid[r][k] == '#') break; // Stop if an obstacle is encountered\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Right\n                for (int k = c + 1; k < N; ++k) {\n                    if (grid[r][k] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({r, k}));\n                }\n                // Up\n                for (int k = r - 1; k >= 0; --k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                // Down\n                for (int k = r + 1; k < N; ++k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from[r][c].push_back(coord_to_id.at({k, c}));\n                }\n                \n                // Build adjacency list for road squares: find adjacent road squares\n                for(int i=0; i<4; ++i) {\n                    int nr = r + dr[i];\n                    int nc = c + dc[i];\n                    if (is_valid(nr, nc) && grid[nr][nc] != '#') {\n                        adj_grid[r][c].push_back({nr, nc}); // Store neighbor coordinates\n                    }\n                }\n            }\n        }\n    }\n\n    // Mark initially covered roads based on the starting position\n    for (int visible_road_id : visible_from[si][sj]) {\n        is_road_covered[visible_road_id] = true;\n    }\n\n    // 3. Greedy phase: iteratively move to cover remaining roads\n    int covered_count = 0;\n    for(bool covered : is_road_covered) if(covered) covered_count++;\n\n    while (covered_count < road_coords.size()) {\n        // Find the best next move: one that maximizes coverage gain per unit cost\n        double best_score = -1.0;\n        int best_next_r = -1, best_next_c = -1;\n        \n        // Store candidates for the next move: (score, cost, next_r, next_c)\n        vector<tuple<double, long long, int, int>> candidates; \n\n        // Iterate through adjacent road squares of the current position\n        for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter this neighbor\n\n            int num_newly_covered = 0;\n            // Count how many currently uncovered roads are visible from this neighbor\n            for (int visible_road_id : visible_from[nr][nc]) {\n                if (!is_road_covered[visible_road_id]) {\n                    num_newly_covered++;\n                }\n            }\n\n            // If this move covers at least one new road, consider it as a candidate\n            if (num_newly_covered > 0) {\n                double current_score = (double)num_newly_covered / move_cost; // Coverage gain per unit cost\n                candidates.emplace_back(current_score, move_cost, nr, nc);\n            }\n        }\n\n        // Select the best candidate move\n        if (!candidates.empty()) {\n            // Sort candidates: primarily by score (descending), secondarily by cost (ascending)\n            sort(candidates.begin(), candidates.end(), [](const auto& a, const auto& b) {\n                if (abs(get<0>(a) - get<0>(b)) > 1e-9) { // Compare scores with tolerance\n                    return get<0>(a) > get<0>(b); // Higher score first\n                }\n                return get<1>(a) < get<1>(b); // Lower cost first for tie-breaking\n            });\n\n            best_next_r = get<2>(candidates[0]);\n            best_next_c = get<3>(candidates[0]);\n            \n        } else {\n            // Fallback strategy: If no adjacent road square offers new coverage,\n            // choose the cheapest move to any adjacent road square to explore.\n            long long min_fallback_cost = -1;\n            for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n                int nr = neighbor_pos.first;\n                int nc = neighbor_pos.second;\n                long long move_cost = cost_grid[nr][nc];\n\n                if (min_fallback_cost == -1 || move_cost < min_fallback_cost) {\n                    min_fallback_cost = move_cost;\n                    best_next_r = nr;\n                    best_next_c = nc;\n                }\n            }\n            // If best_next_r is still -1, it means current_pos has no road neighbors.\n            // This scenario is unlikely in a connected road graph as per problem statement.\n        }\n        \n        // Apply the chosen move\n        total_time += cost_grid[best_next_r][best_next_c]; // Add cost to enter the new square\n        current_pos = {best_next_r, best_next_c}; // Update current position\n        route_path.push_back(current_pos); // Add the new position to the route path\n\n        // Update the coverage status of roads\n        for (int visible_road_id : visible_from[best_next_r][best_next_c]) {\n            if (!is_road_covered[visible_road_id]) {\n                is_road_covered[visible_road_id] = true; // Mark as covered\n                covered_count++; // Increment total count of covered roads\n            }\n        }\n    }\n\n    // 4. Phase 2: Return to the starting position (si, sj) using Dijkstra's algorithm\n    vector<vector<long long>> dist(N, vector<long long>(N, INF)); // Distances\n    vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1})); // Parent pointers for path reconstruction\n    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq; // Priority queue for Dijkstra\n\n    dist[current_pos.first][current_pos.second] = 0; // Distance from current position to itself is 0\n    pq.push({0, current_pos}); // Push start node for Dijkstra\n\n    pair<int, int> dijkstra_target = {si, sj}; // Target is the original start position\n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top();\n        pq.pop();\n\n        // If current distance is greater than recorded distance, skip (already found shorter path)\n        if (d > dist[pos.first][pos.second]) continue;\n        // If we reached the target, break (found shortest path)\n        if (pos == dijkstra_target) break; \n\n        // Explore neighbors\n        for (const auto& neighbor_pos : adj_grid[pos.first][pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; // Cost to enter neighbor\n\n            // Relaxation step\n            if (dist[pos.first][pos.second] + move_cost < dist[nr][nc]) {\n                dist[nr][nc] = dist[pos.first][pos.second] + move_cost;\n                parent[nr][nc] = pos; // Set parent for path reconstruction\n                pq.push({dist[nr][nc], {nr, nc}}); // Push neighbor to priority queue\n            }\n        }\n    }\n\n    // Reconstruct and append the return path to the route_path\n    vector<pair<int, int>> return_path_coords = reconstruct_path(parent, current_pos, dijkstra_target);\n    \n    // Append the steps from the return path, starting from the second element\n    // (the first element would be the current_pos itself, which is already in route_path)\n    if (!return_path_coords.empty()) {\n        for (size_t i = 1; i < return_path_coords.size(); ++i) {\n            route_path.push_back(return_path_coords[i]);\n            total_time += cost_grid[return_path_coords[i].first][return_path_coords[i].second]; // Add cost to enter each step\n        }\n    }\n\n    // 5. Generate the output route string (sequence of moves)\n    string result_route = \"\";\n    for (size_t i = 0; i + 1 < route_path.size(); ++i) {\n        pair<int, int> p1 = route_path[i];\n        pair<int, int> p2 = route_path[i+1];\n        int dr_move = p2.first - p1.first;\n        int dc_move = p2.second - p1.second;\n\n        if (dr_move == -1 && dc_move == 0) result_route += 'U'; // Up\n        else if (dr_move == 1 && dc_move == 0) result_route += 'D'; // Down\n        else if (dr_move == 0 && dc_move == -1) result_route += 'L'; // Left\n        else if (dr_move == 0 && dc_move == 1) result_route += 'R'; // Right\n    }\n\n    // Output the generated route string\n    cout << result_route << endl;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main logic\n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n// Enum for task status\nenum TaskStatus {\n    UNSTARTED,\n    READY,\n    IN_PROGRESS,\n    COMPLETED\n};\n\n// A large value representing an unknown or very large estimated skill deficit.\n// The maximum possible w_ij could be around K * max(d_ik) ~ 20 * 160 = 3200.\n// Using 3300.0 ensures it's larger than any realistic w_ij.\nconst double INF_ESTIMATED_W = 3300.0; \n\nint N, M, K, R;\nvector<vector<int>> d; // d[task_idx][skill_idx]: required skill levels for task i\nvector<vector<int>> adj; // adj[task_idx]: list of tasks that depend on this task (successors)\nvector<int> in_degree; // in_degree[task_idx]: number of prerequisites not yet met for this task\n\nvector<TaskStatus> task_status;\nvector<bool> member_free; // True if member is available to take a new task\nvector<int> member_current_task; // Stores task_idx if member is busy, -1 otherwise\nvector<int> task_start_day; // Stores the day a task was STARTED (1-indexed day)\n\n// Data for learning and estimation\n// estimated_w[member_idx][task_idx]: estimated skill deficit w_ij for member j on task i.\n// Initialized to INF_ESTIMATED_W. Updated when member j completes task i.\nvector<vector<double>> estimated_w; \n\n// Statistics for members: used for fallback estimation when specific (member, task) w is unknown\nvector<int> member_task_count; // Number of tasks completed by this member\nvector<double> sum_observed_times_member; // Sum of durations of tasks completed by this member\n\n// Global statistics: used as a fallback when member-specific info is also unavailable\ndouble global_average_observed_duration = INF_ESTIMATED_W;\nlong long global_total_tasks_completed = 0;\ndouble global_total_observed_time = 0.0;\n\n// Structure to represent a potential assignment (member, task) with its estimated duration.\n// Used for sorting to greedily pick the best assignments.\nstruct Assignment {\n    double estimated_duration;\n    int member_idx;\n    int task_idx;\n\n    // Custom comparison for sorting: primarily by estimated_duration (ascending).\n    // Smaller duration is better. Tie-breaking is done by member_idx then task_idx for determinism.\n    bool operator<(const Assignment& other) const {\n        // Use a small epsilon for floating point comparisons to avoid issues with precision.\n        if (abs(estimated_duration - other.estimated_duration) > 1e-9) {\n            return estimated_duration < other.estimated_duration;\n        }\n        // Tie-breaking: Prefer lower indexed member, then lower indexed task.\n        if (member_idx != other.member_idx) {\n            return member_idx < other.member_idx;\n        }\n        return task_idx < other.task_idx;\n    }\n};\n\n// Updates the estimated_w for a specific (member_idx, task_idx) pair based on observed time.\n// This function is called at most once for each (member, task) pair because a task\n// is assigned to at most one member, and a member is assigned at most one task at a time.\nvoid update_estimated_w(int member_idx, int task_idx, int observed_time) {\n    double w_val;\n    if (observed_time == 1) {\n        // If task took 1 day, according to the problem statement (w_ij=0 => t_ij=1), w_ij must be 0.\n        w_val = 0.0;\n    } else {\n        // If observed_time > 1, then observed_time = w_ij + r_i, where r_i is a random integer in [-3, 3].\n        // This implies w_ij is in the range [max(0, observed_time - 3), observed_time + 3].\n        // We use the midpoint of this range as our best estimate for w_ij.\n        double w_min = max(0, observed_time - 3);\n        double w_max = observed_time + 3;\n        w_val = (w_min + w_max) / 2.0; \n    }\n    // Store the estimated skill deficit.\n    estimated_w[member_idx][task_idx] = w_val;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial problem parameters.\n    cin >> N >> M >> K >> R;\n\n    // Read task difficulty levels (d_i,k).\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Read task dependencies, build adjacency list (successors) and in-degree array.\n    adj.resize(N);\n    in_degree.resize(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; // Dependency: u must be completed before v can start.\n        cin >> u >> v;\n        --u; --v; // Convert to 0-indexed: u is prerequisite for v.\n        adj[u].push_back(v); // Add v to the adjacency list of u.\n        in_degree[v]++; // Increment in-degree of v.\n    }\n\n    // Initialize state variables for tasks and members.\n    task_status.resize(N, UNSTARTED);\n    member_free.resize(M, true);\n    member_current_task.resize(M, -1);\n    task_start_day.resize(N, -1); // -1 indicates task has not started yet.\n\n    // Initialize data structures for learning and estimation.\n    estimated_w.resize(M, vector<double>(N, INF_ESTIMATED_W));\n    member_task_count.resize(M, 0);\n    sum_observed_times_member.resize(M, 0.0);\n\n    // Identify tasks that are initially ready (have an in-degree of 0).\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) {\n            task_status[i] = READY;\n        }\n    }\n\n    int current_day = 1; // Simulation starts from day 1.\n    int completed_tasks_count = 0; // Counter for total completed tasks.\n\n    // Main simulation loop, runs day by day until all tasks are completed or time limit is reached.\n    while (completed_tasks_count < N) {\n        // 1. Process tasks completed at the END of the previous day.\n        vector<int> completed_members_indices_today; // Store indices of members who finished tasks.\n        int n_completed_input;\n        cin >> n_completed_input;\n\n        // Check for termination signal (-1) from the judge.\n        if (n_completed_input == -1) {\n            break; // Exit simulation if signal is received.\n        }\n\n        for (int i = 0; i < n_completed_input; ++i) {\n            int f_idx_1based;\n            cin >> f_idx_1based;\n            int member_idx = f_idx_1based - 1; // Convert member ID to 0-indexed.\n\n            completed_members_indices_today.push_back(member_idx);\n\n            int task_idx = member_current_task[member_idx]; // Get the task this member was working on.\n            \n            // Calculate the time taken for the task.\n            // A task started on task_start_day[task_idx] and finished at the end of current_day\n            // took current_day - task_start_day[task_idx] days.\n            int observed_time = current_day - task_start_day[task_idx];\n\n            // Update global statistics for overall average performance.\n            global_total_observed_time += observed_time;\n            global_total_tasks_completed++;\n            // Re-calculate global average duration to be more accurate.\n            global_average_observed_duration = global_total_observed_time / global_total_tasks_completed;\n\n            // Learn from the completed task: update estimated_w for this specific (member, task) pair.\n            update_estimated_w(member_idx, task_idx, observed_time);\n            \n            // Update task status to COMPLETED.\n            task_status[task_idx] = COMPLETED;\n            completed_tasks_count++;\n\n            // Mark the member as free, ready for a new assignment.\n            member_free[member_idx] = true;\n            member_current_task[member_idx] = -1;\n            \n            // Update member-specific statistics for future estimations.\n            member_task_count[member_idx]++;\n            sum_observed_times_member[member_idx] += observed_time;\n\n            // Update dependencies: decrement in-degree of successor tasks.\n            // If a successor task's in-degree becomes 0, it becomes READY.\n            for (int dependent_task_idx : adj[task_idx]) {\n                in_degree[dependent_task_idx]--;\n                if (in_degree[dependent_task_idx] == 0) {\n                    task_status[dependent_task_idx] = READY;\n                }\n            }\n        }\n        \n        // 2. Generate potential assignments for the current day.\n        vector<Assignment> candidates; // List to store all possible assignments with their estimated durations.\n        vector<int> ready_tasks_indices;\n        // Collect indices of all tasks that are currently READY.\n        for(int i=0; i<N; ++i) {\n            if (task_status[i] == READY) {\n                ready_tasks_indices.push_back(i);\n            }\n        }\n\n        // For every free member and every ready task, calculate an estimated duration.\n        for (int j = 0; j < M; ++j) { // Iterate through all members\n            if (member_free[j]) { // If member j is available\n                for (int task_idx : ready_tasks_indices) { // Consider all ready tasks\n                    double estimated_duration;\n                    \n                    // Heuristic: Estimate task duration for this (member, task) pair.\n                    // We prioritize assignments with the shortest estimated duration.\n                    // The estimation logic follows a hierarchy of information availability:\n                    // 1. Specific (member, task) estimate: If we have observed member j doing task i before.\n                    // 2. Member's average performance: If member j has completed other tasks.\n                    // 3. Global average performance: If member j is new and no other info is available.\n                    // 4. A very large value: If no historical data exists globally.\n\n                    // 1. Check if `estimated_w[j][task_idx]` has been updated from its initial large value.\n                    // The check ` < INF_ESTIMATED_W - 1.0` is a robust way to see if it's been set.\n                    if (estimated_w[j][task_idx] < INF_ESTIMATED_W - 1.0) { \n                        // `estimated_w` is the estimated skill deficit.\n                        // The estimated time to complete is max(1, estimated_w). This assumes r_i=0 for expected time.\n                        estimated_duration = max(1.0, estimated_w[j][task_idx]);\n                    } else {\n                        // 2. Fallback: Member j has some history (completed other tasks). Use their average completion time.\n                        if (member_task_count[j] > 0) {\n                            estimated_duration = sum_observed_times_member[j] / member_task_count[j];\n                        } else {\n                            // 3. Truly global fallback: Member j is new. Use global average observed time if available.\n                            if (global_total_tasks_completed > 0) {\n                                estimated_duration = global_average_observed_duration;\n                            } else {\n                                // 4. If no tasks have been completed globally yet, use a default high value.\n                                estimated_duration = INF_ESTIMATED_W;\n                            }\n                        }\n                    }\n                    \n                    // Ensure minimum duration is 1 day, as per problem statement.\n                    estimated_duration = max(1.0, estimated_duration);\n                    candidates.push_back({estimated_duration, j, task_idx}); // Add this potential assignment to candidates.\n                }\n            }\n        }\n\n        // Sort all candidate assignments by their estimated duration (ascending).\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Make assignments for the current day.\n        vector<pair<int, int>> assignments_today; // Stores {member_idx, task_idx} for output.\n        vector<bool> task_assigned_today(N, false); // Helper to ensure each task is assigned at most once per day.\n        \n        // Iterate through sorted candidates and make assignments greedily.\n        for (const auto& assignment : candidates) {\n            // Stop if we have already assigned tasks to all M members.\n            if (assignments_today.size() == M) { \n                break;\n            }\n            \n            int member_idx = assignment.member_idx;\n            int task_idx = assignment.task_idx;\n\n            // Check if the member is still free, the task is still ready, and the task hasn't been assigned today.\n            if (member_free[member_idx] && task_status[task_idx] == READY && !task_assigned_today[task_idx]) {\n                // Make the assignment.\n                member_free[member_idx] = false; // Mark member as busy.\n                member_current_task[member_idx] = task_idx; // Assign task to member.\n                task_start_day[task_idx] = current_day; // Record the start day.\n                task_status[task_idx] = IN_PROGRESS; // Update task status.\n                \n                assignments_today.push_back({member_idx, task_idx}); // Record assignment for output.\n                task_assigned_today[task_idx] = true; // Mark task as assigned for today.\n            }\n        }\n\n        // 4. Output assignments for the current day.\n        cout << assignments_today.size(); // Number of assignments.\n        for (const auto& p : assignments_today) {\n            // Output member ID and task ID (1-based).\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1; \n        }\n        cout << endl;\n        cout.flush(); // Ensure output is sent immediately.\n\n        current_day++; // Advance to the next day.\n    }\n\n    return 0; // End of simulation.\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <iomanip> // For std::fixed and std::setprecision\n\n// Use long long for coordinates and distances to be safe, although int might suffice for coordinates\nusing coord_t = int;\nusing dist_t = long long;\n\nstruct Point {\n    coord_t x, y;\n    int id; // Original order ID, or special ID for office\n\n    // Equality operator for point comparisons\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Less than operator for potential use in sets/maps\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// Calculate Manhattan distance between two points\ndist_t manhattan_distance(const Point& p1, const Point& p2) {\n    // Use static_cast to long long to prevent intermediate overflow in abs() if coordinates are large\n    return std::abs(static_cast<long long>(p1.x) - p2.x) + std::abs(static_cast<long long>(p1.y) - p2.y);\n}\n\n// Structure to hold information about a single delivery order\nstruct Order {\n    int id;\n    Point pickup;\n    Point delivery;\n    dist_t internal_dist; // Manhattan distance between pickup and delivery\n    dist_t dist_to_office_pickup; // Manhattan distance from office to pickup\n    dist_t dist_delivery_to_office; // Manhattan distance from delivery to office\n};\n\n// Structure for candidate points during route construction\n// Represents a point to visit next, along with its cost and type (pickup/delivery)\nstruct Candidate {\n    Point p;\n    dist_t cost;        // Cost to reach this point from the current location\n    int type;           // 0 for pickup, 1 for delivery\n    int order_id;       // The ID of the order this point belongs to\n    dist_t dist_to_office; // Pre-calculated distance from this point to the office (for tie-breaking)\n\n    // Custom comparison for sorting candidates by cost, then type, then distance to office\n    bool operator<(const Candidate& other) const {\n        if (cost != other.cost) {\n            return cost < other.cost;\n        }\n        // Tie-breaking:\n        // 1. Prefer pickups over deliveries.\n        if (type != other.type) {\n            return type < other.type; // 0 (pickup) < 1 (delivery)\n        }\n        // 2. If same type (both pickups or both deliveries):\n        //    Prefer the point that is closer to the office.\n        return dist_to_office < other.dist_to_office; \n    }\n};\n\n// Helper function to determine the grid cell coordinates for a given point\nstd::pair<int, int> get_cell(const Point& p) {\n    // 800x800 area, divided into 10x10 grid. Cell size is 80x80.\n    return {p.x / 80, p.y / 80}; \n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::vector<Order> all_orders(1000);\n    Point office = {400, 400, -1}; // Office location, ID -1 signifies office\n\n    // Read input for all 1000 orders\n    for (int i = 0; i < 1000; ++i) {\n        all_orders[i].id = i + 1; // Order IDs are 1-based\n        std::cin >> all_orders[i].pickup.x >> all_orders[i].pickup.y >> all_orders[i].delivery.x >> all_orders[i].delivery.y;\n        \n        // Assign original order ID to Point objects\n        all_orders[i].pickup.id = i + 1;\n        all_orders[i].delivery.id = i + 1;\n\n        // Pre-calculate distances for scoring and route construction\n        all_orders[i].internal_dist = manhattan_distance(all_orders[i].pickup, all_orders[i].delivery);\n        all_orders[i].dist_to_office_pickup = manhattan_distance(office, all_orders[i].pickup);\n        all_orders[i].dist_delivery_to_office = manhattan_distance(all_orders[i].delivery, office);\n    }\n\n    // --- Order Selection Heuristic ---\n    // Strategy: Select orders that are spatially clustered and relatively close to the office.\n    // 1. Group orders by the cell their pickup point falls into.\n    // 2. Score cells based on the average distance from the office to pickup points within them.\n    // 3. Prioritize cells closest to the office.\n    // 4. Collect candidate orders from prioritized cells, sorting them by internal travel distance.\n    // 5. Further refine candidates by a combined score and select the top 50.\n\n    // Map to group orders by their pickup cell\n    std::map<std::pair<int, int>, std::vector<Order*>> cell_to_orders_map;\n    for (auto& order : all_orders) {\n        cell_to_orders_map[get_cell(order.pickup)].push_back(&order);\n    }\n\n    // Calculate scores for each cell and store them along with cell coordinates\n    // Use double for average distance for better precision in cell scoring\n    std::vector<std::pair<double, std::pair<int, int>>> cell_scores; \n    for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n        if (order_list.empty()) continue; // Skip empty cells\n        dist_t total_dist_to_cell_pickup = 0;\n        for (Order* order_ptr : order_list) {\n            total_dist_to_cell_pickup += manhattan_distance(office, order_ptr->pickup);\n        }\n        // Average distance = total distance / number of orders in cell\n        cell_scores.push_back({static_cast<double>(total_dist_to_cell_pickup) / order_list.size(), cell_coord});\n    }\n\n    // Sort cells based on their average distance score (ascending)\n    std::sort(cell_scores.begin(), cell_scores.end());\n\n    // Pool of candidate orders to choose from. We aim for more than 50 initially to allow for better final selection.\n    std::vector<Order*> candidate_orders_pool; \n    std::set<int> added_order_ids; // Keep track of added orders to avoid duplicates\n\n    // Collect orders from the best cells first (lowest average distance to office)\n    // Increased pool size for potentially better order selection.\n    const int MAX_CANDIDATES_TO_CONSIDER = 300; \n\n    for (const auto& cell_score_pair : cell_scores) {\n        std::pair<int, int> cell_coord = cell_score_pair.second;\n        if (cell_to_orders_map.count(cell_coord)) {\n            std::vector<Order*>& orders_in_cell = cell_to_orders_map[cell_coord];\n            // Sort orders within this cell by their internal travel distance (shortest first)\n            std::sort(orders_in_cell.begin(), orders_in_cell.end(), [](Order* a, Order* b) {\n                return a->internal_dist < b->internal_dist;\n            });\n            \n            // Add orders from this cell to the candidate pool if not already added\n            for (Order* order_ptr : orders_in_cell) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n        }\n        // Stop collecting if we have enough candidates\n        if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break; \n    }\n    \n    // If still not enough candidates after processing all prioritized cells,\n    // fill up from any remaining orders not yet considered.\n    if (candidate_orders_pool.size() < MAX_CANDIDATES_TO_CONSIDER) {\n        for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n            for (Order* order_ptr : order_list) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n             if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break;\n        }\n    }\n    \n    // Sort the pool of candidates by a refined score: \n    // internal_dist + min(dist_to_office_pickup, dist_delivery_to_office).\n    // This score prioritizes orders that are short and/or have at least one endpoint near the office.\n    std::sort(candidate_orders_pool.begin(), candidate_orders_pool.end(), [](Order* a, Order* b) {\n        dist_t score_a = a->internal_dist + std::min(a->dist_to_office_pickup, a->dist_delivery_to_office);\n        dist_t score_b = b->internal_dist + std::min(b->dist_to_office_pickup, b->dist_delivery_to_office);\n        return score_a < score_b;\n    });\n\n    // Select the top 50 orders from the sorted candidate pool.\n    std::vector<int> selected_order_ids;\n    std::vector<Order*> selected_orders_ptr; // Pointers to the actual Order objects for selected orders\n    for (int i = 0; i < 50; ++i) {\n        selected_order_ids.push_back(candidate_orders_pool[i]->id);\n        selected_orders_ptr.push_back(candidate_orders_pool[i]);\n    }\n\n    // --- Route Construction (Greedy) ---\n    // Uses a greedy approach to build the route, ensuring precedence constraints.\n    // It iteratively picks the cheapest valid next point (pickup or delivery).\n\n    std::vector<Point> route_points; // The sequence of points in the delivery route\n    // Map to quickly access selected order details by their ID\n    std::map<int, Order*> order_map; \n    // Track the visited status of pickups and completed deliveries for selected orders\n    std::map<int, bool> is_pickup_visited;\n    std::map<int, bool> is_delivery_done;\n    \n    // Populate data structures for selected orders\n    for (Order* order_ptr : selected_orders_ptr) {\n        order_map[order_ptr->id] = order_ptr;\n        is_pickup_visited[order_ptr->id] = false;\n        is_delivery_done[order_ptr->id] = false;\n    }\n\n    route_points.push_back(office); // Start the route at the office\n    Point current_location = office;\n    int orders_completed = 0; // Counter for the number of orders fully delivered\n\n    // Greedy construction of the route, ensuring precedence constraints\n    while (orders_completed < 50) {\n        std::vector<Candidate> candidates; // List of possible next points\n\n        // Consider all available pickup points for selected orders\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_pickup_visited[order_id]) {\n                // Add pickup point as a candidate\n                candidates.push_back({order_ptr->pickup, \n                                      manhattan_distance(current_location, order_ptr->pickup), \n                                      0, // type: pickup\n                                      order_id,\n                                      order_ptr->dist_to_office_pickup}); // distance to office for tie-breaking\n            }\n        }\n\n        // Consider all available delivery points IF their pickup has already been visited\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_delivery_done[order_id] && is_pickup_visited[order_id]) {\n                // Add delivery point if its order hasn't been completed AND its pickup has been visited\n                candidates.push_back({order_ptr->delivery, \n                                      manhattan_distance(current_location, order_ptr->delivery), \n                                      1, // type: delivery\n                                      order_id,\n                                      order_ptr->dist_delivery_to_office}); // distance to office for tie-breaking\n            }\n        }\n\n        // If no valid candidates are found, it means we are stuck.\n        // This should not happen if the problem is solvable for the selected 50 orders and the greedy logic is robust.\n        // If this occurs, `orders_completed` will be less than 50, likely leading to a WRONG_ANSWER or a suboptimal route.\n        if (candidates.empty()) {\n            // In a real contest, one might add logging here to debug why this happened.\n            // For now, we break, assuming this is rare with good order selection.\n            break; \n        }\n\n        // Sort candidates to find the best next move (using custom comparator: cost -> type -> dist_to_office)\n        std::sort(candidates.begin(), candidates.end());\n        \n        // Select the best candidate (minimum cost, then type, then distance to office)\n        Candidate best_candidate = candidates[0];\n        \n        // Add the chosen point to the route and update current location\n        route_points.push_back(best_candidate.p);\n        current_location = best_candidate.p;\n\n        // Update status based on the type of point visited\n        if (best_candidate.type == 0) { // It was a pickup\n            is_pickup_visited[best_candidate.order_id] = true;\n        } else { // It was a delivery\n            is_delivery_done[best_candidate.order_id] = true;\n            orders_completed++; // Increment count of fully delivered orders\n        }\n    }\n    \n    route_points.push_back(office); // End the route at the office\n\n    // --- Output ---\n    // Output the list of selected order IDs\n    std::cout << selected_order_ids.size() << std::endl;\n    for (int i = 0; i < selected_order_ids.size(); ++i) {\n        std::cout << selected_order_ids[i] << (i == selected_order_ids.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    // Output the sequence of points in the optimized route\n    std::cout << route_points.size() << std::endl;\n    for (int i = 0; i < route_points.size(); ++i) {\n        std::cout << route_points[i].x << \" \" << route_points[i].y << (i == route_points.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric> // For std::iota\n#include <algorithm> // For std::swap\n\n// Disjoint Set Union (DSU) data structure\n// Used to keep track of connected components.\nstruct DSU {\n    std::vector<int> parent;\n    std::vector<int> sz;\n\n    // Constructor: Initializes DSU for n elements.\n    // Each element is initially in its own set.\n    DSU(int n) {\n        parent.resize(n);\n        // Initialize each element to be its own parent.\n        // std::iota fills the range [begin, end) with sequentially increasing values, starting from value.\n        std::iota(parent.begin(), parent.end(), 0);\n        // Initialize the size of each set to 1.\n        sz.assign(n, 1);\n    }\n\n    // Finds the representative (root) of the set containing element i.\n    // Implements path compression: flattens the tree structure by making every node\n    // on the path from i to the root point directly to the root. This speeds up future find operations.\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n\n    // Unites the sets containing elements i and j.\n    // Returns true if the sets were different and successfully merged, false otherwise\n    // (i.e., if i and j were already in the same set).\n    // Implements union by size: attaches the root of the smaller tree to the root of the larger tree.\n    // This helps keep the tree heights small, improving the efficiency of find operations.\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            // If sizes are different, attach smaller tree to the root of the larger tree.\n            if (sz[root_i] < sz[root_j])\n                std::swap(root_i, root_j);\n            parent[root_j] = root_i;\n            sz[root_i] += sz[root_j];\n            return true; // Successfully merged two distinct sets\n        }\n        return false; // Elements were already in the same set\n    }\n};\n\n// Structure to store edge information: endpoints and calculated d_i\nstruct Edge {\n    int u, v;\n    long long d; // Rounded Euclidean distance\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // std::ios_base::sync_with_stdio(false) unties C++ streams from C stdio.\n    // std::cin.tie(NULL) unties cin from cout, so cin operations do not force a flush of cout.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // The problem statement specifies that N=400 and M=1995 for all test cases.\n    // These values are fixed and NOT read from standard input.\n    // The input starts directly with vertex coordinates.\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates (x_i, y_i) for each vertex.\n    std::vector<std::pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> coords[i].first >> coords[i].second;\n    }\n\n    // Store edge information: endpoints (u, v) and the pre-calculated d_i for each of the M edges.\n    std::vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u_node, v_node;\n        std::cin >> u_node >> v_node; // Read endpoints for edge i\n        edges[i].u = u_node;\n        edges[i].v = v_node;\n\n        // Calculate the Euclidean distance between endpoints u_node and v_node.\n        // Use long double for intermediate calculations to maintain precision,\n        // especially for sqrt and squaring operations.\n        long double dx = static_cast<long double>(coords[u_node].first) - coords[v_node].first;\n        long double dy = static_cast<long double>(coords[u_node].second) - coords[v_node].second;\n        long double dist_sq = dx * dx + dy * dy;\n        long double dist = std::sqrt(dist_sq);\n        \n        // Round the distance to the nearest integer as per problem statement.\n        // static_cast<long long> is used to cast the result of std::round to long long.\n        edges[i].d = static_cast<long long>(std::round(dist));\n    }\n\n    // Initialize the DSU structure for N vertices.\n    // This structure will track which vertices are connected by the edges we adopt.\n    DSU dsu(N);\n\n    // Keep track of how many edges we've chosen that successfully merged components.\n    // To connect N vertices into a single component, we need exactly N-1 such edges.\n    int merges_made = 0;\n\n    // Process each of the M edges in the order they are revealed.\n    for (int i = 0; i < M; ++i) {\n        long long l_i; // The true edge length for the i-th edge, revealed now.\n        std::cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n\n        // Heuristic Strategy: \"Greedy Connectivity\"\n        // We adopt an edge if and only if it connects two previously disconnected components,\n        // AND we still need to perform component merges to ensure full connectivity.\n        // This strategy guarantees that the final set of adopted edges will be connected.\n        // By limiting adopted edges to exactly N-1 that merge components, we avoid creating cycles,\n        // which is crucial for minimizing total cost under this greedy approach.\n\n        if (dsu.find(u) != dsu.find(v)) {\n            // The endpoints u and v belong to different connected components.\n            // This edge is a candidate for connecting components.\n            \n            if (merges_made < N - 1) {\n                // We still need to make component merges to achieve full connectivity.\n                // Adopt this edge.\n                std::cout << 1 << std::endl;\n                dsu.unite(u, v); // Merge the components of u and v.\n                merges_made++;   // Increment the count of successful merges.\n            } else {\n                // We have already made N-1 merges, meaning the graph is now connected.\n                // Any additional edge that connects two components would form a cycle.\n                // To minimize total cost, we reject such redundant edges.\n                std::cout << 0 << std::endl;\n            }\n        } else {\n            // The endpoints u and v are already in the same connected component.\n            // This edge is redundant for connectivity. Reject it to save cost.\n            std::cout << 0 << std::endl;\n        }\n        \n        // std::endl not only inserts a newline character but also flushes the output buffer.\n        // Flushing is required by the problem statement to ensure the judge receives\n        // our output for each step before providing the next input.\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\n// Structures\nstruct Pos {\n    int r, c;\n    // Equality operator for comparing positions\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n    // Less than operator for sorting and using in maps/sets\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n};\n\nstruct Pet {\n    int id;\n    Pos pos;\n    int type;\n};\n\nstruct Human {\n    int id;\n    Pos pos;\n};\n\n// Directions for movement (U, D, L, R)\n// Corresponding dr and dc values\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1}; // U, D, L, R\n// Corresponding characters for movement and blocking actions\nchar move_chars[] = {'U', 'D', 'L', 'R'};\nchar block_chars[] = {'u', 'd', 'l', 'r'};\n\n// --- Helper Functions ---\n\n// Check if a position is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < GRID_SIZE && c >= 0 && c < GRID_SIZE;\n}\n\n// Calculate Manhattan distance between two positions\nint manhattan_distance(Pos p1, Pos p2) {\n    return abs(p1.r - p2.r) + abs(p1.c - p2.c);\n}\n\n// Get character for human movement action (uppercase)\nchar get_direction_char_for_move(Pos from, Pos to) {\n    if (to.r < from.r) return 'U';\n    if (to.r > from.r) return 'D';\n    if (to.c < from.c) return 'L';\n    if (to.c > from.c) return 'R';\n    return '.'; // Should not happen for movement if positions differ\n}\n\n// Get character for human blocking action (lowercase)\nchar get_direction_char_for_block(Pos from, Pos to) {\n    if (to.r < from.r) return 'u';\n    if (to.r > from.r) return 'd';\n    if (to.c < from.c) return 'l';\n    if (to.c > from.c) return 'r';\n    return '.'; // Should not happen for blocking if positions differ\n}\n\n// Get target position from current position and direction character\nPos get_pos_from_dir_char(Pos from, char dir) {\n    Pos to = from;\n    if (dir == 'U' || dir == 'u') to.r--;\n    else if (dir == 'D' || dir == 'd') to.r++;\n    else if (dir == 'L' || dir == 'l') to.c--;\n    else if (dir == 'R' || dir == 'r') to.c++;\n    return to;\n}\n\n// Get precomputed minimum Manhattan distance from a square (r, c) to any pet.\n// Uses a flattened 1D array for quick lookup.\nint get_min_dist_to_pet(int r, int c, const vector<int>& min_pet_dists_flat) {\n    return min_pet_dists_flat[r * GRID_SIZE + c];\n}\n\n// BFS to find reachable squares from a starting position.\n// This function is primarily for scoring calculation after all turns.\npair<int, vector<Pos>> get_reachable_area(Pos start_pos, const vector<vector<bool>>& is_impassable_grid) {\n    vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n    queue<Pos> q;\n    vector<Pos> reachable_squares;\n\n    // If start position is invalid or impassable, return empty area.\n    if (!is_valid(start_pos.r, start_pos.c) || is_impassable_grid[start_pos.r][start_pos.c]) {\n        return {0, {}};\n    }\n\n    q.push(start_pos);\n    visited[start_pos.r][start_pos.c] = true;\n    reachable_squares.push_back(start_pos);\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        // Explore adjacent squares\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n\n            // If adjacent square is valid, not impassable, and not visited, add to queue.\n            if (is_valid(nr, nc) && !is_impassable_grid[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                Pos next_pos = {nr, nc};\n                q.push(next_pos);\n                reachable_squares.push_back(next_pos);\n            }\n        }\n    }\n    return {reachable_squares.size(), reachable_squares};\n}\n\n// --- Global Variables ---\nint N_pets, M_humans;\nvector<Pet> pets_state;\nvector<Human> humans_state;\n// Grid state: true if impassable, false if passable.\nvector<vector<bool>> is_impassable_grid(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n\n// Main logic for the contest problem\nvoid solve() {\n    // Read initial state: pet positions, types, and human positions.\n    cin >> N_pets;\n    pets_state.resize(N_pets);\n    for (int i = 0; i < N_pets; ++i) {\n        pets_state[i].id = i;\n        cin >> pets_state[i].pos.r >> pets_state[i].pos.c >> pets_state[i].type;\n        pets_state[i].pos.r--; pets_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n    cin >> M_humans;\n    humans_state.resize(M_humans);\n    for (int i = 0; i < M_humans; ++i) {\n        humans_state[i].id = i;\n        cin >> humans_state[i].pos.r >> humans_state[i].pos.c;\n        humans_state[i].pos.r--; humans_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n\n    // Game loop for each turn\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        \n        // --- Precomputation for Human Decision Making ---\n        // Calculate minimum distance from every square to any pet.\n        // This is crucial for the human strategy of staying away from pets.\n        vector<int> min_pet_dists_flat(GRID_SIZE * GRID_SIZE);\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                min_pet_dists_flat[r * GRID_SIZE + c] = GRID_SIZE * 2; // Initialize with a large value\n                for (const auto& pet : pets_state) {\n                    min_pet_dists_flat[r * GRID_SIZE + c] = min(min_pet_dists_flat[r * GRID_SIZE + c], manhattan_distance({r, c}, pet.pos));\n                }\n            }\n        }\n\n        // Identify squares that are potentially blockable by humans.\n        // A square is blockable if it's within bounds, not impassable from previous turns,\n        // not occupied by any human or pet at the start of this turn, and not adjacent to any pet.\n        vector<Pos> blockable_squares;\n        vector<bool> is_occupied_at_start(GRID_SIZE * GRID_SIZE, false); // Mark occupied squares for quick checks\n        for (const auto& p : pets_state) is_occupied_at_start[p.pos.r * GRID_SIZE + p.pos.c] = true;\n        for (const auto& h : humans_state) is_occupied_at_start[h.pos.r * GRID_SIZE + h.pos.c] = true;\n\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                // Rule: Cannot block if adjacent to a pet. Minimum distance >= 2.\n                if (!is_impassable_grid[r][c] && !is_occupied_at_start[r * GRID_SIZE + c] && get_min_dist_to_pet(r, c, min_pet_dists_flat) >= 2) {\n                    blockable_squares.push_back({r, c});\n                }\n            }\n        }\n\n        // For each human, store their best potential blocking and moving action.\n        // Format: {score, position}. Initial score is -1.0 indicating no valid option found.\n        vector<pair<double, Pos>> best_block_options(M_humans, {-1.0, {-1, -1}}); \n        vector<pair<double, Pos>> best_move_options(M_humans, {-1.0, {-1, -1}});  \n\n        // --- Evaluate Blocking Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_block_score = -1.0;\n            Pos best_block_pos = {-1, -1};\n\n            for (const auto& sq : blockable_squares) {\n                double current_block_score = 0;\n                // Heuristic: prioritize blocking squares far from pets\n                current_block_score += (double)get_min_dist_to_pet(sq.r, sq.c, min_pet_dists_flat) * 100.0;\n                \n                // Heuristic: prefer extending existing walls (adjacent to already impassable squares)\n                bool adjacent_to_impassable = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = sq.r + dr[d];\n                    int nc = sq.c + dc[d];\n                    if(is_valid(nr, nc) && is_impassable_grid[nr][nc]) {\n                        adjacent_to_impassable = true;\n                        break;\n                    }\n                }\n                if (adjacent_to_impassable) {\n                    current_block_score += 50.0;\n                }\n                \n                // Heuristic: penalize blocking squares far from human's current position (encourages moving towards blocking target)\n                current_block_score -= manhattan_distance(humans_state[i].pos, sq);\n\n                // Update best option if current score is better\n                if (current_block_score > max_block_score) {\n                    max_block_score = current_block_score;\n                    best_block_pos = sq;\n                } else if (abs(current_block_score - max_block_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                    if (sq.r < best_block_pos.r || (sq.r == best_block_pos.r && sq.c < best_block_pos.c)) {\n                        best_block_pos = sq;\n                    }\n                }\n            }\n            // Store the best block option found for human i\n            if (best_block_pos.r != -1) {\n                best_block_options[i] = {max_block_score, best_block_pos};\n            }\n        }\n\n        // --- Evaluate Movement Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_move_score = -1.0;\n            Pos best_move_pos = {-1, -1};\n\n            // Check all 4 adjacent squares for potential movement\n            for (int d = 0; d < 4; ++d) {\n                int nr = humans_state[i].pos.r + dr[d];\n                int nc = humans_state[i].pos.c + dc[d];\n                Pos next_pos = {nr, nc};\n\n                // Can only move to a valid, passable square\n                if (is_valid(nr, nc) && !is_impassable_grid[nr][nc]) {\n                    // Cannot move to a square occupied by another human at the start of the turn\n                    if (!is_occupied_at_start[nr * GRID_SIZE + nc]) { \n                        double current_move_score = 0;\n                        // Heuristic: prefer moving to squares far from pets\n                        current_move_score += (double)get_min_dist_to_pet(nr, nc, min_pet_dists_flat) * 50.0;\n\n                        // Strong incentive to move to a square that this human plans to block\n                        if (best_block_options[i].second == next_pos) {\n                            current_move_score += 100.0;\n                        }\n                        \n                        // Update best option if current score is better\n                        if (current_move_score > max_move_score) {\n                            max_move_score = current_move_score;\n                            best_move_pos = next_pos;\n                        } else if (abs(current_move_score - max_move_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                            if (next_pos.r < best_move_pos.r || (next_pos.r == best_move_pos.r && next_pos.c < best_move_pos.c)) {\n                                best_move_pos = next_pos;\n                            }\n                        }\n                    }\n                }\n            }\n            // Store the best move option found for human i\n            if (best_move_pos.r != -1) {\n                best_move_options[i] = {max_move_score, best_move_pos};\n            }\n        }\n\n        // --- Conflict Resolution and Final Action Assignment ---\n        // This phase determines which actions are actually performed, resolving conflicts.\n        string human_actions_str(M_humans, '.'); // Stores the output action char for each human\n        vector<Pos> squares_to_move_to_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to move\n        vector<Pos> planned_blocks_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to block\n\n        // Structure to hold all potential actions (block or move) for sorting and conflict resolution\n        struct ActionChoice {\n            int human_id;\n            Pos target_pos;\n            double score;\n            bool is_block_action; // true if this choice is to block, false if to move\n\n            // Custom comparator for sorting: higher score first, then lower human_id for tie-breaking\n            bool operator<(const ActionChoice& other) const {\n                if (abs(score - other.score) > 1e-9) return score > other.score; // Sort by score descending\n                return human_id < other.human_id; // Sort by human_id ascending for ties\n            }\n        };\n        vector<ActionChoice> choices;\n\n        // Populate the list of all potential actions\n        for (int i = 0; i < M_humans; ++i) {\n            if (best_block_options[i].first > -1.0) { // If a block option was found\n                choices.push_back({i, best_block_options[i].second, best_block_options[i].first, true});\n            }\n            if (best_move_options[i].first > -1.0) { // If a move option was found\n                choices.push_back({i, best_move_options[i].second, best_move_options[i].first, false});\n            }\n        }\n        // Sort all potential actions based on score and human_id\n        sort(choices.begin(), choices.end());\n\n        vector<bool> human_assigned_action(M_humans, false); // Track if a human has been assigned an action\n\n        // Process sorted choices to assign actions and resolve conflicts\n        for (const auto& choice : choices) {\n            int hid = choice.human_id;\n            Pos target_pos = choice.target_pos;\n            bool is_block = choice.is_block_action;\n\n            if (human_assigned_action[hid]) continue; // Human already has an assigned action\n\n            if (is_block) {\n                // --- Check if this block action is still possible ---\n                bool can_block = true;\n                // 1. Cannot block if target square will be occupied by a moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (squares_to_move_to_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n                // 2. Cannot block if target square is permanently impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) { // If it was impassable before this turn\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) { // And it's currently empty\n                         can_block = false; // Cannot make an already blocked and empty square impassable.\n                     }\n                }\n                // 3. Cannot block if another human has already planned to block this same square.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n\n                // If the block action is valid, assign it.\n                if (can_block) {\n                    human_actions_str[hid] = get_direction_char_for_block(humans_state[hid].pos, target_pos);\n                    planned_blocks_this_turn[hid] = target_pos; // Record this planned block\n                    human_assigned_action[hid] = true;\n                }\n                // If block failed, this human might try their best move action later if available.\n            } else { // This choice is a movement action\n                // --- Check if this move action is still possible ---\n                bool can_move = true;\n                // 1. Cannot move to a square that is already impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) {\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) {\n                         can_move = false;\n                     }\n                }\n                // 2. Cannot move to a square already claimed by another moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (i != hid && squares_to_move_to_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n                // 3. Cannot move to a square that another human plans to block this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n\n                // If the move action is valid, assign it.\n                if (can_move) {\n                    human_actions_str[hid] = get_direction_char_for_move(humans_state[hid].pos, target_pos);\n                    squares_to_move_to_this_turn[hid] = target_pos; // Record this planned move\n                    human_assigned_action[hid] = true;\n                }\n                // If move failed, this human might have a block action as their next best choice.\n            }\n        }\n        \n        // --- Fallback: Handle humans who couldn't get their preferred action or any action ---\n        // If a human's top choice (block or move) was taken or invalid, they might try their second best,\n        // or default to blocking if possible, or default to staying put.\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                // Try to perform the best block action if it failed initially\n                if (best_block_options[i].first > -1.0) {\n                     Pos block_target = best_block_options[i].second;\n                     bool can_block_fallback = true;\n                     // Check availability similar to above\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (squares_to_move_to_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     if (is_impassable_grid[block_target.r][block_target.c]) {\n                          if (!is_occupied_at_start[block_target.r * GRID_SIZE + block_target.c]) { can_block_fallback = false; }\n                     }\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (planned_blocks_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     \n                     if (can_block_fallback) {\n                          human_actions_str[i] = get_direction_char_for_block(humans_state[i].pos, block_target);\n                          planned_blocks_this_turn[i] = block_target;\n                          human_assigned_action[i] = true;\n                     }\n                }\n                // If blocking still not possible, try to perform the best move action if it failed initially\n                if (!human_assigned_action[i] && best_move_options[i].first > -1.0) {\n                    Pos move_target = best_move_options[i].second;\n                    bool can_move_fallback = true;\n                    // Check availability similar to above\n                    if (is_impassable_grid[move_target.r][move_target.c]) {\n                         if (!is_occupied_at_start[move_target.r * GRID_SIZE + move_target.c]) { can_move_fallback = false; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (h_idx != i && squares_to_move_to_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (planned_blocks_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    \n                    if (can_move_fallback) {\n                         human_actions_str[i] = get_direction_char_for_move(humans_state[i].pos, move_target);\n                         squares_to_move_to_this_turn[i] = move_target;\n                         human_assigned_action[i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Final fallback: If a human still has no action assigned, they do nothing (stay put).\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                human_actions_str[i] = '.';\n            }\n        }\n\n        // --- Output Human Actions and Flush ---\n        cout << human_actions_str << endl;\n        cout << flush; // Essential to flush output for interactive problems\n\n        // --- Read Pet Movements and Update Game State ---\n        vector<string> current_pet_moves(N_pets);\n        for (int i = 0; i < N_pets; ++i) {\n            cin >> current_pet_moves[i];\n        }\n\n        // Update Pet Positions based on input movements\n        for (int i = 0; i < N_pets; ++i) {\n            Pos current_pet_pos = pets_state[i].pos; // Current position at start of turn\n            for (char move : current_pet_moves[i]) { // Process each move character in the string\n                if (move == '.') continue; // No move\n\n                Pos next_pet_pos = current_pet_pos;\n                if (move == 'U') next_pet_pos.r--;\n                else if (move == 'D') next_pet_pos.r++;\n                else if (move == 'L') next_pet_pos.c--;\n                else if (move == 'R') next_pet_pos.c++;\n                \n                // Determine if the target square for the pet is passable.\n                // A square is passable for a pet if it's within grid bounds, AND\n                // it's NOT newly blocked by human action THIS turn, AND\n                // it's NOT permanently blocked (from previous turns) AND currently empty.\n                \n                bool target_is_newly_impassable = false; // Blocked by humans THIS turn\n                for(const auto& block_pos : planned_blocks_this_turn) {\n                    if (block_pos == next_pet_pos) {\n                        target_is_newly_impassable = true;\n                        break;\n                    }\n                }\n                \n                bool is_permanently_blocked_and_empty = false; // Blocked from PREVIOUS turns and currently empty\n                if (is_impassable_grid[next_pet_pos.r][next_pet_pos.c]) { // If it was impassable before this turn\n                    if (!is_occupied_at_start[next_pet_pos.r * GRID_SIZE + next_pet_pos.c]) { // And it's currently empty\n                        is_permanently_blocked_and_empty = true;\n                    }\n                }\n\n                // If the target square is valid and passable for the pet, move the pet.\n                if (is_valid(next_pet_pos.r, next_pet_pos.c) && !target_is_newly_impassable && !is_permanently_blocked_and_empty) {\n                    current_pet_pos = next_pet_pos; // Pet successfully moves\n                } else {\n                    // If move is not possible, pet stays put for this move.\n                    // 'current_pet_pos' remains unchanged, and the next move in the string will be attempted from this position.\n                }\n            }\n            pets_state[i].pos = current_pet_pos; // Update pet's final position for the turn\n        }\n\n        // Update Grid State: Apply the squares that humans planned to block.\n        for (int i = 0; i < M_humans; ++i) {\n            if (planned_blocks_this_turn[i].r != -1) { // If human i planned to block a square\n                is_impassable_grid[planned_blocks_this_turn[i].r][planned_blocks_this_turn[i].c] = true;\n            }\n        }\n\n        // Update Human Positions based on their assigned move actions.\n        for (int i = 0; i < M_humans; ++i) {\n            if (human_actions_str[i] != '.' && human_actions_str[i] != 'u' && human_actions_str[i] != 'd' && human_actions_str[i] != 'l' && human_actions_str[i] != 'r') {\n                // This is a move action (uppercase char)\n                humans_state[i].pos = get_pos_from_dir_char(humans_state[i].pos, human_actions_str[i]);\n            }\n        }\n    }\n\n    // --- Scoring Calculation (for local testing/debugging, not submitted) ---\n    /*\n    double total_satisfaction = 0;\n    for (int i = 0; i < M_humans; ++i) {\n        auto [reachable_count, reachable_squares] = get_reachable_area(humans_state[i].pos, is_impassable_grid);\n        int caught_pets = 0;\n        for (const auto& pet : pets_state) {\n            for (const auto& sq : reachable_squares) {\n                if (pet.pos == sq) {\n                    caught_pets++;\n                    break;\n                }\n            }\n        }\n        double s_i = (double)reachable_count / 900.0 * pow(0.5, caught_pets);\n        total_satisfaction += s_i;\n    }\n    double final_score = round(1e8 * total_satisfaction / M_humans);\n    cerr << \"Final Score (approx): \" << fixed << setprecision(10) << final_score << endl;\n    */\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main game logic\n\n    return 0; // Program finished successfully\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Structure to store parent information for path reconstruction.\n// It records the previous grid cell (r, c), the previous step count (k),\n// and the move character that led to the current state.\nstruct ParentInfo {\n    int r, c, k; // Previous grid position and step count.\n    char move;   // The move character that was chosen to transition from (r,c,k) to the current state.\n};\n\n// Structure representing a state in the Dijkstra search.\n// It includes the expected actual time elapsed, current grid position (r, c),\n// and the number of moves (k) that have been decided/processed for the path.\nstruct State {\n    double expected_time;\n    int r, c, k; \n\n    // Custom comparator for the priority queue to implement a min-priority queue.\n    // States with lower expected_time have higher priority.\n    bool operator>(const State& other) const {\n        return expected_time > other.expected_time;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj, ti, tj; // Start and target coordinates.\n    double p;           // Probability of forgetting a move.\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // Read horizontal wall information. h_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i, j+1), 0 otherwise. Size: 20x19.\n    vector<vector<int>> h_walls(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            h_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    // Read vertical wall information. v_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i+1, j), 0 otherwise. Size: 19x20.\n    vector<vector<int>> v_walls(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            v_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    const int MAX_L = 200; // Maximum allowed length of the output string.\n    const double INF = numeric_limits<double>::max(); // Represents infinity for unreachable states.\n\n    // dist[r][c][k]: Stores the minimum expected actual time to reach grid cell (r, c)\n    // after k moves have been decided/processed for the path.\n    // k ranges from 0 to MAX_L.\n    vector<vector<vector<double>>> dist(20, vector<vector<double>>(20, vector<double>(MAX_L + 1, INF)));\n\n    // parent stores ParentInfo to reconstruct the path.\n    vector<vector<vector<ParentInfo>>> parent(20, vector<vector<ParentInfo>>(20, vector<ParentInfo>(MAX_L + 1, {-1, -1, -1, ' '})));\n\n    // Priority queue for Dijkstra's algorithm.\n    priority_queue<State, vector<State>, greater<State>> pq;\n\n    // Initial state: At home (si, sj), 0 moves processed, with an expected time of 0.0.\n    dist[si][sj][0] = 0.0;\n    pq.push({0.0, si, sj, 0});\n\n    // Define movement directions and corresponding characters for 'U', 'D', 'L', 'R'.\n    int dr[] = {-1, 1, 0, 0}; // Delta row for U, D, L, R\n    int dc[] = {0, 0, -1, 1}; // Delta column for U, D, L, R\n    char moves[] = {'U', 'D', 'L', 'R'};\n\n    // Variables to track the best path found to the office.\n    // min_expected_arrival_time stores the minimum expected time to reach the office.\n    // best_k stores the number of moves processed when the office was reached with min_expected_arrival_time.\n    double min_expected_arrival_time = INF;\n    int best_k = -1; \n\n    // Dijkstra's algorithm main loop.\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        double t = current.expected_time; // Expected time to reach this state.\n        int r = current.r;                 // Current row.\n        int c = current.c;                 // Current column.\n        int k = current.k;                 // Number of moves processed so far.\n\n        // If we found a better path to this state already, skip processing.\n        if (t > dist[r][c][k]) {\n            continue;\n        }\n\n        // Check if the current cell is the office.\n        if (r == ti && c == tj) {\n            // If we reached the office and this path is better than the best found so far, update.\n            if (t < min_expected_arrival_time) {\n                min_expected_arrival_time = t;\n                best_k = k; // Record the number of moves processed for this best path.\n            }\n            // Note: We don't 'continue' here because even if we reached the office,\n            // this state might be part of an even better path to the office IF it's reached earlier in terms of actual moves.\n            // However, since the goal is minimizing expected time, and the arrival time `t` is recorded,\n            // any further exploration from `(r,c,k)` for THIS specific path's time `t` is not useful for finding a *shorter* path to the office *via this specific branch*.\n            // But other states in PQ might offer a path with a lower expected time.\n            // The check `if (k == MAX_L)` below handles the path length limit.\n        }\n        \n        // If we have already processed MAX_L moves, we cannot extend this path further.\n        if (k == MAX_L) {\n            continue;\n        }\n\n        // Explore transitions for the next move (the (k+1)-th move in the sequence).\n        // For each of the 4 possible directions ('U', 'D', 'L', 'R'):\n        for (int i = 0; i < 4; ++i) {\n            char move_char = moves[i];\n            int nr_attempt = r, nc_attempt = c; // Initialize potential next position to current.\n\n            // Determine the target cell if the move is successful, considering grid boundaries and walls.\n            bool wall_collision = false; // True if move is blocked by boundary or wall.\n\n            if (move_char == 'U') {\n                // Check for boundary (r=0) or vertical wall v_walls[r-1][c] (between (r-1,c) and (r,c)).\n                if (r > 0 && !v_walls[r - 1][c]) { nr_attempt = r - 1; } else { wall_collision = true; }\n            } else if (move_char == 'D') {\n                // Check for boundary (r=19) or vertical wall v_walls[r][c] (between (r,c) and (r+1,c)).\n                if (r < 19 && !v_walls[r][c]) { nr_attempt = r + 1; } else { wall_collision = true; }\n            } else if (move_char == 'L') {\n                // Check for boundary (c=0) or horizontal wall h_walls[r][c-1] (between (r,c-1) and (r,c)).\n                if (c > 0 && !h_walls[r][c - 1]) { nc_attempt = c - 1; } else { wall_collision = true; }\n            } else if (move_char == 'R') {\n                // Check for boundary (c=19) or horizontal wall h_walls[r][c] (between (r,c) and (r,c+1)).\n                if (c < 19 && !h_walls[r][c]) { nc_attempt = c + 1; } else { wall_collision = true; }\n            }\n\n            // The actual time advances by 1 turn for this step, regardless of success or failure.\n            double next_expected_time = t + 1.0;\n            int next_k = k + 1; // One more move is now processed.\n\n            // Case 1: Move is forgotten (probability p).\n            // Takahashi stays at the current cell (r, c). The next state is (r, c) after k+1 moves.\n            // If the path to this state (r, c, next_k) via this route is better than previously found paths:\n            if (dist[r][c][next_k] > next_expected_time) {\n                dist[r][c][next_k] = next_expected_time;\n                // Record the parent information: we came from (r, c) at step k, and chose 'move_char'\n                // to generate this state at step k+1.\n                parent[r][c][next_k] = {r, c, k, move_char}; \n                pq.push({next_expected_time, r, c, next_k});\n            }\n\n            // Case 2: Move is executed (probability 1-p).\n            // Takahashi moves to (nr_attempt, nc_attempt). The next state is (nr_attempt, nc_attempt) after k+1 moves.\n            // If the path to this state (nr_attempt, nc_attempt, next_k) via this route is better:\n            if (dist[nr_attempt][nc_attempt][next_k] > next_expected_time) {\n                dist[nr_attempt][nc_attempt][next_k] = next_expected_time;\n                // Record parent information: came from (r, c) at step k, chose 'move_char'.\n                parent[nr_attempt][nc_attempt][next_k] = {r, c, k, move_char};\n                pq.push({next_expected_time, nr_attempt, nc_attempt, next_k});\n            }\n        }\n    }\n\n    // Path reconstruction.\n    string path = \"\";\n    if (best_k != -1) { // If the office was reached at least once within MAX_L moves.\n        int curr_r = ti;\n        int curr_c = tj;\n        int curr_k = best_k;\n\n        // Trace back from the office-reaching state to the start state (0 moves processed).\n        // The loop terminates when curr_k becomes 0.\n        while (curr_k > 0) {\n            ParentInfo p_info = parent[curr_r][curr_c][curr_k];\n            // Append the move character to the path string. This character is the (curr_k)-th move in the sequence.\n            path += p_info.move;\n            // Move to the parent state.\n            curr_r = p_info.r;\n            curr_c = p_info.c;\n            curr_k = p_info.k;\n        }\n        // The path string is built in reverse order, so reverse it.\n        reverse(path.begin(), path.end());\n    }\n    // If best_k remains -1, it means the office was not reached within MAX_L moves with a finite expected time.\n    // According to problem statement, failure leads to score 0. An empty path might be output, or a default path.\n    // However, given problem guarantees and structure, best_k should be set if office is reachable.\n    // For contest robustness, if path is empty, a simple BFS path could be a fallback, but Dijkstra should yield the optimal strategy.\n    \n    cout << path << endl; // Output the constructed commuting route.\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <random>\n#include <chrono> // For seeding the random number generator\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_DIRECTIONS = 4;\n\n// Directions: 0:Left, 1:Up, 2:Right, 3:Down\n// di[d] is the row change for direction d\n// dj[d] is the column change for direction d\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Base connections for the 8 tile types\n// base_connections[tile_type][entry_direction] = exit_direction\n// -1 means no connection\n// This table is derived from the problem statement's 'to' array.\nint base_connections[8][NUM_DIRECTIONS] = {\n    {1, 0, -1, -1}, // Type 0: L-U / U-L (Curve)\n    {3, -1, -1, 0}, // Type 1: L-D / D-L (Curve)\n    {-1, -1, 3, 2}, // Type 2: R-D / D-R (Curve)\n    {-1, 2, 1, -1}, // Type 3: R-U / U-R (Curve)\n    {1, 2, 3, 0},   // Type 4: Square path L->U->R->D->L\n    {3, 2, 1, 0},   // Type 5: S-curve like L->D, U->R, R->U, D->L (as per problem's to table)\n    {2, -1, 0, -1}, // Type 6: Horizontal L<->R (Straight)\n    {-1, 3, -1, 1}  // Type 7: Vertical U<->D (Straight)\n};\n\n// Function to map initial tile type and rotation count to effective tile type\n// The problem states how rotation changes the tile type for different groups.\nint map_type(int initial_type, int rotation) {\n    if (initial_type >= 0 && initial_type <= 3) { // Group 1: {0,1,2,3} rotate cyclically\n        return (initial_type + rotation) % 4;\n    } else if (initial_type == 4) { // Group 2a: {4,5} for initial type 4\n        // Rotation 0,2 -> type 4; Rotation 1,3 -> type 5\n        return 4 + (rotation % 2);\n    } else if (initial_type == 5) { // Group 2b: {4,5} for initial type 5\n        // Rotation 0,2 -> type 5; Rotation 1,3 -> type 4\n        return 4 + ((rotation + 1) % 2);\n    } else if (initial_type == 6) { // Group 3a: {6,7} for initial type 6\n        // Rotation 0,2 -> type 6; Rotation 1,3 -> type 7\n        return 6 + (rotation % 2);\n    } else if (initial_type == 7) { // Group 3b: {6,7} for initial type 7\n        // Rotation 0,2 -> type 7; Rotation 1,3 -> type 6\n        return 6 + ((rotation + 1) % 2);\n    }\n    return -1; // Should not happen\n}\n\n// Global variables to store the current configuration and support loop detection\nvector<vector<int>> base_type_input_grid; // Stores the initial tile type for each cell\nvector<vector<int>> current_rotations_grid; // Stores rotation count (0-3) for each cell\nvector<vector<vector<int>>> effective_to_grid; // Stores the connections for the current configuration of all cells\nvector<vector<vector<bool>>> visited_edge; // To mark edges (cell, entry_direction) that have been part of a found loop or dead end path\nvector<int> loop_lengths; // Stores lengths of all detected loop lines\n\n// Function to calculate the connections for a cell (r, c) based on its base type and current rotation\nvector<int> get_cell_connections(int r, int c) {\n    int initial_type = base_type_input_grid[r][c];\n    int rotation = current_rotations_grid[r][c];\n    int effective_type = map_type(initial_type, rotation);\n    // Return a copy of the connection rules for the effective tile type\n    return vector<int>(base_connections[effective_type], base_connections[effective_type] + NUM_DIRECTIONS);\n}\n\n// Function to find all loop lines and calculate the score (L1 * L2)\n// This function is called repeatedly by the local search heuristic.\nlong long evaluate_all_loops() {\n    // 1. Populate the effective_to_grid based on current rotations\n    effective_to_grid.assign(GRID_SIZE, vector<vector<int>>(GRID_SIZE, vector<int>(NUM_DIRECTIONS)));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            effective_to_grid[i][j] = get_cell_connections(i, j);\n        }\n    }\n\n    // 2. Find all loops using Depth First Search\n    loop_lengths.clear();\n    // visited_edge[i][j][d_in] marks if the edge entering cell (i,j) from direction d_in has been visited globally.\n    // This ensures each directed edge is explored at most once across all DFS traversals, making loop detection efficient.\n    visited_edge.assign(GRID_SIZE, vector<vector<bool>>(GRID_SIZE, vector<bool>(NUM_DIRECTIONS, false)));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            for (int d_in = 0; d_in < NUM_DIRECTIONS; ++d_in) {\n                // If this edge has not been visited yet, start a new DFS traversal\n                if (!visited_edge[i][j][d_in]) {\n                    vector<tuple<int, int, int>> current_path; // Stores the sequence of (row, col, entry_direction) visited in this DFS\n                    map<tuple<int, int, int>, int> visited_in_current_dfs; // Maps state to the step index in current_path for cycle detection\n                    \n                    int cur_i = i, cur_j = j, cur_d_in = d_in;\n                    int step = 0;\n\n                    while (true) {\n                        // Check for out of bounds\n                        if (cur_i < 0 || cur_i >= GRID_SIZE || cur_j < 0 || cur_j >= GRID_SIZE) {\n                            break; // Path broken (out of bounds)\n                        }\n\n                        auto state = make_tuple(cur_i, cur_j, cur_d_in);\n                        \n                        // Check for cycle\n                        if (visited_in_current_dfs.count(state)) {\n                            int cycle_start_step = visited_in_current_dfs[state];\n                            int loop_len = step - cycle_start_step;\n                            \n                            // Mark all edges in the found cycle as visited globally\n                            for (int k = cycle_start_step; k < current_path.size(); ++k) {\n                                auto [pi, pj, pd_in] = current_path[k];\n                                visited_edge[pi][pj][pd_in] = true;\n                            }\n                            loop_lengths.push_back(loop_len);\n                            break; // Found a loop, stop this DFS traversal\n                        }\n\n                        // Mark current state as visited in this DFS and add to path\n                        visited_in_current_dfs[state] = step;\n                        current_path.push_back(state);\n\n                        // Determine next tile and direction\n                        int d_out = effective_to_grid[cur_i][cur_j][cur_d_in];\n                        if (d_out == -1) {\n                            break; // Path broken (tile has no exit in this direction)\n                        }\n\n                        cur_i += di[d_out];\n                        cur_j += dj[d_out];\n                        cur_d_in = (d_out + 2) % 4; // The entry direction to the next tile is opposite of the exit direction from current tile\n                        step++;\n                    }\n                    \n                    // Mark all edges in the path explored by this DFS as globally visited.\n                    // This prevents re-exploring dead-end paths or segments that didn't form a cycle.\n                    for(const auto& path_state : current_path) {\n                        auto [pi, pj, pd_in] = path_state;\n                        visited_edge[pi][pj][pd_in] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 3. Calculate the score: L1 * L2\n    sort(loop_lengths.rbegin(), loop_lengths.rend()); // Sort lengths in descending order\n\n    if (loop_lengths.size() < 2) {\n        return 0; // Score is 0 if less than two loop lines are found\n    }\n    // Use long long for score to prevent overflow\n    return (long long)loop_lengths[0] * loop_lengths[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input and store base tile types\n    base_type_input_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            base_type_input_grid[i][j] = row[j] - '0';\n        }\n    }\n\n    // Initialize rotations: start with all tiles at 0 rotation.\n    // This is a common starting point for heuristic search.\n    current_rotations_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0)); \n\n    long long best_score = 0;\n    vector<vector<int>> best_rotations = current_rotations_grid;\n\n    // Calculate initial score for the all-zero rotation configuration\n    best_score = evaluate_all_loops();\n\n    // --- Randomized Iterative Improvement (Hill Climbing Variant) ---\n    // Use a Mersenne Twister engine for good random number generation.\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> cell_dist(0, GRID_SIZE - 1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n\n    // Number of iterations for the local search. This value is a heuristic tuning parameter.\n    // More iterations generally yield better results but increase computation time.\n    int num_iterations = 100000; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        // Pick a random cell (r, c) to potentially change its rotation\n        int r = cell_dist(rng);\n        int c = cell_dist(rng);\n        int original_rotation = current_rotations_grid[r][c];\n\n        // Explore all 4 possible rotations for the chosen cell (r, c).\n        // For each, evaluate the total score. Keep track of the rotation that yields the maximum score locally.\n        long long max_local_score = -1; // Initialize with a value lower than any possible score\n        int best_local_r = original_rotation; // Default to keeping the original rotation if no improvement found\n\n        for (int test_r = 0; test_r < 4; ++test_r) {\n            current_rotations_grid[r][c] = test_r; // Temporarily set this rotation\n            long long score = evaluate_all_loops(); // Evaluate the score for this configuration\n            \n            if (score > max_local_score) {\n                max_local_score = score;\n                best_local_r = test_r;\n            }\n        }\n        \n        // After trying all 4 rotations, commit the best one found for this cell (r, c).\n        // This is a greedy step: always move to a state that improves the local score.\n        current_rotations_grid[r][c] = best_local_r;\n\n        // Update the global best score and configuration if the current configuration is better\n        if (max_local_score > best_score) {\n            best_score = max_local_score;\n            best_rotations = current_rotations_grid; // Save the rotations that achieved this best score\n        }\n    }\n\n    // Output the resulting rotations as a single string of 900 digits.\n    string result_string = \"\";\n    result_string.reserve(GRID_SIZE * GRID_SIZE); // Reserve space for efficiency\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            result_string += to_string(best_rotations[i][j]);\n        }\n    }\n    cout << result_string << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional> // for std::greater\n\nusing namespace std;\n\nint N;\nint T_limit;\nvector<vector<int>> initial_board_grid;\npair<int, int> initial_empty_pos;\n\n// Target configuration: canonical grid graph with empty at (N-1, N-1)\nvector<vector<int>> canonical_board_grid;\n\n// For state representation and visited set\nusing Board = vector<vector<int>>;\nusing StateKey = vector<int>; // Flattened board\n\n// Stores minimum cost (number of moves) and the path to reach a board state.\n// Key: flattened board configuration.\nmap<StateKey, pair<int, string>> visited;\n\n// Movement directions: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\nchar move_chars[] = {'U', 'D', 'L', 'R'};\n\n// --- Heuristic function ---\n// Calculates the Manhattan distance of the empty square from the target position (N-1, N-1).\n// This is an admissible heuristic for sliding tile puzzles.\nint calculate_heuristic(int r, int c) {\n    return abs(r - (N - 1)) + abs(c - (N - 1));\n}\n\n// --- Board to StateKey conversion ---\n// Converts the 2D board representation to a 1D vector for use as a map key.\nStateKey board_to_key(const Board& board) {\n    StateKey key;\n    key.reserve(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            key.push_back(board[r][c]);\n        }\n    }\n    return key;\n}\n\n// --- Custom State struct for Priority Queue ---\n// Represents a state in the search: current board, empty square position, cost (moves), and path.\nstruct SearchState {\n    Board board;\n    int empty_r, empty_c;\n    int cost; // g_cost: number of moves from initial state\n    string path;\n\n    // Operator overload for priority_queue to prioritize states with lower f_cost (g_cost + h_cost).\n    // If f_costs are equal, prioritize states with lower actual cost (g_cost).\n    bool operator>(const SearchState& other) const {\n        int h_self = calculate_heuristic(empty_r, empty_c);\n        int h_other = calculate_heuristic(other.empty_r, other.empty_c);\n        \n        // Primary sort by f_cost (g + h)\n        if ((cost + h_self) != (other.cost + h_other)) {\n            return (cost + h_self) > (other.cost + h_other);\n        }\n        // Secondary sort by actual cost (g) to favor shorter paths when heuristics are equal\n        return cost > other.cost; \n    }\n};\n\nvoid solve() {\n    // 1. Construct the canonical target board configuration.\n    // This configuration aims to form a grid graph spanning tree with the empty square at (N-1, N-1).\n    // Each tile (r, c) (not the empty square) is assigned bits representing lines needed\n    // to connect to its neighbors in the grid, excluding any connection to the empty square.\n    canonical_board_grid.assign(N, vector<int>(N));\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (r == N - 1 && c == N - 1) {\n                canonical_board_grid[r][c] = 0; // The empty square\n            } else {\n                int val = 0;\n                // Tile at (r, c) needs a RIGHT line (bit 4) if neighbor (r, c+1) exists and is not empty.\n                if (c < N - 1) val |= 4; \n                // Tile at (r, c) needs a LEFT line (bit 1) if neighbor (r, c-1) exists.\n                if (c > 0) val |= 1;     \n                // Tile at (r, c) needs a DOWN line (bit 8) if neighbor (r+1, c) exists and is not empty.\n                if (r < N - 1) val |= 8; \n                // Tile at (r, c) needs an UP line (bit 2) if neighbor (r-1, c) exists.\n                if (r > 0) val |= 2;     \n                canonical_board_grid[r][c] = val;\n            }\n        }\n    }\n\n    // 2. Initialize A* search.\n    priority_queue<SearchState, vector<SearchState>, greater<SearchState>> pq;\n    visited.clear();\n\n    StateKey initial_key = board_to_key(initial_board_grid);\n    SearchState initial_state = {initial_board_grid, initial_empty_pos.first, initial_empty_pos.second, 0, \"\"};\n    \n    // Check if the initial state is already the target state.\n    bool is_initial_target = true;\n    if (initial_state.empty_r != N - 1 || initial_state.empty_c != N - 1) {\n        is_initial_target = false;\n    } else {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r == N - 1 && c == N - 1) continue; // Skip the empty square itself\n                if (initial_state.board[r][c] != canonical_board_grid[r][c]) {\n                    is_initial_target = false;\n                    break;\n                }\n            }\n            if (!is_initial_target) break;\n        }\n    }\n\n    if (is_initial_target) {\n        cout << \"\" << endl; // Zero moves needed if already in target state.\n        return;\n    }\n\n    visited[initial_key] = {0, \"\"};\n    pq.push(initial_state);\n\n    // Limit the number of states explored to prevent Time Limit Exceeded.\n    // This limit is heuristic and may need tuning. It's adjusted based on N.\n    int max_states_to_explore = 2500000; // Default value\n    if (N >= 8) max_states_to_explore = 1800000; \n    if (N == 10) max_states_to_explore = 1200000; \n\n    int states_explored = 0;\n\n    // A* search loop.\n    while (!pq.empty() && states_explored < max_states_to_explore) {\n        SearchState current = pq.top();\n        pq.pop();\n\n        states_explored++;\n\n        StateKey current_key = board_to_key(current.board);\n        \n        // If we've found a shorter path to this state already, skip.\n        if (visited.count(current_key) && visited[current_key].first < current.cost) {\n            continue;\n        }\n\n        // Check if the current state is the target state.\n        bool is_target = true;\n        if (current.empty_r != N - 1 || current.empty_c != N - 1) {\n            is_target = false;\n        } else {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (r == N - 1 && c == N - 1) continue; // Skip the empty square\n                    if (current.board[r][c] != canonical_board_grid[r][c]) {\n                        is_target = false;\n                        break;\n                    }\n                }\n                if (!is_target) break;\n            }\n        }\n\n        // If target is reached, print the path and terminate.\n        if (is_target) {\n            cout << current.path << endl;\n            return; \n        }\n        \n        // Explore neighboring states by moving the empty square.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current.empty_r + dr[i];\n            int nc = current.empty_c + dc[i];\n\n            // Check if the potential new position for the empty square is within board bounds.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                Board next_board = current.board; // Create a copy of the current board.\n                // Perform the move: swap the empty square with the adjacent tile.\n                swap(next_board[current.empty_r][current.empty_c], next_board[nr][nc]);\n\n                StateKey next_key = board_to_key(next_board);\n                int next_cost = current.cost + 1;\n\n                // If this state hasn't been visited, or if we found a shorter path to it:\n                if (!visited.count(next_key) || next_cost < visited[next_key].first) {\n                    // Record the new state with its cost and path.\n                    visited[next_key] = {next_cost, current.path + move_chars[i]};\n                    // Add the new state to the priority queue for exploration.\n                    pq.push({next_board, nr, nc, next_cost, current.path + move_chars[i]});\n                }\n            }\n        }\n    }\n    \n    // According to the problem statement, a solution that forms a tree of size N^2-1\n    // is guaranteed to exist within T operations. If the search loop finishes\n    // without finding the target state, it implies that the search limits (e.g.,\n    // max_states_to_explore) were too strict, the heuristic was insufficient,\n    // or the state space exploration was too slow for the given time limit.\n    // In a competitive programming context, if this part is reached, it typically\n    // indicates a need for optimization, a better heuristic, or a different algorithm.\n    // For this problem, we assume the target state is reachable and will be found.\n    // If not found, the program would exit without outputting a path, which would be WA/TLE.\n}\n\n// Helper function to convert hexadecimal character to integer tile value.\nint char_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input: N (board size) and T (move limit).\n    cin >> N >> T_limit;\n\n    // Read the initial board configuration.\n    initial_board_grid.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            initial_board_grid[i][j] = char_to_int(row[j]);\n            // Store the position of the empty square (tile value 0).\n            if (initial_board_grid[i][j] == 0) {\n                initial_empty_pos = {i, j};\n            }\n        }\n    }\n\n    // Solve the puzzle using A* search.\n    solve();\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <iomanip>\n\nusing namespace std;\n\n// Use the maximum allowed coordinate value for defining line endpoints.\n// The problem statement allows coordinates up to 10^9.\nconst long long INF_COORD = 1e9; \n\nstruct Strawberry {\n    long long x, y;\n    int id;\n};\n\nstruct Line {\n    long long px, py, qx, qy;\n};\n\n// Helper function to select 'count' unique integer coordinates for lines.\n// This version attempts to select coordinates in a more structured way,\n// prioritizing spread and avoiding strawberry locations.\nvector<long long> select_line_coords(int count, const set<long long>& occupied_coords) {\n    vector<long long> selected_coords;\n    set<long long> current_selection;\n\n    // Define a search range slightly larger than the typical strawberry coordinate range.\n    // Strawberry coordinates |x|, |y| < 10000. We use [-15000, 15000] as the primary range.\n    long long search_range_start = -15000;\n    long long search_range_end = 15000;\n    \n    // Calculate an approximate step size for even distribution.\n    // We aim for 'count' points, which create 'count + 1' effective intervals.\n    double step = static_cast<double>(search_range_end - search_range_start) / (count + 1);\n\n    // Try to pick points approximately evenly spaced within the search range.\n    for (int i = 0; i < count; ++i) {\n        // Calculate a target coordinate. Add 0.5 to step to center it within its interval.\n        long long target_coord = static_cast<long long>(search_range_start + (i + 0.5) * step);\n        \n        // Ensure target_coord is within the search range.\n        target_coord = max(search_range_start, min(search_range_end, target_coord));\n\n        // Search outwards from the target_coord to find the nearest available integer coordinate.\n        long long current_offset = 0;\n        bool found = false;\n        while (current_offset <= 30000) { // Limit search to prevent infinite loops (unlikely with large ranges)\n            vector<long long> candidates;\n            candidates.push_back(target_coord + current_offset);\n            if (current_offset > 0) {\n                candidates.push_back(target_coord - current_offset);\n            }\n\n            for(long long cand : candidates) {\n                // Clamp candidate to the search range.\n                cand = max(search_range_start, min(search_range_end, cand));\n\n                // Check if this candidate is not occupied by a strawberry and not already selected.\n                if (occupied_coords.find(cand) == occupied_coords.end() && current_selection.find(cand) == current_selection.end()) {\n                    selected_coords.push_back(cand);\n                    current_selection.insert(cand);\n                    found = true;\n                    goto next_coord; // Found a suitable coordinate, move to the next 'i'.\n                }\n            }\n            current_offset++;\n        }\n        \n        // If the search outwards failed to find a coordinate within the limit,\n        // and we still need more coordinates, fall back to a linear scan within the range.\n        if (!found && selected_coords.size() < count) {\n             for (long long val = search_range_start; val <= search_range_end && selected_coords.size() < count; ++val) {\n                if (occupied_coords.find(val) == occupied_coords.end() && current_selection.find(val) == current_selection.end()) {\n                    selected_coords.push_back(val);\n                    current_selection.insert(val);\n                    goto next_coord;\n                }\n            }\n        }\n        next_coord:; // Label for goto\n    }\n    \n    // Fallback: If the structured search didn't yield enough unique coordinates,\n    // use the previous strategy's broader ranges.\n    if (selected_coords.size() < count) {\n        // Try values far from origin first.\n        for (long long val = -20000; val <= -10001 && selected_coords.size() < count; ++val) {\n            if (occupied_coords.find(val) == occupied_coords.end() && current_selection.find(val) == current_selection.end()) {\n                selected_coords.push_back(val);\n                current_selection.insert(val);\n            }\n        }\n        for (long long val = 10001; val <= 20000 && selected_coords.size() < count; ++val) {\n            if (occupied_coords.find(val) == occupied_coords.end() && current_selection.find(val) == current_selection.end()) {\n                selected_coords.push_back(val);\n                current_selection.insert(val);\n            }\n        }\n        // Then try values within the typical strawberry coordinate range.\n        for (long long val = -10000; val <= 10000 && selected_coords.size() < count; ++val) {\n            if (occupied_coords.find(val) == occupied_coords.end() && current_selection.find(val) == current_selection.end()) {\n                selected_coords.push_back(val);\n                current_selection.insert(val);\n            }\n        }\n    }\n\n    return selected_coords;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    int k; // Maximum number of cuts\n    cin >> n >> k;\n\n    vector<int> a(11); // a[d] is the number of attendees for d years\n    for (int d = 1; d <= 10; ++d) {\n        cin >> a[d];\n    }\n\n    vector<Strawberry> strawberries(n);\n    set<long long> sx_set, sy_set; // Sets to store unique strawberry x and y coordinates for efficient lookup.\n    for (int i = 0; i < n; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        sx_set.insert(strawberries[i].x);\n        sy_set.insert(strawberries[i].y);\n    }\n\n    // Strategy: Divide the K cuts into vertical and horizontal lines.\n    // A balanced split (k/2 vertical, k-k/2 horizontal) creates a grid of regions.\n    int num_v_lines = k / 2;\n    int num_h_lines = k - num_v_lines;\n\n    // Select coordinates for the vertical and horizontal lines using the improved strategy.\n    vector<long long> v_line_values = select_line_coords(num_v_lines, sx_set);\n    vector<long long> h_line_values = select_line_coords(num_h_lines, sy_set);\n\n    // Sort line coordinates to define intervals correctly.\n    sort(v_line_values.begin(), v_line_values.end());\n    sort(h_line_values.begin(), h_line_values.end());\n\n    // Define interval boundaries for regions.\n    // These boundaries are the selected line coordinates plus sentinels far outside the strawberry range.\n    // Strawberry coordinates satisfy |x|, |y| < 10000. Using +/- 20000 ensures they act as effective infinities for interval partitioning.\n    vector<long long> x_intervals = {-20000LL}; // Lower sentinel\n    x_intervals.insert(x_intervals.end(), v_line_values.begin(), v_line_values.end());\n    x_intervals.push_back(20000LL); // Upper sentinel\n    // Ensure boundaries are sorted and unique.\n    sort(x_intervals.begin(), x_intervals.end());\n    x_intervals.erase(unique(x_intervals.begin(), x_intervals.end()), x_intervals.end());\n\n    vector<long long> y_intervals = {-20000LL}; // Lower sentinel\n    y_intervals.insert(y_intervals.end(), h_line_values.begin(), h_line_values.end());\n    y_intervals.push_back(20000LL); // Upper sentinel\n    sort(y_intervals.begin(), y_intervals.end());\n    y_intervals.erase(unique(y_intervals.begin(), y_intervals.end()), y_intervals.end());\n\n    // Group regions by the number of strawberries they contain.\n    // `regions_by_count[d]` will store a list of `region_flat_idx` for regions containing exactly `d` strawberries.\n    map<int, vector<int>> regions_by_count;\n    \n    int region_flat_idx_counter = 0; // A unique ID for each distinct rectangular region created by the grid.\n\n    // Iterate through all created rectangular regions defined by the intervals.\n    for (size_t j = 0; j < x_intervals.size() - 1; ++j) {\n        for (size_t l = 0; l < y_intervals.size() - 1; ++l) {\n            long long min_x = x_intervals[j];\n            long long max_x = x_intervals[j+1];\n            long long min_y = y_intervals[l];\n            long long max_y = y_intervals[l+1];\n\n            // Count strawberries strictly within this open rectangular region (piece).\n            // The problem states strawberries on cut lines belong to no pieces, hence the strict inequalities.\n            int count = 0;\n            for (const auto& straw : strawberries) {\n                if (straw.x > min_x && straw.x < max_x &&\n                    straw.y > min_y && straw.y < max_y) {\n                    count++;\n                }\n            }\n            \n            // If a region contains strawberries, record it by its strawberry count and a unique index.\n            if (count > 0) {\n                regions_by_count[count].push_back(region_flat_idx_counter);\n                region_flat_idx_counter++;\n            }\n        }\n    }\n    \n    // Assignment phase: Greedily assign available regions to satisfy attendee demands.\n    // Iterate through demands for $d=1$ to $10$. For each demand $a_d$, try to find\n    // an unused region with exactly $d$ strawberries.\n    \n    set<int> used_region_flat_indices; // Set to keep track of which regions have already been assigned to avoid double counting.\n\n    // Iterate through each strawberry count demand (d from 1 to 10).\n    for (int d = 1; d <= 10; ++d) {\n        if (a[d] > 0) { // Only proceed if there's a demand for 'd' strawberries.\n            // Check if we have any regions that contain exactly 'd' strawberries.\n            if (regions_by_count.count(d)) {\n                // Get the list of regions containing 'd' strawberries.\n                const vector<int>& available_regions_for_d = regions_by_count.at(d); \n                \n                int assigned_for_this_d = 0; // Counter for pieces of size 'd' assigned for current demand 'a[d]'.\n                \n                // Iterate through all regions that are known to contain exactly 'd' strawberries.\n                for (int region_flat_idx : available_regions_for_d) {\n                    // Check if this specific region has already been assigned.\n                    if (used_region_flat_indices.find(region_flat_idx) == used_region_flat_indices.end()) {\n                        // This region is available. Assign it to satisfy one demand for 'd' strawberries.\n                        used_region_flat_indices.insert(region_flat_idx); // Mark this region as used.\n                        // Increment count for pieces of size 'd' that successfully meet a demand.\n                        assigned_for_this_d++;\n                        \n                        // If we have satisfied all $a_d$ demands for this count 'd', stop looking for this 'd'.\n                        if (assigned_for_this_d == a[d]) {\n                            break; \n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Prepare the output cuts.\n    vector<Line> cuts;\n    // For each selected vertical line coordinate `val`, create a line segment that spans across the entire plane.\n    // Use INF_COORD for endpoints to ensure it cuts the cake and stays within coordinate limits.\n    for (long long val : v_line_values) {\n        cuts.push_back({val, -INF_COORD, val, INF_COORD});\n    }\n    // For each selected horizontal line coordinate `val`, create a line segment that spans across the entire plane.\n    // Use INF_COORD for endpoints.\n    for (long long val : h_line_values) {\n        cuts.push_back({-INF_COORD, val, INF_COORD, val});\n    }\n\n    // Output the total number of cuts and the coordinates defining each cut line.\n    cout << cuts.size() << endl;\n    for (const auto& line : cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <set>\n#include <algorithm>\n#include <map>\n#include <tuple>\n\nusing namespace std;\n\n// Maximum number of operations to perform.\n// A limit is needed to prevent infinite loops and control execution time.\nconst int MAX_OPS = 5000; \n\n// Structure to represent a grid point.\nstruct Point {\n    int x, y;\n\n    // For use in std::set and std::map.\n    // Lexicographical comparison.\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n\n    // For equality checks.\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Global variables for grid dimensions, center, and total weight.\nlong long N_val; // Grid size (N x N). Renamed from N to avoid conflict.\nPoint center; // Center of the grid for weight calculation.\nlong long total_weight_sum_val; // Sum of weights of all points with dots. Renamed to avoid conflict.\n\n// Data structures for storing drawn segments to check for overlaps.\n// For axis-aligned segments:\n// h_segments_by_y[y] stores a set of pairs {min_x, max_x} for horizontal segments on line y.\n// v_segments_by_x[x] stores a set of pairs {min_y, max_y} for vertical segments on line x.\nmap<int, set<pair<int, int>>> h_segments_by_y;\nmap<int, set<pair<int, int>>> v_segments_by_x;\n\n// For 45-degree segments, we use transformed coordinates:\n// u = x + y\n// v = x - y\n// A segment with dx=dy becomes horizontal in (u,v) space (v is constant).\n//   Stored in uv_v_segments_by_v: key is the constant v, value is the range of u {min_u, max_u}.\n// A segment with dx=-dy becomes vertical in (u,v) space (u is constant).\n//   Stored in uv_h_segments_by_u: key is the constant u, value is the range of v {min_v, max_v}.\nmap<int, set<pair<int, int>>> uv_h_segments_by_u; // Stores vertical segments in (u,v) plane\nmap<int, set<pair<int, int>>> uv_v_segments_by_v; // Stores horizontal segments in (u,v) plane\n\n// Calculates the weight of a grid point based on its distance from the center.\nlong long weight(Point p) {\n    long long dx = p.x - center.x;\n    long long dy = p.y - center.y;\n    return dx * dx + dy * dy + 1;\n}\n\n// Adds a new segment (defined by two points) to the appropriate segment tracking maps.\nvoid add_segment(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        v_segments_by_x[p1.x].insert({min_y, max_y});\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        h_segments_by_y[p1.y].insert({min_x, max_x});\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // For 45-degree segments, |dx| must equal |dy|.\n        // This check is defensive; it should not be necessary if rectangle shape is correctly validated.\n        if (abs(dx) != abs(dy)) {\n             return; \n        }\n\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n\n        if (dx == dy) { // Segment is horizontal in (u,v) space (v is constant).\n            int v_const = v1; // v1 == v2 for dx=dy.\n            // Store in uv_v_segments_by_v, keyed by the constant v. Range is of u.\n            uv_v_segments_by_v[v_const].insert({min(u1, u2), max(u1, u2)});\n        } else { // dx == -dy. Segment is vertical in (u,v) space (u is constant).\n            int u_const = u1; // u1 == u2 for dx=-dy.\n            // Store in uv_h_segments_by_u, keyed by the constant u. Range is of v.\n            uv_h_segments_by_u[u_const].insert({min(v1, v2), max(v1, v2)});\n        }\n    }\n}\n\n// Checks if a new segment defined by p1 and p2 overlaps with any previously drawn segment.\nbool check_segment_overlap(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        \n        auto it_map = v_segments_by_x.find(p1.x); // Look for segments on the same vertical line.\n        if (it_map != v_segments_by_x.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_y, max_y}.\n            \n            // Efficiently find potentially overlapping segments.\n            // Find the first segment whose max_y is greater than or equal to our min_y.\n            // A segment [seg_min_y, seg_max_y] overlaps with [min_y, max_y] if seg_max_y >= min_y AND seg_min_y <= max_y.\n            // We search for segments whose 'first' element (seg_min_y) is <= max_y.\n            // `upper_bound({max_y, -1})` finds the first element strictly greater than {max_y, -1}.\n            // Decrementing it gives the first element that might overlap (its start is <= max_y).\n            auto it = segments.upper_bound({max_y, -1}); \n            if (it != segments.begin()) {\n                --it; // Move to the first segment that could overlap.\n                do {\n                    // Check for overlap: existing segment [it->first, it->second] vs new segment [min_y, max_y].\n                    if (it->second >= min_y && it->first <= max_y) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break; // Stop if we reached the beginning.\n                    --it; // Move to the next potential overlapping segment.\n                } while (it->first >= min_y); // Optimization: If an existing segment starts before our new segment, further preceding segments cannot overlap.\n            }\n        }\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        \n        auto it_map = h_segments_by_y.find(p1.y); // Look for segments on the same horizontal line.\n        if (it_map != h_segments_by_y.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_x, max_x}.\n            \n            auto it = segments.upper_bound({max_x, -1});\n            if (it != segments.begin()) {\n                --it;\n                do {\n                    // Existing segment [it->first, it->second] vs new segment [min_x, max_x].\n                    if (it->second >= min_x && it->first <= max_x) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_x);\n            }\n        }\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // This branch is for 45-degree segments, where |dx| == |dy|.\n        if (abs(dx) != abs(dy)) return false; // Should not happen if shape is valid.\n\n        // Calculate transformed coordinates for the new segment.\n        int u1_new = p1.x + p1.y;\n        int v1_new = p1.x - p1.y;\n        int u2_new = p2.x + p2.y;\n        int v2_new = p2.x - p2.y;\n\n        if (dx == dy) { // New segment is horizontal in (u,v) space (v is constant).\n            int v_const_new = v1_new; // v1_new == v2_new.\n            int min_u_new = min(u1_new, u2_new);\n            int max_u_new = max(u1_new, u2_new);\n\n            auto it_map = uv_v_segments_by_v.find(v_const_new); // Map stores horizontal segments in (u,v).\n            if (it_map != uv_v_segments_by_v.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_u, max_u}.\n                \n                auto it = segments.upper_bound({max_u_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_u_new, max_u_new].\n                        if (it->second >= min_u_new && it->first <= max_u_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_u_new);\n                }\n            }\n        } else { // dx == -dy. New segment is vertical in (u,v) space (u is constant).\n            int u_const_new = u1_new; // u1_new == u2_new.\n            int min_v_new = min(v1_new, v2_new);\n            int max_v_new = max(v1_new, v2_new);\n\n            auto it_map = uv_h_segments_by_u.find(u_const_new); // Map stores vertical segments in (u,v).\n            if (it_map != uv_h_segments_by_u.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_v, max_v}.\n                \n                auto it = segments.upper_bound({max_v_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_v_new, max_v_new].\n                        if (it->second >= min_v_new && it->first <= max_v_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_v_new);\n                }\n            }\n        }\n    }\n    return false; // No overlap found.\n}\n\n\n// Checks if a point 'test_p' lies strictly on the line segment defined by 'seg_p1' and 'seg_p2',\n// excluding the endpoints.\nbool is_point_on_segment_exclusive(Point test_p, Point seg_p1, Point seg_p2) {\n    if (seg_p1 == seg_p2) return false; // Degenerate segment.\n\n    // Check collinearity using the cross product.\n    // (test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) == (test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y)\n    long long cross_product = (long long)(test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) - (long long)(test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y);\n    if (cross_product != 0) return false; // Not collinear.\n\n    // Check if the point lies within the bounding box of the segment.\n    bool on_x = (test_p.x >= min(seg_p1.x, seg_p2.x) && test_p.x <= max(seg_p1.x, seg_p2.x));\n    bool on_y = (test_p.y >= min(seg_p1.y, seg_p2.y) && test_p.y <= max(seg_p1.y, seg_p2.y));\n\n    if (!on_x || !on_y) return false; // Collinear but outside the segment's bounds.\n\n    // Point is collinear and within the bounding box. Now check if it's strictly between the endpoints.\n    // It's strictly between if it's not equal to either endpoint.\n    bool is_endpoint1 = (test_p.x == seg_p1.x && test_p.y == seg_p1.y);\n    bool is_endpoint2 = (test_p.x == seg_p2.x && test_p.y == seg_p2.y);\n    \n    return !(is_endpoint1 || is_endpoint2);\n}\n\n// Checks Condition 2: No dots (other than the rectangle's corners) lie on the perimeter of the proposed rectangle.\n// p1_new is the point where the new dot will be placed.\n// p2_old, p3_old, p4_old are the three existing points that form the rectangle with p1_new.\nbool check_perimeter_dots(Point p1_new, Point p2_old, Point p3_old, Point p4_old, const set<Point>& current_dots) {\n    // Define the four segments of the rectangle.\n    Point segments[4][2] = {{p1_new, p2_old}, {p2_old, p3_old}, {p3_old, p4_old}, {p4_old, p1_new}};\n    \n    // The dots that are allowed to be on the perimeter are the existing corners of the rectangle.\n    set<Point> allowed_on_perimeter = {p2_old, p3_old, p4_old};\n\n    for (auto& seg : segments) {\n        Point seg_p1 = seg[0];\n        Point seg_p2 = seg[1];\n\n        if (seg_p1 == seg_p2) continue; // Skip degenerate segments.\n\n        // Iterate through all currently placed dots.\n        for (const auto& dot : current_dots) {\n            // If the dot is one of the allowed corners, it's fine.\n            if (allowed_on_perimeter.count(dot)) continue;\n            \n            // Check if this dot lies strictly on the current segment.\n            if (is_point_on_segment_exclusive(dot, seg_p1, seg_p2)) {\n                return false; // Found a forbidden dot on the perimeter.\n            }\n        }\n    }\n    return true; // No forbidden dots found on any segment.\n}\n\n// Checks if four points (p1, p2, p3, p4) in order form a valid rectangle.\n// p1 is the potential new dot, and p2, p3, p4 are existing dots.\nbool check_rectangle_shape_and_order(Point p1, Point p2, Point p3, Point p4) {\n    // Calculate vectors for each side.\n    long long dx1 = p2.x - p1.x; // Vector p1->p2\n    long long dy1 = p2.y - p1.y;\n    long long dx2 = p3.x - p2.x; // Vector p2->p3\n    long long dy2 = p3.y - p2.y;\n    long long dx3 = p4.x - p3.x; // Vector p3->p4\n    long long dy3 = p4.y - p3.y;\n    long long dx4 = p1.x - p4.x; // Vector p4->p1\n    long long dy4 = p1.y - p4.y;\n\n    // A rectangle is a parallelogram with perpendicular adjacent sides.\n    // Check if opposite sides are parallel and equal in length:\n    // Vector p1->p2 should be the negation of p3->p4 (or p4->p3).\n    bool side1_matches_side3 = (dx1 == -dx3) && (dy1 == -dy3);\n    // Vector p2->p3 should be the negation of p4->p1 (or p1->p4).\n    bool side2_matches_side4 = (dx2 == -dx4) && (dy2 == -dy4);\n\n    if (!side1_matches_side3 || !side2_matches_side4) {\n        return false; // Not a parallelogram.\n    }\n    \n    // Check if adjacent sides are perpendicular using the dot product.\n    // Dot product of vector p1->p2 and vector p2->p3 must be zero.\n    long long dot_product_12_23 = dx1 * dx2 + dy1 * dy2;\n    \n    if (dot_product_12_23 != 0) {\n        return false; // Adjacent sides are not perpendicular.\n    }\n\n    // All conditions met: it's a rectangle.\n    return true;\n}\n\n// Structure to represent a candidate move (placing a new dot).\nstruct CandidateMove {\n    Point p1_new; // The new dot's coordinates.\n    Point p2_old, p3_old, p4_old; // The three existing dots used to form the rectangle.\n    long long weight_val; // The weight of the new dot (p1_new).\n\n    // For sorting candidates: we want the move that adds the point with the highest weight.\n    bool operator<(const CandidateMove& other) const {\n        return weight_val < other.weight_val; // Ascending for std::sort, so we sort reversed later.\n    }\n};\n\n// Finds all possible valid moves (rectangles that can be drawn).\nvector<CandidateMove> find_candidate_moves(const set<Point>& current_dots) {\n    vector<CandidateMove> candidates;\n    // Convert the set of dots to a vector for easier iteration.\n    vector<Point> dots_vec(current_dots.begin(), current_dots.end());\n\n    // Strategy: Iterate through pairs of existing dots (pa, pb) and check if they can be part of a rectangle.\n\n    // --- Generate Axis-Aligned Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point pa = dots_vec[i];\n            Point pb = dots_vec[j];\n\n            // Case 1: pa and pb share the same y-coordinate (form a horizontal segment).\n            if (pa.y == pb.y) {\n                int y_base = pa.y;\n                int x1 = min(pa.x, pb.x);\n                int x2 = max(pa.x, pb.x);\n                \n                // Search for points on parallel lines y_new = y_base + dy and y_new = y_base - dy.\n                // We search symmetrically outwards from the base segment.\n                for (int dy = 1; ; ++dy) {\n                    // If both upward and downward searches go out of bounds, stop.\n                    if (y_base + dy >= N_val && y_base - dy < 0) break; \n\n                    bool found_upper = false;\n                    Point pc_upper = {-1, -1}, pd_upper = {-1, -1}; // Placeholder for potential points.\n                    // Check for points on the line y_base + dy.\n                    if (y_base + dy < N_val) {\n                        pc_upper = {x1, y_base + dy};\n                        pd_upper = {x2, y_base + dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_upper) && current_dots.count(pd_upper)) {\n                            found_upper = true;\n                        }\n                    }\n\n                    bool found_lower = false;\n                    Point pc_lower = {-1, -1}, pd_lower = {-1, -1};\n                    // Check for points on the line y_base - dy.\n                    if (y_base - dy >= 0) {\n                        pc_lower = {x1, y_base - dy};\n                        pd_lower = {x2, y_base - dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_lower) && current_dots.count(pd_lower)) {\n                            found_lower = true;\n                        }\n                    }\n\n                    // If no points were found in either direction at this distance 'dy',\n                    // and 'dy' has exceeded a reasonable limit (e.g., grid size), stop searching in this direction.\n                    if (!found_upper && !found_lower) {\n                        if (dy > N_val) break; // Heuristic limit to prevent excessive search.\n                        continue; // Continue to the next 'dy' if not out of bounds.\n                    }\n                    \n                    // If we found two points on the upper line (pc_upper, pd_upper):\n                    if (found_upper) {\n                        // Potential rectangle vertices are: (x1, y_base), (x2, y_base), pc_upper, pd_upper.\n                        // We need to find a NEW dot (p_new) and three OLD dots (p2_old, p3_old, p4_old).\n                        // If pc_upper is empty, it can be p_new. The existing dots are pd_upper, pa, pb.\n                        Point p_new = pc_upper;\n                        if (!current_dots.count(p_new)) {\n                            // Try forming the rectangle with p_new and the three existing dots.\n                            // The existing dots for this case are pd_upper, pa, pb.\n                            // Vertices are (x1, y_base), (x2, y_base), (x2, y_base+dy), (x1, y_base+dy).\n                            // Possible pairings for (p2_old, p3_old, p4_old) to form a rectangle with p_new=(x1, y_base+dy):\n                            // 1. (p_new, (x1, y_base), (x2, y_base), (x2, y_base+dy))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_upper)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_upper, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // 2. (p_new, pd_upper, pb, pa) - this order tries to form a rectangle (x1,y_up), (x2,y_up), (x2,y_base), (x1,y_base)\n                            if (current_dots.count(pd_upper) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_upper, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_upper, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_upper, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_upper is empty, it can be p_new. Existing dots: pc_upper, pa, pb.\n                        p_new = pd_upper;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_upper, pa, pb) -> ((x2, y_base+dy), (x1, y_base+dy), (x1, y_base), (x2, y_base))\n                            if (current_dots.count(pc_upper) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_upper, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_upper, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_upper, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pb, pa, pc_upper) -> ((x2, y_base+dy), (x2, y_base), (x1, y_base), (x1, y_base+dy))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_upper)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_upper, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    // If both upper and lower lines had pairs of points, we don't need to search further for this pa, pb pair in 'dy' direction.\n                    if (found_upper && found_lower) break; \n                    // If neither direction yielded points, further 'dy' won't find them either.\n                    if (!found_upper && !found_lower) break;\n                }\n            }\n\n            // Case 2: pa and pb share the same x-coordinate (form a vertical segment).\n            if (pa.x == pb.x) {\n                int x_base = pa.x;\n                int y1 = min(pa.y, pb.y);\n                int y2 = max(pa.y, pb.y);\n\n                // Search for points on parallel lines x_new = x_base + dx and x_new = x_base - dx.\n                for (int dx = 1; ; ++dx) {\n                    if (x_base + dx >= N_val && x_base - dx < 0) break;\n\n                    bool found_right = false;\n                    Point pc_right = {-1, -1}, pd_right = {-1, -1};\n                    // Check for points on the line x_base + dx.\n                    if (x_base + dx < N_val) {\n                        pc_right = {x_base + dx, y1};\n                        pd_right = {x_base + dx, y2};\n                        if (current_dots.count(pc_right) && current_dots.count(pd_right)) {\n                            found_right = true;\n                        }\n                    }\n\n                    bool found_left = false;\n                    Point pc_left = {-1, -1}, pd_left = {-1, -1};\n                    // Check for points on the line x_base - dx.\n                    if (x_base - dx >= 0) {\n                        pc_left = {x_base - dx, y1};\n                        pd_left = {x_base - dx, y2};\n                        if (current_dots.count(pc_left) && current_dots.count(pd_left)) {\n                            found_left = true;\n                        }\n                    }\n\n                    if (!found_right && !found_left) {\n                        if (dx > N_val) break;\n                        continue;\n                    }\n\n                    // If we found two points on the right line (pc_right, pd_right):\n                    if (found_right) {\n                        // Potential rectangle vertices: (x_base, y1), (x_base, y2), pc_right, pd_right.\n                        // Try placing new dot at pc_right. Existing dots are pd_right, pa, pb.\n                        Point p_new = pc_right;\n                        if (!current_dots.count(p_new)) {\n                            // Try (p_new, pa, pb, pd_right) -> ((x_base+dx, y1), (x_base, y1), (x_base, y2), (x_base+dx, y2))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_right)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_right) &&\n                                        !check_segment_overlap(pd_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_right, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pd_right, pb, pa) -> ((x_base+dx, y1), (x_base+dx, y2), (x_base, y2), (x_base, y1))\n                             if (current_dots.count(pd_right) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_right, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_right) &&\n                                        !check_segment_overlap(pd_right, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_right, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_right, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_right is empty, it can be p_new. Existing dots: pc_right, pa, pb.\n                        p_new = pd_right;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_right, pa, pb) -> ((x_base+dx, y2), (x_base+dx, y1), (x_base, y1), (x_base, y2))\n                            if (current_dots.count(pc_right) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_right, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_right) &&\n                                        !check_segment_overlap(pc_right, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_right, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_right, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                             // Try (p_new, pb, pa, pc_right) -> ((x_base+dx, y2), (x_base, y2), (x_base, y1), (x_base+dx, y1))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_right)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_right) &&\n                                        !check_segment_overlap(pc_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_right, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_right && found_left) break;\n                    if (!found_right && !found_left) break;\n                }\n            }\n        }\n    }\n\n    // --- Generate 45-degree Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point p_a = dots_vec[i];\n            Point p_b = dots_vec[j];\n\n            long long dx_ab = p_b.x - p_a.x;\n            long long dy_ab = p_b.y - p_a.y;\n\n            // Check if p_a and p_b could be adjacent vertices of a 45-degree rectangle.\n            // This implies their difference vector (dx_ab, dy_ab) must have |dx_ab| == |dy_ab| and not be zero.\n            if (abs(dx_ab) == abs(dy_ab) && dx_ab != 0) {\n                // The vector for the next side must be perpendicular and have the same length.\n                // Two possibilities for the next vector: (-dy_ab, dx_ab) and (dy_ab, -dx_ab).\n                int possible_v[2][2] = {{- (int)dy_ab, (int)dx_ab}, {(int)dy_ab, - (int)dx_ab}};\n\n                for (int k = 0; k < 2; ++k) {\n                    long long next_dx = possible_v[k][0];\n                    long long next_dy = possible_v[k][1];\n\n                    // Calculate the coordinates of the other two potential vertices of the rectangle.\n                    Point p_c = {p_b.x + (int)next_dx, p_b.y + (int)next_dy}; // p_c = p_b + next_vector\n                    Point p_d = {p_a.x + (int)next_dx, p_a.y + (int)next_dy}; // p_d = p_a + next_vector\n\n                    // Check if these potential points are within grid bounds.\n                    if (p_c.x >= 0 && p_c.x < N_val && p_c.y >= 0 && p_c.y < N_val &&\n                        p_d.x >= 0 && p_d.x < N_val && p_d.y >= 0 && p_d.y < N_val) {\n                        \n                        // If both p_c and p_d already exist as dots:\n                        if (current_dots.count(p_c) && current_dots.count(p_d)) {\n                            // We've found a rectangle formed by p_a, p_b, p_c, p_d.\n                            // A new dot can be placed at any of these vertices if it's currently empty.\n                            // We need to find an empty point (p_new) and three existing points (p2, p3, p4).\n\n                            // Case 1: p_a is the new dot (p_new). p_b, p_c, p_d must be existing dots.\n                            Point p_new = p_a;\n                            if (!current_dots.count(p_new)) { // Check if p_a is empty.\n                                // Order: (p_new, p_b, p_c, p_d) where p_b is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_b, p_c, p_d)) {\n                                    // Check for segment overlaps and perimeter dots.\n                                    if (!check_segment_overlap(p_new, p_b) &&\n                                        !check_segment_overlap(p_b, p_c) &&\n                                        !check_segment_overlap(p_c, p_d) &&\n                                        !check_segment_overlap(p_d, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_b, p_c, p_d, current_dots)) {\n                                            candidates.push_back({p_new, p_b, p_c, p_d, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 2: p_b is the new dot (p_new). p_a, p_c, p_d must be existing dots.\n                            p_new = p_b;\n                            if (!current_dots.count(p_new)) { // Check if p_b is empty.\n                                // Order: (p_new, p_a, p_d, p_c) where p_a is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_a, p_d, p_c)) {\n                                    if (!check_segment_overlap(p_new, p_a) &&\n                                        !check_segment_overlap(p_a, p_d) &&\n                                        !check_segment_overlap(p_d, p_c) &&\n                                        !check_segment_overlap(p_c, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_a, p_d, p_c, current_dots)) {\n                                            candidates.push_back({p_new, p_a, p_d, p_c, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 3: p_c is the new dot (p_new). p_a, p_b, p_d must be existing dots.\n                            p_new = p_c;\n                            if (!current_dots.count(p_new)) { // Check if p_c is empty.\n                                // Order: (p_new, p_d, p_a, p_b) where p_d is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_d, p_a, p_b)) {\n                                    if (!check_segment_overlap(p_new, p_d) &&\n                                        !check_segment_overlap(p_d, p_a) &&\n                                        !check_segment_overlap(p_a, p_b) &&\n                                        !check_segment_overlap(p_b, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_d, p_a, p_b, current_dots)) {\n                                            candidates.push_back({p_new, p_d, p_a, p_b, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 4: p_d is the new dot (p_new). p_a, p_b, p_c must be existing dots.\n                            p_new = p_d;\n                            if (!current_dots.count(p_new)) { // Check if p_d is empty.\n                                // Order: (p_new, p_c, p_b, p_a) where p_c is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_c, p_b, p_a)) {\n                                    if (!check_segment_overlap(p_new, p_c) &&\n                                        !check_segment_overlap(p_c, p_b) &&\n                                        !check_segment_overlap(p_b, p_a) &&\n                                        !check_segment_overlap(p_a, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_c, p_b, p_a, current_dots)) {\n                                            candidates.push_back({p_new, p_c, p_b, p_a, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M; // Number of initially placed dots.\n    cin >> N_val >> M;\n\n    // Calculate grid center coordinates. N is always odd.\n    center = {(int)(N_val - 1) / 2, (int)(N_val - 1) / 2};\n    total_weight_sum_val = 0; // Initialize total weight sum.\n\n    // Store the initial dots.\n    set<Point> current_dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        current_dots.insert({x, y});\n        total_weight_sum_val += weight({x, y}); // Add weight of initial dots.\n    }\n\n    // Store the operations performed.\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    int ops_count = 0;\n    // Game loop: continue as long as possible and within the operation limit.\n    while (ops_count < MAX_OPS) {\n        // Find all possible moves.\n        vector<CandidateMove> candidates = find_candidate_moves(current_dots);\n\n        // If no more moves can be made, break the loop.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates in descending order of weight (using reverse iterators on ascending sort).\n        sort(candidates.rbegin(), candidates.rend());\n\n        // Select the best move: the one with the highest weight for the new dot.\n        const auto& best_move = candidates[0];\n\n        // Apply the best move: add the new dot and update total weight.\n        current_dots.insert(best_move.p1_new);\n        total_weight_sum_val += best_move.weight_val;\n        ops_count++;\n\n        // Record the operation details.\n        operations.emplace_back(best_move.p1_new.x, best_move.p1_new.y,\n                                best_move.p2_old.x, best_move.p2_old.y,\n                                best_move.p3_old.x, best_move.p3_old.y,\n                                best_move.p4_old.x, best_move.p4_old.y);\n\n        // Add the segments of the newly drawn rectangle to the tracking maps.\n        add_segment(best_move.p1_new, best_move.p2_old);\n        add_segment(best_move.p2_old, best_move.p3_old);\n        add_segment(best_move.p3_old, best_move.p4_old);\n        add_segment(best_move.p4_old, best_move.p1_new);\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output the details of each operation.\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) << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <tuple>       // For std::tuple and std::tie\n#include <array>       // For std::array\n#include <queue>       // Not used in this version, but potentially useful for other heuristics\n#include <iomanip>     // Not used in this version\n\nusing namespace std;\n\nconst int SIZE = 10;\n\n// Global board state. Using std::array for better C++ integration and compatibility with std::tuple.\n// 0 means empty, 1, 2, 3 represent the flavors.\nstd::array<std::array<int, SIZE>, SIZE> board;\n\n// Stores the predefined sequence of candy flavors (f_1, f_2, ..., f_100)\nint f_sequence[101];\n\n// Helper function to find the p_t-th empty cell.\n// Cells are numbered 1 to (101-t) based on row-major order.\n// Returns a pair {row, col} of the cell's coordinates.\npair<int, int> get_pt_empty_cell(int p_t) {\n    int empty_count = 0;\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            if (board[r][c] == 0) {\n                empty_count++;\n                if (empty_count == p_t) {\n                    return {r, c};\n                }\n            }\n        }\n    }\n    return {-1, -1}; // Should not happen in a valid game state\n}\n\n// Applies a tilt operation to the global 'board'.\n// This function modifies the actual game state.\nvoid apply_actual_tilt(char dir) {\n    // Create a temporary copy of the current board state to correctly simulate gravity.\n    // This copy reflects the state BEFORE any candies start moving.\n    std::array<std::array<int, SIZE>, SIZE> temp_board_state = board;\n\n    // Handle each tilt direction\n    if (dir == 'F') { // Tilt Forward (candies move towards larger row indices, i.e., down)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col; // Stores flavors in this column in their original order\n            // Collect all flavors in the current column from top to bottom from the *copied* state\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the column in the global board (preparing to repopulate)\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            // Repopulate the column from the bottom, packing candies\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[SIZE - 1 - (k - 1 - i)][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'B') { // Tilt Backward (candies move towards smaller row indices, i.e., up)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col;\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[i][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'R') { // Tilt Right (candies move towards larger column indices, i.e., right)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][SIZE - 1 - (k - 1 - i)] = flavors_in_row[i];\n            }\n        }\n    } else { // dir == 'L', Tilt Left (candies move towards smaller column indices, i.e., left)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][i] = flavors_in_row[i];\n            }\n        }\n    }\n}\n\n// Simulates a tilt on a copy of the current board state.\n// Returns:\n// 1. The final row of the *newly placed* candy.\n// 2. The final column of the *newly placed* candy.\n// 3. The resulting board state after the tilt.\n// Uses std::array for the board state to enable proper tuple inclusion.\n// The original position (original_r, original_c) of the new candy is required to track its movement.\nstd::tuple<int, int, std::array<std::array<int, SIZE>, SIZE>> simulate_tilt_and_get_new_candy_pos(char dir, int original_r, int original_c) {\n    // This array will hold the board state after the simulated tilt.\n    std::array<std::array<int, SIZE>, SIZE> sim_board_state; \n\n    // Copy the current global board state to work on. The global 'board' already has the new candy placed.\n    // This copy is what we will modify during simulation.\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            sim_board_state[r][c] = board[r][c];\n        }\n    }\n\n    int sim_r_final = -1, sim_c_final = -1; // Will store the final position of the *newly placed* candy\n\n    // Apply tilt logic to sim_board_state\n    if (dir == 'F') { // Move down\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor} in the column\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) { // Read from the copied state\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end()); // Sort by original row to determine packing order\n\n        int k = occupied_in_col.size();\n        // Clear the column in the simulated board before repopulating\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from bottom\n        for (int i = 0; i < k; ++i) {\n            int original_row = occupied_in_col[i].first;\n            int new_row = SIZE - 1 - (k - 1 - i); // Packed to the bottom\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            // Check if this is the candy we just placed by comparing its original position\n            if (original_row == original_r) {\n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'B') { // Move up\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor}\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) {\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end());\n\n        int k = occupied_in_col.size();\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from top\n        for (int i = 0; i < k; ++i) {\n            int original_row = occupied_in_col[i].first;\n            int new_row = i; // Packed to the top\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            if (original_row == original_r) {\n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'R') { // Move right\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from right\n        for (int i = 0; i < k; ++i) {\n            int original_col = occupied_in_row[i].first;\n            int new_col = SIZE - 1 - (k - 1 - i); // Packed to the right\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    } else { // dir == 'L', Move left\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from left\n        for (int i = 0; i < k; ++i) {\n            int original_col = occupied_in_row[i].first;\n            int new_col = i; // Packed to the left\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    }\n    // Return the final position of the new candy and the simulated board state\n    return {sim_r_final, sim_c_final, sim_board_state};\n}\n\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the predefined sequence of candy flavors from input\n    for (int i = 1; i <= 100; ++i) {\n        cin >> f_sequence[i];\n    }\n\n    // Initialize the global board to be empty (all cells set to 0)\n    for (int i = 0; i < SIZE; ++i) {\n        for (int j = 0; j < SIZE; ++j) {\n            board[i][j] = 0;\n        }\n    }\n\n    // Main loop: Process each candy placement and make a tilt decision\n    // t is the current candy number being placed (1 to 100)\n    for (int t = 1; t <= 100; ++t) {\n        int p_t; // The index of the empty cell where the t-th candy will be placed.\n        cin >> p_t;\n\n        // Find the coordinates where the new candy is placed.\n        pair<int, int> cell = get_pt_empty_cell(p_t);\n        int current_r = cell.first;  // Original row of the new candy\n        int current_c = cell.second; // Original column of the new candy\n        int flavor_t = f_sequence[t]; // Flavor of the new candy\n        \n        // Place the candy in the actual board FIRST.\n        // The simulation functions will then read from this updated 'board'.\n        board[current_r][current_c] = flavor_t;\n\n        // For the 100th candy, no tilt is performed or output is required.\n        if (t == 100) {\n            continue; // Skip the rest of the loop for t=100\n        }\n\n        char best_tilt = 'F'; // Initialize best tilt direction to 'F' (for tie-breaking if all distances are equal)\n        // Initialize min_final_dist to a value larger than any possible Manhattan distance (max dist = 9+9=18 for a 10x10 grid)\n        int min_final_dist = SIZE * 2; \n\n        // Define the possible tilt directions. The order matters for tie-breaking: 'F' < 'B' < 'L' < 'R'.\n        char possible_tilts[] = {'F', 'B', 'L', 'R'};\n\n        // Evaluate each possible tilt direction\n        for (char tilt_dir : possible_tilts) {\n            int sim_r_final, sim_c_final; // Final position of the new candy after simulated tilt\n            std::array<std::array<int, SIZE>, SIZE> temp_board_state; // Board state after simulated tilt\n\n            // Simulate the tilt. This function reads from the current global 'board',\n            // simulates the tilt on a copy, and returns the final position of the new candy\n            // and the resulting board state.\n            tie(sim_r_final, sim_c_final, temp_board_state) = simulate_tilt_and_get_new_candy_pos(tilt_dir, current_r, current_c);\n\n            int current_min_dist = SIZE * 2; // Initialize min distance for this specific tilt direction\n            \n            // Iterate through the *simulated* board to find the nearest neighbor of the same flavor.\n            for (int r_other = 0; r_other < SIZE; ++r_other) {\n                for (int c_other = 0; c_other < SIZE; ++c_other) {\n                    // Check if the cell contains a candy of the same flavor AND is not the new candy's final position.\n                    // The condition `!(r_other == sim_r_final && c_other == sim_c_final)` is important\n                    // to ensure we are finding distance to *other* candies, not to itself.\n                    if (temp_board_state[r_other][c_other] == flavor_t && !(r_other == sim_r_final && c_other == sim_c_final)) {\n                        // Calculate Manhattan distance from the new candy's final position to this neighbor\n                        int dist = abs(sim_r_final - r_other) + abs(sim_c_final - c_other);\n                        // Update the minimum distance found for this tilt direction\n                        current_min_dist = min(current_min_dist, dist);\n                    }\n                }\n            }\n            \n            // If current_min_dist is still SIZE*2, it means no other candy of the same flavor exists.\n            // This implies the new candy is the first of its flavor. Any tilt is equally \"good\"\n            // in terms of distance to neighbors. The tie-breaking logic will then apply.\n\n            // Update the best tilt if the current tilt yields a smaller minimum distance.\n            // Tie-breaking is implicitly handled by the order of checking tilts ('F' < 'B' < 'L' < 'R').\n            // If current_min_dist is strictly smaller, we found a better tilt.\n            if (current_min_dist < min_final_dist) {\n                min_final_dist = current_min_dist;\n                best_tilt = tilt_dir;\n            }\n            // If current_min_dist == min_final_dist, the 'best_tilt' remains unchanged because the loop\n            // iterates in the desired order, ensuring lexicographical tie-breaking.\n        }\n\n        // After evaluating all possible tilts, apply the chosen 'best_tilt' to the actual game board.\n        apply_actual_tilt(best_tilt);\n\n        // Output the chosen tilt direction, followed by a newline.\n        cout << best_tilt << endl;\n        // Flush the output buffer to ensure the judge receives the output immediately.\n        cout << flush;\n    }\n\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\n// Function to convert an adjacency matrix to its bitstring representation.\n// The order of edges in the string is lexicographical by (i, j) pairs where i < j.\nstd::string adj_matrix_to_string(int N, const std::vector<std::vector<bool>>& adj) {\n    std::string s = \"\";\n    s.reserve(N * (N - 1) / 2); // Pre-allocate memory for efficiency\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            s += (adj[i][j] ? '1' : '0');\n        }\n    }\n    return s;\n}\n\n// Function to compute the degree sequence of a graph from its bitstring representation.\n// The degree sequence is returned as a vector of integers.\nstd::vector<int> get_degrees_from_string(int N, const std::string& s) {\n    std::vector<int> degrees(N, 0); // Initialize degrees for all vertices to 0\n    int k = 0; // Index for iterating through the bitstring\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (s[k] == '1') { // If an edge exists between vertex i and vertex j\n                degrees[i]++; // Increment degree of vertex i\n                degrees[j]++; // Increment degree of vertex j\n            }\n            k++; // Move to the next character in the bitstring\n        }\n    }\n    // The degree sequence comparison uses the canonical degree sequence of G_i,\n    // which is stored in precomputed_degrees. We do NOT sort degrees_H here,\n    // as we compare it against the specific, non-sorted degree sequences of G_i.\n    return degrees;\n}\n\nint main() {\n    // Fast I/O operations\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    std::cin >> M >> epsilon;\n\n    // Heuristic choice for N:\n    // The score formula round(10^9 * 0.9^E / N) implies a smaller N is better for the score multiplier (1/N).\n    // However, N must be large enough to create M distinct graphs that are robust to noise and vertex shuffling.\n    // The total number of possible edges in an N-vertex graph is N*(N-1)/2.\n    // To distinguish M graphs using edge counts as a primary feature, we need N*(N-1)/2 >= M-1.\n    // For M=100, this implies N=15 (since 14*13/2=91 and 15*14/2=105).\n    // Given epsilon can be up to 0.4, relying solely on edge counts might be insufficient.\n    // N=20 provides 190 edges, offering more structural diversity and thus better distinguishability.\n    // It balances the 1/N score factor (1/20) with sufficient edge capacity for M=100 graphs.\n    // N=20 is within the problem's constraint [4, 100].\n    int N = 20; \n\n    // Store precomputed degree sequences for G_0, ..., G_{M-1}.\n    // This allows for quick comparison during query processing.\n    std::vector<std::vector<int>> precomputed_degrees(M, std::vector<int>(N));\n    // Store the string representations of G_0, ..., G_{M-1} for output.\n    std::vector<std::string> graph_strings(M);\n\n    // Seed the random number generator for graph generation.\n    // Using a fixed seed (0) ensures that the generated graphs are identical\n    // across different runs for the same M and epsilon values, which is crucial for reproducibility.\n    std::mt19937 rng(0); \n\n    // Maximum possible edges in an N-vertex graph.\n    int max_possible_edges = N * (N - 1) / 2;\n\n    // Generate M distinct graphs.\n    for (int i = 0; i < M; ++i) {\n        // Generate graphs with edge counts spaced out to maximize distinguishability.\n        // The i-th graph (0-indexed) will have approximately i * (max_edges / (M-1)) edges.\n        // This strategy spreads the edge counts evenly from 0 up to max_possible_edges.\n        // Since M >= 10, M-1 is at least 9, so division by zero is avoided.\n        int target_edges = static_cast<int>(static_cast<double>(i) * max_possible_edges / (M - 1));\n        \n        // Ensure target_edges is within valid bounds [0, max_possible_edges].\n        // This is a safeguard against potential floating-point inaccuracies or edge cases.\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n\n        // Initialize an adjacency matrix for the graph G_i.\n        std::vector<std::vector<bool>> adj(N, std::vector<bool>(N, false));\n        int edges_added = 0;\n\n        // Add exactly target_edges randomly to the graph G_i.\n        // This loop picks random pairs of vertices and adds an edge if it doesn't exist,\n        // until the target number of edges is reached.\n        // For N=20, this approach is efficient enough.\n        if (target_edges > 0) {\n            while (edges_added < target_edges) {\n                int u = rng() % N; // Pick a random vertex u\n                int v = rng() % N; // Pick a random vertex v\n                if (u == v) continue; // Avoid self-loops\n                if (u > v) std::swap(u, v); // Ensure consistent ordering (u < v) for edge representation\n                \n                if (!adj[u][v]) { // If the edge (u,v) does not exist yet\n                    adj[u][v] = adj[v][u] = true; // Add the edge (undirected)\n                    edges_added++; // Increment the count of added edges\n                }\n            }\n        }\n        \n        // Convert the constructed adjacency matrix to the required string format.\n        graph_strings[i] = adj_matrix_to_string(N, adj);\n        // Compute and store the degree sequence for this graph G_i.\n        precomputed_degrees[i] = get_degrees_from_string(N, graph_strings[i]);\n    }\n\n    // Output N, followed by the string representations of the M generated graphs.\n    std::cout << N << std::endl;\n    for (int i = 0; i < M; ++i) {\n        std::cout << graph_strings[i] << std::endl;\n    }\n    // Flush the output buffer to ensure all generated graph data is sent to the judge.\n    std::cout << std::flush; \n\n    // Process the 100 queries.\n    for (int k = 0; k < 100; ++k) {\n        std::string H_str; // The graph string received for the current query H_k.\n        std::cin >> H_str;\n\n        // Compute the degree sequence of the received graph H_k.\n        std::vector<int> degrees_H = get_degrees_from_string(N, H_str);\n\n        int best_match_idx = -1; // Stores the index of the best matching G_i found so far.\n        // Initialize min_dist to a value larger than any possible L1 distance.\n        // For N=20, the maximum L1 distance is N*(N-1) = 20*19 = 380.\n        // Using -1 as a flag indicates that no comparison has been made yet.\n        long long min_dist = -1; \n\n        // Find which precomputed graph G_i has a degree sequence 'closest' to H_k's degree sequence.\n        // Closeness is measured by the L1 distance.\n        for (int i = 0; i < M; ++i) {\n            long long current_dist = 0; // L1 distance for G_i.\n            for (int j = 0; j < N; ++j) {\n                // Sum of absolute differences in degrees between H_k and G_i for each vertex.\n                current_dist += std::abs(degrees_H[j] - precomputed_degrees[i][j]);\n            }\n\n            // If this is the first graph considered (best_match_idx == -1), or\n            // if the current graph G_i is closer to H_k than the current best match,\n            // update the best match.\n            if (best_match_idx == -1 || current_dist < min_dist) {\n                min_dist = current_dist;\n                best_match_idx = i;\n            }\n        }\n        \n        // Output the predicted index t_k. This is the index of the graph G_i\n        // that H_k is most likely generated from based on degree sequence similarity.\n        std::cout << best_match_idx << std::endl;\n        // Flush the output buffer to ensure the prediction is sent immediately.\n        std::cout << std::flush; \n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Use a large value for infinity, greater than any possible shortest path sum.\n// Max path length can be approximately N * max_w = 1000 * 10^6 = 10^9.\n// The problem uses 10^9 for unreachable distances. Our internal INF must be larger\n// to correctly identify unreachable nodes in Dijkstra's algorithm.\nconst long long INF = 4e15; \n\n// Structure to represent an edge in the graph.\nstruct Edge {\n    int u, v, w, id;       // Endpoints, weight, and original index of the edge.\n    long long dist_uv;     // Shortest path distance between u and v in the original graph.\n    long long endpoint_path_sum; // Sum of shortest paths from all nodes to u and v.\n    int assignment;        // The day this edge is scheduled for repair.\n};\n\n// Structure for Dijkstra's priority queue: stores distance and vertex.\nstruct State {\n    long long dist;\n    int vertex;\n\n    // For priority_queue: sort by distance (min-heap).\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\n// Dijkstra's algorithm to find shortest paths from a single source vertex.\n// It returns a vector containing the shortest distance from start_node to every other node.\n// Time complexity: O(M log N) or O(M + N log N) depending on priority queue implementation.\nvector<long long> dijkstra(int start_node, int n, const vector<vector<pair<int, int>>>& adj) {\n    vector<long long> dist(n + 1, INF); // Initialize distances to infinity.\n    dist[start_node] = 0;               // Distance from source to itself is 0.\n    priority_queue<State, vector<State>, greater<State>> pq;\n    pq.push({0, start_node});\n\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        long long d = current.dist;\n        int v = current.vertex;\n\n        // If we found a shorter path to 'v' already, skip this one.\n        if (d > dist[v]) {\n            continue;\n        }\n\n        // Explore neighbors of vertex 'v'.\n        for (auto& edge_info : adj[v]) {\n            int neighbor = edge_info.first;\n            int weight = edge_info.second;\n            \n            // Relaxation step: If a shorter path to 'neighbor' is found through 'v'.\n            // Check for overflow before addition. If dist[v] is INF, dist[v] + weight will be larger than any finite path or INF, so this condition handles INF correctly.\n            if (dist[v] != INF && dist[v] + weight < dist[neighbor]) {\n                dist[neighbor] = dist[v] + weight;\n                pq.push({dist[neighbor], neighbor});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, d_days, k_limit;\n    cin >> n >> m >> d_days >> k_limit;\n\n    // Adjacency list for graph: vector of vectors of pairs {neighbor, weight}.\n    // Vertices are 1-indexed in input, so we use size n+1 for 1-based indexing.\n    vector<vector<pair<int, int>>> adj(n + 1);\n    vector<Edge> edges;\n    edges.reserve(m); // Pre-allocate memory for edges.\n\n    // Read edges and build the adjacency list.\n    for (int i = 0; i < m; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w}); // Graph is undirected.\n        // Store edge details including its original index 'i' (0 to m-1).\n        edges.push_back({u, v, w, i, 0, 0, 0}); // Initialize endpoint_path_sum to 0\n    }\n\n    // Step 1: Compute all-pairs shortest paths (APSP).\n    // This is done by running Dijkstra from each vertex.\n    // For N=1000, M=3000, complexity O(N*(M+N log N)) is feasible.\n    vector<vector<long long>> dist_matrix(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        dist_matrix[i] = dijkstra(i, n, adj);\n    }\n\n    // Step 2: Precompute sum of shortest path distances from all nodes to each node.\n    // sum_dist_to[j] will store sum(dist_matrix[i][j] for i = 1 to N).\n    vector<long long> sum_dist_to(n + 1, 0);\n    for (int i = 1; i <= n; ++i) { // Source node\n        for (int j = 1; j <= n; ++j) { // Destination node\n            // Only add finite distances. The graph is guaranteed to be connected.\n            if (dist_matrix[i][j] != INF) {\n                sum_dist_to[j] += dist_matrix[i][j];\n            }\n        }\n    }\n\n    // Step 3: For each edge, populate dist_uv and endpoint_path_sum.\n    for (auto& edge : edges) {\n        edge.dist_uv = dist_matrix[edge.u][edge.v];\n        \n        // Calculate sum of shortest paths involving endpoints for this edge.\n        // This heuristic tries to capture how \"central\" the edge's endpoints are.\n        // Use long long to avoid overflow for sums.\n        edge.endpoint_path_sum = sum_dist_to[edge.u] + sum_dist_to[edge.v];\n    }\n\n    // Step 4: Sort edges based on a refined heuristic.\n    // Heuristic:\n    // 1. Prioritize edges that are direct shortest paths (i.e., edge.w == edge.dist_uv).\n    // 2. Among those, prioritize edges connecting vertices with high 'centrality' (large endpoint_path_sum).\n    // 3. If ties persist, prioritize edges connecting vertices that are far apart (large edge.dist_uv).\n    // 4. If ties persist, prioritize heavier edges (large edge.w).\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        bool is_direct_shortest_a = (a.dist_uv == a.w);\n        bool is_direct_shortest_b = (b.dist_uv == b.w);\n\n        if (is_direct_shortest_a != is_direct_shortest_b) {\n            // Prioritize edges that are direct shortest paths. 'true' (1) > 'false' (0).\n            return is_direct_shortest_a > is_direct_shortest_b; \n        }\n        \n        // If both are direct shortest paths OR both are not:\n        if (a.endpoint_path_sum != b.endpoint_path_sum) {\n            // Prioritize edges whose endpoints are more central (higher sum of path lengths).\n            return a.endpoint_path_sum > b.endpoint_path_sum;\n        }\n\n        if (a.dist_uv != b.dist_uv) {\n            // Prioritize edges connecting vertices that are farther apart.\n            return a.dist_uv > b.dist_uv; \n        }\n        \n        // If all previous criteria are equal:\n        // Prioritize heavier edges.\n        return a.w > b.w; \n    });\n\n    // Step 5: Assign edges to days using a round-robin approach for better balance.\n    // This ensures that the top-ranked (most critical) edges are spread out over all D days.\n    // The constraint K > ceil(M/D) guarantees that each day will receive at most ceil(M/D) edges, which is <= K.\n    vector<int> assignments(m); // To store the day assignment for each edge, indexed by its original ID.\n    \n    for (int i = 0; i < m; ++i) {\n        // Assign the i-th edge in the sorted list to day (i % d_days) + 1.\n        int assigned_day = (i % d_days) + 1;\n        edges[i].assignment = assigned_day;\n        assignments[edges[i].id] = assigned_day;\n    }\n\n    // Step 6: Output the assignments for each edge in the order they appeared in the input.\n    for (int i = 0; i < m; ++i) {\n        cout << assignments[i] << (i == m - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\n// Grid index helpers\n#define GRID_IDX(x, y, z, D) ((x) * (D) * (D) + (y) * (D) + (z))\n\n// Grid access macros\n#define GRID_GET(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n#define GRID_WRITE(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n\n// Polycube representation\nstruct Polycube {\n    vector<tuple<int, int, int>> cells; // Stores cells in grid coordinates (x, y, z)\n\n    // Custom comparison for Polycube, used for std::map keys.\n    // Sorts cells lexicographically.\n    bool operator<(const Polycube& other) const {\n        return cells < other.cells;\n    }\n    bool operator==(const Polycube& other) const {\n        return cells == other.cells;\n    }\n    int volume() const { return cells.size(); }\n};\n\n// Global parameters\nint D;\nvector<string> f1_str, r1_str, f2_str, r2_str;\nvector<bool> G1_grid, G2_grid; // G1_grid[idx] is true if cell can be occupied for obj1\n\n// --- ID and Shape Management ---\n// Counter for unique block IDs to be used in the output grid.\n// Each DISTINCT CONNECTED COMPONENT placed gets a unique ID.\nint next_component_output_id_counter; \n\n// Map: canonical_shape -> score_id.\n// A score_id is assigned to each distinct SHAPE. This is used for scoring.\nmap<Polycube, int> shape_to_score_id;\n// Counter for assigning new score_ids to new shapes.\nint next_score_id_counter; \n\n// Store assignments for each object.\nstruct BlockAssignment {\n    int output_id;       // Unique ID for this specific connected component in the output grid.\n    int score_id;        // ID representing its canonical shape for scoring purposes.\n    Polycube shape_grid_coords; // The actual polycube in grid coordinates.\n};\nvector<BlockAssignment> assignments1, assignments2;\n\n// Library of basic polycubes (shapes to generate orientations from)\nvector<Polycube> base_library_shapes;\n\n// Pre-generated orientations for library shapes.\n// Stores {volume, list_of_normalized_orientations}\nvector<pair<int, vector<Polycube>>> precomputed_library_orientations;\n\n// Helper to create a 3D grid vector\ntemplate<typename T>\nvector<T> create_grid_vec(size_t size, T default_val) {\n    return vector<T>(size, default_val);\n}\n\n// Convert string silhouettes to boolean grids representing valid cell locations\nvoid setup_grids() {\n    G1_grid.assign(D * D * D, false);\n    G2_grid.assign(D * D * D, false);\n\n    // For object 1, a cell (x,y,z) can be occupied if f1(z,x)=1 and r1(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int x = 0; x < D; ++x) {\n            if (f1_str[z][x] == '1') {\n                for (int y = 0; y < D; ++y) {\n                    if (r1_str[z][y] == '1') {\n                        GRID_GET(G1_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // For object 2, a cell (x,y,z) can be occupied if f2(z,x)=1 and r2(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int y = 0; y < D; ++y) {\n            if (r2_str[z][y] == '1') {\n                for (int x = 0; x < D; ++x) {\n                    if (f2_str[z][x] == '1') {\n                        GRID_GET(G2_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalize a polycube: translate its cells so the minimum coordinate is (0,0,0)\n// and sort the cells lexicographically. This gives a canonical representation for translation.\nPolycube normalize(const Polycube& poly) {\n    if (poly.cells.empty()) return poly;\n    \n    int min_x = get<0>(poly.cells[0]);\n    int min_y = get<1>(poly.cells[0]);\n    int min_z = get<2>(poly.cells[0]);\n    for (const auto& cell : poly.cells) {\n        min_x = min(min_x, get<0>(cell));\n        min_y = min(min_y, get<1>(cell));\n        min_z = min(min_z, get<2>(cell));\n    }\n    \n    Polycube normalized_poly;\n    normalized_poly.cells.reserve(poly.cells.size());\n    for (const auto& cell : poly.cells) {\n        normalized_poly.cells.emplace_back(get<0>(cell) - min_x, get<1>(cell) - min_y, get<2>(cell) - min_z);\n    }\n    sort(normalized_poly.cells.begin(), normalized_poly.cells.end());\n    return normalized_poly;\n}\n\n// Generate all unique orientations (rotations) of a polycube.\n// Returns a vector of normalized Polycubes.\nvector<Polycube> get_orientations(const Polycube& poly) {\n    set<Polycube> unique_orientations;\n    vector<tuple<int,int,int>> current_cells = poly.cells;\n\n    // Apply rotations around X, Y, Z axes\n    for (int rotx = 0; rotx < 4; ++rotx) { // Rotations around X-axis\n        vector<tuple<int,int,int>> current_cells_y = current_cells;\n        for (int roty = 0; roty < 4; ++roty) { // Rotations around Y-axis\n            vector<tuple<int,int,int>> current_cells_z = current_cells_y;\n            for (int rotz = 0; rotz < 4; ++rotz) { // Rotations around Z-axis\n                Polycube oriented_poly;\n                oriented_poly.cells = current_cells_z;\n                unique_orientations.insert(normalize(oriented_poly));\n                \n                // Rotate around Z: (x, y, z) -> (-y, x, z)\n                vector<tuple<int,int,int>> next_z;\n                next_z.reserve(current_cells_z.size());\n                for(const auto& cell : current_cells_z) next_z.emplace_back(-get<1>(cell), get<0>(cell), get<2>(cell));\n                current_cells_z = next_z;\n            }\n            // Rotate around Y: (x, y, z) -> (z, y, -x)\n            vector<tuple<int,int,int>> next_y;\n            next_y.reserve(current_cells_y.size());\n            for(const auto& cell : current_cells_y) next_y.emplace_back(get<2>(cell), get<1>(cell), -get<0>(cell));\n            current_cells_y = next_y;\n        }\n        // Rotate around X: (x, y, z) -> (x, -z, y)\n        vector<tuple<int,int,int>> next_x;\n        next_x.reserve(current_cells.size());\n        for(const auto& cell : current_cells) next_x.emplace_back(get<0>(cell), -get<2>(cell), get<1>(cell));\n        current_cells = next_x;\n    }\n\n    vector<Polycube> orientations;\n    orientations.reserve(unique_orientations.size());\n    for (const auto& p : unique_orientations) orientations.push_back(p);\n    return orientations;\n}\n\n// Initialize the library of polycubes with all their orientations\nvoid initialize_library() {\n    // Define a set of 'base' polycubes to generate orientations from.\n    base_library_shapes.push_back({{{0,0,0}}}); // Monomino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}}}); // Domino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}}}); // L-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}}}); // I-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}}}); // Square tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {3,0,0}}}); // I-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}}}); // I-tetromino (vertical)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {1,1,0}}}); // T-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {1,1,0}, {2,1,0}}}); // Skew tetromino (S)\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {1,1,0}, {1,2,0}}}); // Skew tetromino (Z)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {2,1,0}}}); // L-tetromino\n    // Add more shapes if needed for better scores.\n\n    // Use a map to group orientations by their canonical form.\n    map<Polycube, vector<Polycube>> unique_canonical_shapes;\n\n    for(const auto& base_shape : base_library_shapes) {\n        vector<Polycube> orientations = get_orientations(base_shape); // These are already normalized\n        \n        // The first orientation in the list represents the canonical form.\n        Polycube canonical_form = orientations[0]; \n        \n        // If this canonical form is already in our map, skip.\n        if (unique_canonical_shapes.find(canonical_form) == unique_canonical_shapes.end()) {\n            unique_canonical_shapes[canonical_form] = orientations;\n        }\n    }\n    \n    // Populate precomputed_library_orientations from the map.\n    for(auto const& [canonical_shape, orientations_list] : unique_canonical_shapes) {\n        precomputed_library_orientations.push_back({(int)orientations_list[0].cells.size(), orientations_list});\n    }\n\n    // Sort library by volume descending to prioritize larger blocks.\n    sort(precomputed_library_orientations.rbegin(), precomputed_library_orientations.rend());\n}\n\n// Utility to check if a cell coordinate is within the DxD D grid bounds\nbool is_valid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n    \n// Attempt to place a given normalized block_shape (from the library) such that it covers the target cell.\n// Returns true if a valid placement is found, false otherwise.\n// If true, 'placed_block_out_grid_coords' will contain the actual polycube in grid coordinates.\nbool try_place(const Polycube& normalized_library_shape, // A normalized orientation from the library\n               int target_x, int target_y, int target_z, // The cell we MUST cover\n               const vector<bool>& G, // Grid indicating valid cell locations for the object\n               const vector<bool>& covered, // Grid indicating already occupied cells\n               Polycube& placed_block_out_grid_coords) { // Output: the placed polycube in grid coordinates\n\n    // Iterate through each cell of the normalized_library_shape to try aligning it with the target cell.\n    for (const auto& cell_in_shape : normalized_library_shape.cells) {\n        int shape_cell_x, shape_cell_y, shape_cell_z;\n        tie(shape_cell_x, shape_cell_y, shape_cell_z) = cell_in_shape;\n\n        // Calculate the potential origin (top-left-front corner) of the block in grid coordinates.\n        int origin_x = target_x - shape_cell_x;\n        int origin_y = target_y - shape_cell_y;\n        int origin_z = target_z - shape_cell_z;\n\n        Polycube current_placement_grid_coords; // To store cells of the potential placement\n        bool possible = true;\n\n        // Check if all cells of the block, when placed at this origin, are valid.\n        for (const auto& cell_in_shape_ : normalized_library_shape.cells) {\n            int cx, cy, cz;\n            tie(cx, cy, cz) = cell_in_shape_;\n            \n            // Calculate actual grid coordinates for this cell of the block.\n            int px = origin_x + cx;\n            int py = origin_y + cy;\n            int pz = origin_z + cz;\n\n            // Check boundaries, if cell is allowed by G, and if it's not already covered.\n            if (!is_valid(px, py, pz) || !GRID_GET(G, px, py, pz, D) || GRID_GET(covered, px, py, pz, D)) {\n                possible = false;\n                break;\n            }\n            current_placement_grid_coords.cells.emplace_back(px, py, pz);\n        }\n\n        if (possible) {\n            // Found a valid placement that covers (target_x, target_y, target_z) and respects constraints.\n            placed_block_out_grid_coords = current_placement_grid_coords;\n            return true;\n        }\n    }\n    return false; // No valid placement found for this library block shape to cover the target cell.\n}\n\n// Greedy fill function\nvoid fill_object(const vector<bool>& G,\n                 vector<bool>& covered,\n                 vector<BlockAssignment>& assignments,\n                 bool is_object1) {\n\n    // Iterate through all cells of the grid.\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 this cell must be filled (according to G) and is not yet covered by any block:\n                if (GRID_GET(G, x, y, z, D) && !GRID_GET(covered, x, y, z, D)) {\n                    // This cell (x,y,z) must be part of a NEW, CONNECTED block instance.\n                    \n                    bool block_placed_in_this_step = false;\n                    Polycube best_placed_block_grid_coords; // Stores the best found block instance in grid coordinates.\n                    int best_block_score_id = -1;             // The score_id associated with this shape.\n                    int max_volume_found = -1;                // To prioritize larger blocks.\n\n                    // --- Attempt to fit the largest possible library block first ---\n                    for (const auto& lib_item : precomputed_library_orientations) {\n                        int current_vol = lib_item.first;\n                        const vector<Polycube>& orientations = lib_item.second; // list of normalized orientations\n\n                        // Optimization: If we already found a block and the current library block is not larger, skip.\n                        if (block_placed_in_this_step && current_vol <= max_volume_found) continue;\n\n                        // Try each orientation of the current library shape.\n                        for (const auto& oriented_shape_normalized : orientations) { \n                            Polycube current_placed_block_grid_coords; // To store the resulting polycube in grid coords\n                            \n                            // try_place will find an alignment that covers (x,y,z) and forms a valid, connected polycube.\n                            if (try_place(oriented_shape_normalized, x, y, z, G, covered, current_placed_block_grid_coords)) {\n                                // Success! 'current_placed_block_grid_coords' is a single, connected polycube.\n                                \n                                // Get its canonical form to determine its score_id.\n                                Polycube canonical_form = normalize(current_placed_block_grid_coords);\n                                \n                                int current_score_id;\n                                // Find or assign a score_id for this canonical shape.\n                                if (shape_to_score_id.count(canonical_form)) {\n                                    // This shape has been seen before, reuse its score_id.\n                                    current_score_id = shape_to_score_id[canonical_form];\n                                } else {\n                                    // New shape, assign a new score_id.\n                                    current_score_id = next_score_id_counter++;\n                                    shape_to_score_id[canonical_form] = current_score_id;\n                                }\n                                \n                                // We found a candidate block. If it's larger than the previous best for this cell, update.\n                                if (!block_placed_in_this_step || current_vol > max_volume_found) {\n                                    best_placed_block_grid_coords = current_placed_block_grid_coords; // Store the actual placed polycube\n                                    best_block_score_id = current_score_id;\n                                    max_volume_found = current_vol;\n                                    block_placed_in_this_step = true;\n                                }\n                            }\n                        }\n                    }\n                    \n                    // --- Assignment ---\n                    if (block_placed_in_this_step) {\n                        // Assign a NEW, UNIQUE output ID to this specific connected component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        // Add the assignment, linking the output ID, score ID, and the placed block.\n                        assignments.push_back({current_component_output_id, best_block_score_id, best_placed_block_grid_coords});\n                        \n                        // Mark all cells of this specific block instance as covered.\n                        for (const auto& cell : best_placed_block_grid_coords.cells) {\n                            GRID_GET(covered, get<0>(cell), get<1>(cell), get<2>(cell), D) = true;\n                        }\n                    } else {\n                        // Fallback: No library block could be placed starting from (x,y,z).\n                        // Place a 1x1x1 unit block at (x,y,z).\n                        Polycube unit_block_cell_grid_coords = {{{x, y, z}}}; // The single cell at its grid position\n                        Polycube canonical_unit = normalize(unit_block_cell_grid_coords); // Canonical is {{{0,0,0}}}\n\n                        int current_score_id;\n                        // Get or assign score_id for the unit block shape.\n                        if (shape_to_score_id.count(canonical_unit)) {\n                            current_score_id = shape_to_score_id[canonical_unit];\n                        } else {\n                            current_score_id = next_score_id_counter++;\n                            shape_to_score_id[canonical_unit] = current_score_id;\n                        }\n                        \n                        // Assign a NEW, UNIQUE output ID to this unit block component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        assignments.push_back({current_component_output_id, current_score_id, unit_block_cell_grid_coords});\n                        GRID_GET(covered, x, y, z, D) = true; // Mark this cell as covered.\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input D (dimension of the grid)\n    cin >> D;\n    \n    // Resize input strings for silhouettes\n    f1_str.resize(D); r1_str.resize(D);\n    f2_str.resize(D); r2_str.resize(D);\n\n    // Read the four silhouette images\n    for (int i = 0; i < D; ++i) cin >> f1_str[i];\n    for (int i = 0; i < D; ++i) cin >> r1_str[i];\n    for (int i = 0; i < D; ++i) cin >> f2_str[i];\n    for (int i = 0; i < D; ++i) cin >> r2_str[i];\n\n    // Initialize the grids that define where cells can be occupied\n    setup_grids();\n    // Initialize the library of shapes and their orientations\n    initialize_library();\n\n    // Initialize counters.\n    // next_component_output_id_counter ensures each placed component gets a unique ID for the output grid.\n    next_component_output_id_counter = 1; \n    // next_score_id_counter ensures each distinct shape gets a unique score_id for scoring.\n    next_score_id_counter = 1;          \n    shape_to_score_id.clear();          // Clear for object 1.\n    assignments1.clear();               \n    vector<bool> covered1(D * D * D, false);\n    fill_object(G1_grid, covered1, assignments1, true); // Fill object 1\n\n    // Process object 2.\n    // IMPORTANT: Counters are NOT reset for shapes. This allows sharing score_ids for identical shapes.\n    // HOWEVER, next_component_output_id_counter must NOT be reset if we want output IDs to be global and unique across both objects.\n    // Based on problem statement and example, total 'n' blocks means total unique components.\n    assignments2.clear();               \n    vector<bool> covered2(D * D * D, false);\n    fill_object(G2_grid, covered2, assignments2, false); // Fill object 2\n\n    // --- Output ---\n    // The total number of blocks 'n' is the maximum output ID used.\n    cout << next_component_output_id_counter - 1 << endl;\n\n    // Output for object 1: Use the unique output_id for each component.\n    vector<int> b1_output(D * D * D, 0);\n    for (const auto& assign : assignments1) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b1_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b1_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    // Output for object 2: Use the unique output_id for each component.\n    vector<int> b2_output(D * D * D, 0);\n    for (const auto& assign : assignments2) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b2_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b2_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <map>\n\n// Use long double for precision in distance calculations\nusing ftype = long double;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nstruct Resident {\n    int id;\n    Point pos;\n};\n\nint N_stations_global, M_edges_global, K_residents_global;\nstd::vector<Point> station_pos_global;\nstd::vector<Edge> edges_global; // Store edges with original IDs and weights\nstd::vector<Resident> residents_global;\n\n// Precomputed distances: dists_global[i][k] is distance from station i to resident k\nstd::vector<std::vector<ftype>> dists_global;\n\n// Function to calculate Euclidean distance\nftype dist(Point p1, Point p2) {\n    ftype dx = static_cast<ftype>(p1.x) - p2.x;\n    ftype dy = static_cast<ftype>(p1.y) - p2.y;\n    return std::sqrt(dx * dx + dy * dy);\n}\n\n// Calculate total cost\nlong long calculate_total_cost(const std::vector<int>& P, const std::vector<int>& B) {\n    long long edge_cost = 0;\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (B[j]) {\n            edge_cost += edges_global[j].w;\n        }\n    }\n    long long station_cost = 0;\n    for (int i = 0; i < N_stations_global; ++i) {\n        station_cost += static_cast<long long>(P[i]) * P[i];\n    }\n    return station_cost + edge_cost;\n}\n\n// Helper to compute reachable vertices from station 0\nstd::vector<int> get_reachable_stations(int N, const std::vector<int>& B_current, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> reachable_indices;\n    std::vector<std::vector<int>> adj(N);\n    \n    // Rebuild adjacency list from active edges (B_current)\n    for(const auto& edge : all_edges_indexed) {\n        if (B_current[edge.id]) { // Use edge.id to check B_current\n            adj[edge.u].push_back(edge.v);\n            adj[edge.v].push_back(edge.u);\n        }\n    }\n\n    std::queue<int> q;\n    if (N > 0) { // Station 0 is always source\n        q.push(0);\n        reachable_indices.push_back(0);\n    }\n    \n    std::vector<bool> visited(N, false);\n    if (N > 0) visited[0] = true;\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for(int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                reachable_indices.push_back(v);\n            }\n        }\n    }\n    return reachable_indices;\n}\n\n\n// --- Optimized P Assignment using Priority Queue ---\n\n// Struct to hold state for PQ in solve_P_greedy_marginal_cost\nstruct StationUpgradeState {\n    long long marginal_cost; // Cost to cover the *next* uncovered resident for this station\n    int station_idx;\n\n    bool operator>(const StationUpgradeState& other) const {\n        // Primary sort by cost, secondary by station index for deterministic behavior\n        if (marginal_cost != other.marginal_cost) {\n            return marginal_cost > other.marginal_cost; // Min-heap\n        }\n        return station_idx > other.station_idx;\n    }\n};\n\n// Global structures for the PQ-based solver\nstd::vector<std::vector<std::pair<ftype, int>>> residents_by_dist_global; // For each station, residents sorted by distance {distance, resident_id}\nstd::vector<int> next_uncovered_resident_idx_global; // For each station, index into residents_by_dist_global\nstd::vector<bool> global_resident_covered_global;\nint current_uncovered_count_global;\n\n// Function to update coverage status and push next upgrade to PQ\nvoid update_coverage_and_pq(int station_idx, std::vector<int>& P, \n                            std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>>& pq) {\n    \n    if (station_idx >= N_stations_global || residents_by_dist_global[station_idx].empty()) return;\n\n    // Find the first resident for this station that is not yet covered and reachable by current P[station_idx]\n    int current_k_idx_in_list = next_uncovered_resident_idx_global[station_idx];\n    \n    while(current_k_idx_in_list < residents_by_dist_global[station_idx].size()) {\n        auto& resident_entry = residents_by_dist_global[station_idx][current_k_idx_in_list];\n        int k_id = resident_entry.second;\n        ftype dist_to_k = resident_entry.first;\n\n        // If resident is too far even with max P, skip it.\n        if (dist_to_k > 5000.0 + 1e-9) { \n            current_k_idx_in_list++;\n            continue;\n        }\n        // If resident is already covered OR cannot be covered by current P[station_idx]\n        if (global_resident_covered_global[k_id] || dist_to_k > P[station_idx] + 1e-9) {\n            current_k_idx_in_list++;\n            continue;\n        }\n        // Found an uncovered resident that is reachable by current P[station_idx]. Break to process it.\n        break;\n    }\n    next_uncovered_resident_idx_global[station_idx] = current_k_idx_in_list;\n\n    // If we've advanced past all residents for this station that can be covered by current P, return.\n    if (next_uncovered_resident_idx_global[station_idx] >= residents_by_dist_global[station_idx].size()) {\n        return;\n    }\n\n    // Now, process the found resident `k_id` which requires an increase in P.\n    auto& resident_entry = residents_by_dist_global[station_idx][next_uncovered_resident_idx_global[station_idx]];\n    int k_id = resident_entry.second;\n    ftype dist_to_k = resident_entry.first;\n\n    // Calculate the required P to cover this specific resident.\n    int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n    // The new P value must be at least the current P and at least the required P.\n    int new_p_val = std::max(P[station_idx], required_p_int);\n    \n    // Calculate the actual marginal cost for this specific upgrade step.\n    long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[station_idx]) * P[station_idx];\n    \n    // Push this potential upgrade to the PQ.\n    pq.push({actual_marginal_cost, station_idx});\n}\n\n\nstd::vector<int> solve_P_greedy_marginal_cost_pq(const std::vector<int>& V_prime_indices, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> P(N_stations_global, 0);\n    \n    if (K_residents_global == 0) return P; // No residents, no cost.\n\n    // If V_prime is empty and K > 0, coverage is impossible. Return zeros.\n    if (V_prime_indices.empty()) {\n        return P; \n    }\n\n    // Initialize global structures for PQ solver\n    residents_by_dist_global.assign(N_stations_global, std::vector<std::pair<ftype, int>>());\n    next_uncovered_resident_idx_global.assign(N_stations_global, 0);\n    global_resident_covered_global.assign(K_residents_global, false);\n    current_uncovered_count_global = K_residents_global;\n    \n    // Populate residents_by_dist_global and sort for stations in V_prime\n    for (int station_idx : V_prime_indices) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            // Only consider residents potentially coverable within max P (5000)\n            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { \n                residents_by_dist_global[station_idx].push_back({dists_global[station_idx][k], k});\n            }\n        }\n        // Sort residents by distance for this station\n        std::sort(residents_by_dist_global[station_idx].begin(), residents_by_dist_global[station_idx].end());\n        // Initialize next_uncovered_resident_idx_global for this station\n        next_uncovered_resident_idx_global[station_idx] = 0; \n    }\n\n    // Priority queue for upgrades\n    std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>> pq;\n\n    // Initial population of PQ: For each station, find the first resident it needs to cover\n    for (int station_idx : V_prime_indices) {\n        update_coverage_and_pq(station_idx, P, pq); \n    }\n\n    // Greedy loop: While there are uncovered residents and potential upgrades\n    while (current_uncovered_count_global > 0 && !pq.empty()) {\n        StationUpgradeState current_upgrade = pq.top();\n        pq.pop();\n\n        int s = current_upgrade.station_idx;\n        \n        // Re-evaluate: The PQ entry might be stale if P[s] has already increased\n        // or if the target resident is now covered by another station.\n        // Update the station's state to find the *actual* next resident to cover.\n        update_coverage_and_pq(s, P, pq); // This will update next_uncovered_resident_idx_global[s] and push new PQ entry if needed.\n\n        // If update_coverage_and_pq found a new resident or P[s] increased, it pushed to PQ.\n        // We need to ensure that *this* popped element from PQ is still valid for the current state.\n        // The 'current_upgrade.marginal_cost' might be outdated.\n        // The crucial part is that `update_coverage_and_pq` re-calculates based on current P[s].\n        // If the station `s` still needs to cover a resident and `update_coverage_and_pq` successfully pushed a valid state,\n        // then that new state will be processed later.\n        // For the CURRENT popped element, we need to know if it corresponds to the actual next step.\n\n        // The logic in `update_coverage_and_pq` is designed to find the *next* resident.\n        // If it returned, it implies the station `s` might need an upgrade to cover that resident.\n        // The cost pushed is `actual_marginal_cost` for that specific upgrade.\n        // We should apply the upgrade if `current_uncovered_count_global` is still positive.\n\n        // The PQ entry `current_upgrade` represents the cost to cover the resident that was\n        // `residents_by_dist_global[s][next_uncovered_resident_idx_global[s]]` AT THE TIME of pushing.\n        // After `update_coverage_and_pq` called above, `next_uncovered_resident_idx_global[s]` might have advanced.\n        // If the element we popped was for a resident already covered or too far, we simply ignore it.\n\n        // Re-check if the resident the popped entry was intended for is *still* the target and is uncovered.\n        if (next_uncovered_resident_idx_global[s] < residents_by_dist_global[s].size()) {\n            auto& resident_entry = residents_by_dist_global[s][next_uncovered_resident_idx_global[s]];\n            int k_id = resident_entry.second;\n            ftype dist_to_k = resident_entry.first;\n            \n            // If the resident is covered or too far with current P[s], this popped element is stale.\n            if (global_resident_covered_global[k_id] || dist_to_k > P[s] + 1e-9) {\n                // This PQ entry is stale because the resident is already covered or P[s] is already sufficient.\n                // `update_coverage_and_pq` might have already pushed a *new* entry for this station `s`\n                // if P[s] changed, or if `next_uncovered_resident_idx_global[s]` advanced.\n                continue; // Skip processing this stale entry.\n            }\n\n            // If we reach here, the popped entry is relevant, and `next_uncovered_resident_idx_global[s]` points to the uncovered resident.\n            // Calculate the required P and marginal cost based on the current P[s]\n            int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n            int new_p_val = std::max(P[s], required_p_int);\n            long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[s]) * P[s];\n\n            // Apply the upgrade\n            P[s] = new_p_val;\n\n            // Update coverage for all residents potentially covered by the new P[s] starting from this resident.\n            int initial_next_idx = next_uncovered_resident_idx_global[s]; // Start from current target\n            for (int i = initial_next_idx; i < residents_by_dist_global[s].size(); ++i) {\n                auto& current_resident_entry = residents_by_dist_global[s][i];\n                int resident_k_id = current_resident_entry.second;\n                ftype dist_to_resident_k = current_resident_entry.first;\n\n                if (dist_to_resident_k > P[s] + 1e-9) { // Stop if distance exceeds new P[s]\n                    break; \n                }\n\n                if (!global_resident_covered_global[resident_k_id]) {\n                    global_resident_covered_global[resident_k_id] = true;\n                    current_uncovered_count_global--;\n                }\n                // Update the index to the next potential resident for this station\n                next_uncovered_resident_idx_global[s] = i + 1;\n            }\n            \n            // After covering, re-populate PQ for station `s` in case it needs further upgrades.\n            update_coverage_and_pq(s, P, pq);\n        }\n    }\n\n    // Fallback for any remaining uncovered residents if PQ becomes empty but count > 0.\n    // This typically means coverage is impossible or requires very high P.\n    // Set P to 5000 for the closest station in V_prime that can cover it.\n    if (current_uncovered_count_global > 0) {\n        for(int k=0; k<K_residents_global; ++k) {\n            if (!global_resident_covered_global[k]) {\n                ftype min_d = 5001.0;\n                int best_station_idx = -1;\n                for (int station_idx : V_prime_indices) { // Use original V_prime_indices for this fallback\n                    ftype d = dists_global[station_idx][k];\n                    if (d <= 5000.0 + 1e-9) { // Can cover within max radius\n                        if (d < min_d) {\n                            min_d = d;\n                            best_station_idx = station_idx;\n                        }\n                    }\n                }\n                if (best_station_idx != -1) {\n                    // Force coverage by setting P to 5000.\n                    if (P[best_station_idx] < 5000) {\n                        P[best_station_idx] = 5000;\n                    }\n                }\n            }\n        }\n    }\n\n    return P;\n}\n\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> N_stations_global >> M_edges_global >> K_residents_global;\n\n    station_pos_global.resize(N_stations_global);\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cin >> station_pos_global[i].x >> station_pos_global[i].y;\n    }\n\n    edges_global.resize(M_edges_global);\n    for (int i = 0; i < M_edges_global; ++i) {\n        edges_global[i].id = i;\n        std::cin >> edges_global[i].u >> edges_global[i].v >> edges_global[i].w;\n        edges_global[i].u--; // 0-indexed\n        edges_global[i].v--; // 0-indexed\n    }\n\n    residents_global.resize(K_residents_global);\n    for (int i = 0; i < K_residents_global; ++i) {\n        residents_global[i].id = i;\n        std::cin >> residents_global[i].pos.x >> residents_global[i].pos.y;\n    }\n\n    // 1. Precompute all distances\n    dists_global.resize(N_stations_global, std::vector<ftype>(K_residents_global));\n    for (int i = 0; i < N_stations_global; ++i) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            dists_global[i][k] = dist(station_pos_global[i], residents_global[k].pos);\n        }\n    }\n\n    // Sort edges by weight for MST and pruning\n    std::vector<Edge> sorted_edges = edges_global;\n    std::sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    // 2. Initial Connectivity using MST\n    std::vector<int> parent(N_stations_global);\n    std::iota(parent.begin(), parent.end(), 0);\n    auto find_set = [&](auto self, int v) -> int {\n        if (v == parent[v]) return v;\n        return parent[v] = self(self, parent[v]);\n    };\n    auto unite_sets = [&](int a, int b) -> bool {\n        a = find_set(find_set, a);\n        b = find_set(find_set, b);\n        if (a != b) {\n            parent[b] = a;\n            return true;\n        }\n        return false;\n    };\n\n    std::vector<int> B(M_edges_global, 0); // B[j] = 1 if edge j is ON, 0 otherwise\n    int edges_count = 0;\n    if (N_stations_global > 1) { // MST only needed if more than 1 station\n        for (const auto& edge : sorted_edges) {\n            if (unite_sets(edge.u, edge.v)) {\n                B[edge.id] = 1;\n                edges_count++;\n                if (edges_count == N_stations_global - 1) break;\n            }\n        }\n    } \n\n    // 3. Edge Pruning (Iterative Improvement)\n    // This pruning strategy checks if coverage is *feasible* after edge removal.\n    // It does not enforce full connectivity between all N stations.\n    for (const auto& edge_to_consider : sorted_edges) {\n        int edge_id = edge_to_consider.id;\n        if (B[edge_id] == 0) continue; // Edge is already OFF\n\n        // Temporarily remove the edge\n        B[edge_id] = 0;\n\n        // Determine the set of stations reachable from station 0 with the current B\n        std::vector<int> temp_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Check if coverage is feasible with the new V_prime.\n        // Coverage is feasible if every resident can be reached by at least one station\n        // in temp_V_prime_indices within the maximum radius of 5000.\n        bool coverage_feasible_after_prune = true;\n        if (K_residents_global > 0) {\n            if (temp_V_prime_indices.empty()) {\n                coverage_feasible_after_prune = false; // Cannot cover if no stations are reachable\n            } else {\n                for (int k = 0; k < K_residents_global; ++k) {\n                    bool resident_k_can_be_covered = false;\n                    for (int station_idx : temp_V_prime_indices) {\n                        if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { // Max possible coverage radius\n                            resident_k_can_be_covered = true;\n                            break;\n                        }\n                    }\n                    if (!resident_k_can_be_covered) {\n                        coverage_feasible_after_prune = false;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // If coverage is not feasible, restore the edge.\n        if (!coverage_feasible_after_prune) {\n            B[edge_id] = 1; // Restore the edge\n        }\n        // If coverage is feasible, we tentatively keep the edge removed.\n    }\n\n    // 4. Determine the final V_prime set after pruning and assign P values\n    std::vector<int> final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n\n    // Ensure V_prime is not empty if K > 0 by adding the cheapest edge if necessary.\n    if (K_residents_global > 0 && final_V_prime_indices.empty() && N_stations_global > 0) {\n        for (const auto& edge_to_add : sorted_edges) {\n            if (B[edge_to_add.id] == 0) { // If edge is OFF\n                B[edge_to_add.id] = 1; // Turn it ON\n                final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n                break; // Added one edge, sufficient for now.\n            }\n        }\n    }\n    \n    // Assign P values using the optimized PQ solver\n    std::vector<int> P = solve_P_greedy_marginal_cost_pq(final_V_prime_indices, edges_global);\n\n    // 5. Local Search / Iterative Refinement\n    // Reduced iterations for performance.\n    const int LOCAL_SEARCH_ITER = 300; \n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    for(int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        bool improved = false;\n\n        // --- Edge Removal ---\n        // Iterate through edges by increasing weight.\n        std::vector<Edge> edges_to_try_removing = sorted_edges; \n\n        for (const auto& edge_to_consider : edges_to_try_removing) {\n            int edge_id = edge_to_consider.id;\n            if (B[edge_id] == 0) continue; // Already OFF\n\n            // Temporarily remove edge\n            B[edge_id] = 0;\n\n            // Determine new V_prime\n            std::vector<int> next_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n            \n            // Check if coverage is still feasible with the new V_prime.\n            bool coverage_feasible = true;\n            if (K_residents_global > 0) {\n                if (next_V_prime_indices.empty()) {\n                    coverage_feasible = false;\n                } else {\n                    for (int k = 0; k < K_residents_global; ++k) {\n                        bool resident_k_can_be_covered = false;\n                        for (int station_idx : next_V_prime_indices) {\n                            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) {\n                                resident_k_can_be_covered = true;\n                                break;\n                            }\n                        }\n                        if (!resident_k_can_be_covered) {\n                            coverage_feasible = false;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (!coverage_feasible) {\n                B[edge_id] = 1; // Revert edge removal\n                continue;\n            }\n\n            // Re-solve P values for the new V_prime\n            std::vector<int> next_P = solve_P_greedy_marginal_cost_pq(next_V_prime_indices, edges_global);\n            \n            // Verify actual coverage with next_P and next_V_prime_indices (should be guaranteed if feasibility check is perfect and solver is correct)\n            bool actual_coverage_ok = true;\n            if (K_residents_global > 0) {\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    bool k_covered = false;\n                    for(int st_idx_check : next_V_prime_indices) {\n                        if (next_P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= next_P[st_idx_check]) {\n                            k_covered = true;\n                            break;\n                        }\n                    }\n                    if(k_covered) covered_count++;\n                }\n                if (covered_count < K_residents_global) actual_coverage_ok = false;\n            }\n\n            if (actual_coverage_ok) {\n                // Calculate costs: Compare cost *before* removal vs *after* removal.\n                // Cost BEFORE removal: Current P, B with edge_id restored to 1.\n                std::vector<int> B_before_removal = B; // B has edge_id=0\n                B_before_removal[edge_id] = 1; // Temporarily restore edge for cost calc\n                long long cost_before_removal = calculate_total_cost(P, B_before_removal);\n                \n                // Cost AFTER removal: next_P, B with edge_id=0\n                long long cost_after_removal = calculate_total_cost(next_P, B); \n                \n                if (cost_after_removal < cost_before_removal) {\n                    P = next_P; // Update P values\n                    // B is already updated (edge_id is 0)\n                    improved = true;\n                } else {\n                    // Revert the change\n                    B[edge_id] = 1;\n                }\n            } else {\n                // Revert the change if actual coverage is lost\n                B[edge_id] = 1;\n            }\n        }\n        \n        // --- P Value Adjustment ---\n        // Re-calculate current V_prime based on current B state\n        std::vector<int> current_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Only attempt P adjustment if V_prime is not empty OR if there are no residents to cover.\n        if (!current_V_prime_indices.empty() || K_residents_global == 0) {\n            \n            // Try decreasing P of a random station in V_prime that has P > 0\n            int station_to_adjust = -1;\n            if (!current_V_prime_indices.empty()) {\n                std::vector<int> stations_with_p_greater_than_zero;\n                for (int s_idx : current_V_prime_indices) {\n                    if (P[s_idx] > 0) {\n                        stations_with_p_greater_than_zero.push_back(s_idx);\n                    }\n                }\n\n                if (!stations_with_p_greater_than_zero.empty()) {\n                    // Pick one randomly from those with P > 0\n                    station_to_adjust = stations_with_p_greater_than_zero[std::uniform_int_distribution<int>(0, stations_with_p_greater_than_zero.size() - 1)(rng)];\n                }\n            }\n\n            if (station_to_adjust != -1) {\n                int original_P = P[station_to_adjust];\n                P[station_to_adjust]--; // Try decreasing P by 1\n                \n                // Check coverage with the decreased P\n                bool coverage_ok = true;\n                if (K_residents_global > 0) {\n                    int covered_count = 0;\n                    for(int k=0; k<K_residents_global; ++k) {\n                        bool k_covered = false;\n                        for(int st_idx_check : current_V_prime_indices) { // Use the current V_prime\n                            if (P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= P[st_idx_check]) {\n                                k_covered = true;\n                                break;\n                            }\n                        }\n                        if(k_covered) covered_count++;\n                    }\n                    if (covered_count < K_residents_global) coverage_ok = false;\n                }\n                \n                if (coverage_ok) {\n                    // Cost decreased (since P decreased)\n                    improved = true;\n                } else {\n                    // Revert if coverage lost\n                    P[station_to_adjust] = original_P;\n                }\n            }\n        }\n\n        if (!improved) {\n             // If no improvement in an entire iteration, break.\n             break; \n        }\n    }\n\n    // Output final P values and B values\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cout << P[i] << (i == N_stations_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n    for (int j = 0; j < M_edges_global; ++j) {\n        std::cout << B[j] << (j == M_edges_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <map>\n#include <tuple> // For tie-breaking if needed, though struct comparison is sufficient\n\n// Maximum number of tiers\nconst int N = 30;\n// Total number of balls\nconst int M = N * (N + 1) / 2; // M = 465\n\n// Structure to represent coordinates (tier x, position y)\nstruct Coord {\n    int x, y;\n\n    // Operator overloading for map keys and comparisons.\n    // Required for std::map and for determining lexicographical order.\n    bool operator<(const Coord& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Coord& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Useful for tie-breaking in lexicographical order.\n    bool operator>(const Coord& other) const {\n        if (x != other.x) return x > other.x;\n        return y > other.y;\n    }\n};\n\n// Convert pyramid coordinates (x, y) to a linear index.\n// This index serves as the \"target position\" for a ball with a value equal to this index.\n// For example, ball with value 0 should be at (0,0), value 1 at (1,0), value 2 at (1,1), etc.\ninline int get_idx_from_coord(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Define relative coordinates for the 6 possible adjacent moves.\n// These correspond to the adjacency rules given in the problem statement.\n// Order:\n// (dx[0], dy[0]) = (1, 0) : (x+1, y)   (Down-Left)\n// (dx[1], dy[1]) = (1, 1) : (x+1, y+1) (Down-Right)\n// (dx[2], dy[2]) = (0, 1) : (x, y+1)   (Right)\n// (dx[3], dy[3]) = (0,-1) : (x, y-1)   (Left)\n// (dx[4], dy[4]) = (-1,0) : (x-1, y)   (Up-Left)\n// (dx[5], dy[5]) = (-1,1) : (x-1, y+1) (Up-Right)\nint dx[] = {1, 1, 0, 0, -1, -1}; // change in x\nint dy[] = {0, 1, 1, -1, 0, 1}; // change in y\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Map to store the current value of the ball at a given coordinate.\n    // Key: Coord, Value: ball_value\n    std::map<Coord, int> current_values_map;\n    \n    // Vector to store all valid coordinates in the pyramid.\n    // Populated in order: (0,0), (1,0), (1,1), (2,0), (2,1), (2,2), ...\n    // This order ensures deterministic iteration through all cells and facilitates tie-breaking.\n    std::vector<Coord> all_coords;\n    all_coords.reserve(M);\n\n    // Read input and populate the initial state of the pyramid.\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            Coord c = {x, y};\n            all_coords.push_back(c);\n            int value;\n            std::cin >> value;\n            current_values_map[c] = value;\n        }\n    }\n\n    // Store the sequence of performed swaps.\n    // Each swap is a pair of adjacent coordinates.\n    std::vector<std::pair<Coord, Coord>> swaps;\n    const int MAX_SWAPS = 10000; // Maximum allowed operations.\n\n    // Heuristic strategy:\n    // This problem is NP-hard, so we employ a greedy heuristic.\n    // The target configuration is one where each ball with value `v` is located at\n    // coordinate `c` such that `get_idx_from_coord(c.x, c.y) == v`.\n    // This configuration guarantees the condition V(x,y) < V(x+1,y) and V(x,y) < V(x+1,y+1).\n    //\n    // In each step (up to MAX_SWAPS operations), we find the single best adjacent swap.\n    // The \"best\" swap is defined as one that maximizes the reduction in the total absolute error.\n    // The total absolute error is the sum of |target_index - current_value| for all balls.\n    // A swap is only considered if it moves a ball with a larger value to a position\n    // that should ideally hold a larger index (i.e., resolves an inversion where idx1 < idx2 but val1 > val2).\n    // If multiple swaps yield the same maximum benefit, we choose the one that is\n    // lexicographically smallest in terms of the coordinate pair (c1, c2), where c1 is\n    // the \"left/up\" ball and c2 is the \"right/down\" ball (idx(c1) < idx(c2)).\n\n    for (int k = 0; k < MAX_SWAPS; ++k) {\n        // Variables to track the best swap found in this iteration.\n        // Initialize max_benefit to a very small number. We are interested in non-negative benefits.\n        long long max_benefit = -2e18; \n        Coord best_c1 = {-1, -1}, best_c2 = {-1, -1}; // Initialize to invalid coordinates.\n\n        // Iterate through all balls (c1) and their potential neighbors (c2).\n        // `all_coords` is iterated in lexicographical order.\n        for (const auto& c1 : all_coords) { \n            int val1 = current_values_map.at(c1);\n            int idx1 = get_idx_from_coord(c1.x, c1.y);\n\n            // Check each of the 6 possible adjacent neighbors of c1.\n            for (int i = 0; i < 6; ++i) {\n                Coord c2 = {c1.x + dx[i], c1.y + dy[i]};\n\n                // Validate if the neighbor coordinate c2 is within the pyramid boundaries.\n                if (c2.x < 0 || c2.x >= N || c2.y < 0 || c2.y > c2.x) {\n                    continue; // c2 is outside the pyramid.\n                }\n\n                int val2 = current_values_map.at(c2);\n                int idx2 = get_idx_from_coord(c2.x, c2.y);\n\n                // We are only interested in swaps that fix an \"inversion\" according to the target index.\n                // An inversion exists if c1 should have a smaller index than c2 (idx1 < idx2),\n                // but c1 currently holds a larger value than c2 (val1 > val2).\n                // Swapping these would move a smaller value towards a smaller index, and a larger value\n                // towards a larger index, thus reducing the total absolute error.\n                if (idx1 < idx2 && val1 > val2) {\n                    // Calculate the benefit of swapping c1 and c2.\n                    // Benefit is defined as the reduction in the sum of absolute errors:\n                    // Total Error = Sum over all balls v of | target_idx(pos[v]) - v |\n                    // current_error_sum = |idx1 - val1| + |idx2 - val2|\n                    // new_error_sum     = |idx1 - val2| + |idx2 - val1|  (after swapping val1 and val2)\n                    // benefit           = current_error_sum - new_error_sum\n                    long long current_error_sum = std::abs((long long)idx1 - val1) + std::abs((long long)idx2 - val2);\n                    long long new_error_sum = std::abs((long long)idx1 - val2) + std::abs((long long)idx2 - val1);\n                    long long benefit = current_error_sum - new_error_sum;\n\n                    // Update `best_c1`, `best_c2`, and `max_benefit` if this swap is better.\n                    // Selection criteria:\n                    // 1. Maximize the benefit. We require `benefit >= 0`. A benefit of 0 means\n                    //    the total error sum doesn't decrease, but the swap might still resolve\n                    //    an inversion and potentially reduce direct violations (E), or help reach MAX_SWAPS.\n                    // 2. If benefits are equal, choose the lexicographically smaller coordinate pair (c1, c2).\n                    //    The iteration order ensures that the first encountered pair for a given\n                    //    benefit is the lexicographically smallest. Thus, we update only if the current\n                    //    pair (c1, c2) is strictly smaller than the current `(best_c1, best_c2)`.\n                    \n                    if (benefit > max_benefit) {\n                        max_benefit = benefit;\n                        best_c1 = c1;\n                        best_c2 = c2;\n                    } else if (benefit == max_benefit) {\n                        // Tie-breaking: select the lexicographically smaller coordinate pair (c1, c2).\n                        if (c1 < best_c1 || (c1 == best_c1 && c2 < best_c2)) {\n                             best_c1 = c1;\n                             best_c2 = c2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // If a beneficial swap was found (best_c1 is valid and max_benefit >= 0),\n        // and we haven't reached the maximum allowed number of swaps:\n        if (best_c1.x != -1 && max_benefit >= 0) {\n            // Apply the selected best swap.\n            std::swap(current_values_map.at(best_c1), current_values_map.at(best_c2));\n            // Record the swap operation.\n            swaps.push_back({best_c1, best_c2});\n        } else {\n            // No swap found with non-negative benefit, or we have already performed MAX_SWAPS (implicit in k loop condition).\n            // In this case, we cannot improve further with this greedy strategy, so we stop.\n            break;\n        }\n    }\n\n    // Output the total number of operations performed.\n    std::cout << swaps.size() << std::endl;\n    // Output each swap operation in the specified format.\n    for (const auto& sw : swaps) {\n        std::cout << sw.first.x << \" \" << sw.first.y << \" \" << sw.second.x << \" \" << sw.second.y << std::endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions and properties\nconst int MAX_D = 9; // D is fixed at 9 for all test cases\nint D;\nbool is_obstacle[MAX_D][MAX_D];\nint dist[MAX_D][MAX_D];\npair<int, int> entrance;\n\n// Directions for BFS: North, East, South, West\n// These correspond to changes in (row, column) coordinates.\nint dr[] = {-1, 0, 1, 0};\nint dc[] = {0, 1, 0, -1};\n\n// Structure to hold cell information: row, column, and its shortest distance from the entrance.\n// This is used for sorting storage locations.\nstruct CellInfo {\n    int r, c, d;\n\n    // Custom comparison operator for sorting:\n    // 1. Primarily by distance (ascending).\n    // 2. Secondarily by row index (ascending).\n    // 3. Tertiarily by column index (ascending).\n    bool operator<(const CellInfo& other) const {\n        if (d != other.d) {\n            return d < other.d;\n        }\n        if (r != other.r) {\n            return r < other.r;\n        }\n        return c < other.c;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming performance.\n    // `ios_base::sync_with_stdio(false)` unties C++ streams from C stdio.\n    // `cin.tie(NULL)` unties cin from cout, meaning cin operations do not force cout to flush.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N; // Number of obstacles\n    cin >> D >> N;\n\n    // Set entrance coordinates (0-indexed). D is always 9, so (D-1)/2 is 4.\n    entrance = {0, (D - 1) / 2};\n\n    // Initialize grid properties: mark all cells as not an obstacle and unreachable initially.\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            is_obstacle[i][j] = false;\n            dist[i][j] = -1; // -1 indicates unreachable or unvisited\n        }\n    }\n\n    // Read and mark obstacle locations.\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    // --- BFS to calculate shortest distances ---\n    // We perform a Breadth-First Search starting from the entrance to find the shortest\n    // path distance to all reachable non-obstacle cells.\n    queue<pair<int, int>> q;\n\n    // The entrance is guaranteed not to be an obstacle.\n    dist[entrance.first][entrance.second] = 0;\n    q.push(entrance);\n\n    // This vector will store information about all reachable cells (including the entrance)\n    // along with their distances.\n    vector<CellInfo> all_reachable_cells;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n\n        // Add the current cell to our list of reachable cells.\n        all_reachable_cells.push_back({r, c, dist[r][c]});\n\n        // Explore neighbors in all four directions.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid bounds, is not an obstacle, and has not been visited yet.\n            if (nr >= 0 && nr < D && nc >= 0 && nc < D && !is_obstacle[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1; // Distance is one more than the current cell's distance.\n                q.push({nr, nc}); // Add the neighbor to the queue for exploration.\n            }\n        }\n    }\n\n    // --- Sorting Storage Locations ---\n    // The problem states that containers are stored in squares other than the entrance and obstacles.\n    // The total number of containers is M = D*D - 1 - N. These will occupy M storage locations.\n    // We need to sort these storage locations based on their proximity to the entrance to establish an order.\n    vector<CellInfo> sorted_storage_locs;\n    for (const auto& cell : all_reachable_cells) {\n        // The entrance cell itself is not a storage location, so we skip it.\n        if (cell.r == entrance.first && cell.c == entrance.second) {\n            continue;\n        }\n        sorted_storage_locs.push_back(cell);\n    }\n\n    // Sort the storage locations using the custom comparison operator defined in CellInfo.\n    // This ensures they are ordered by distance, then row, then column.\n    sort(sorted_storage_locs.begin(), sorted_storage_locs.end());\n\n    // Calculate the total number of containers to be stored.\n    int num_containers = D * D - 1 - N;\n\n    // --- Container Placement Phase ---\n    // This phase handles the arrival of containers one by one.\n    // For each arriving container, we decide where to store it.\n    // Our strategy: The d-th container to arrive (with ID t_d) is placed in the d-th location\n    // from our sorted list of storage locations (`sorted_storage_locs`). This greedy approach aims\n    // to keep containers with smaller target retrieval IDs in \"closer\" or more accessible locations.\n    \n    // We need to record the arrival order for each container ID.\n    // `container_arrival_idx[container_id]` will store the index `d` (0 to num_containers-1)\n    // representing the order in which `container_id` arrived and was placed.\n    vector<int> container_arrival_idx(num_containers); \n\n    for (int d = 0; d < num_containers; ++d) {\n        int container_id; // The ID of the container arriving at step d.\n        cin >> container_id;\n\n        // The d-th arriving container is placed at the d-th location in our sorted list.\n        CellInfo current_storage_loc = sorted_storage_locs[d];\n        pair<int, int> pos = {current_storage_loc.r, current_storage_loc.c};\n        \n        // Output the chosen storage location (row and column) for this container.\n        cout << pos.first << \" \" << pos.second << endl;\n        // `endl` typically flushes the output buffer in C++ streams, which is required.\n        \n        // Record that `container_id` arrived at step `d` and was assigned to `sorted_storage_locs[d]`.\n        // This means container_id is stored at the d-th closest available slot.\n        container_arrival_idx[container_id] = d; \n    }\n\n    // --- Container Retrieval Phase ---\n    // After all containers are stored, we need to determine the order in which they are transported out.\n    // The goal is to minimize the number of inversions in the retrieval sequence `b_0, b_1, ..., b_{M-1}`.\n    // This is achieved by aiming for the sorted sequence `0, 1, ..., M-1`.\n    // Our placement strategy (d-th arrival at d-th closest slot) allows for this.\n    // Container `k` is placed at `sorted_storage_locs[container_arrival_idx[k]]`.\n    // By retrieving containers in increasing order of their IDs (0, 1, 2, ...), we can achieve minimal inversions.\n    // Container `k` can be retrieved at step `k` because its location is guaranteed to be reachable.\n    // All containers `0, ..., k-1` are retrieved before container `k`, making their locations empty.\n    // The entire storage area is connected to the entrance, ensuring reachability.\n    \n    for (int k = 0; k < num_containers; ++k) {\n        // We want to retrieve container with ID `k` at step `k` of the retrieval sequence.\n        // Find out which storage slot `d` this container `k` was assigned to based on its arrival order.\n        int d = container_arrival_idx[k]; \n        \n        // The location of container `k` is the d-th sorted storage location.\n        CellInfo retrieved_cell = sorted_storage_locs[d];\n        pair<int, int> pos = {retrieved_cell.r, retrieved_cell.c};\n        \n        // Output the coordinates of the container to be transported out at this step.\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> initial_grid;\nvector<vector<int>> output_grid; // -1: unassigned, 0..m: assigned color\nvector<vector<bool>> adj;\nvector<pair<int, int>> dx = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n// Checks if assigning color 'color_to_assign' to a cell is valid\n// given the colors of its already assigned neighbors.\n// 'neighbor_colors' is a set of colors of already assigned neighbors of the cell.\nbool is_valid(int color_to_assign, const set<int>& neighbor_colors) {\n    for (int neighbor_color : neighbor_colors) {\n        if (color_to_assign != neighbor_color) {\n            if (!adj[min(color_to_assign, neighbor_color)][max(color_to_assign, neighbor_color)]) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> n >> m;\n\n    initial_grid.resize(n, vector<int>(n));\n    output_grid.resize(n, vector<int>(n, -1)); // Initialize all cells as unassigned (-1)\n\n    // Store first occurrence of each color (1 to m) as a seed\n    vector<pair<int, int>> seeds(m + 1, {-1, -1});\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> initial_grid[i][j];\n            if (initial_grid[i][j] >= 1 && initial_grid[i][j] <= m) {\n                if (seeds[initial_grid[i][j]].first == -1) {\n                    seeds[initial_grid[i][j]] = {i, j};\n                }\n            }\n        }\n    }\n\n    // Compute adjacency matrix for colors 0 to m\n    adj.resize(m + 1, vector<bool>(m + 1, false));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = initial_grid[i][j];\n            if (c1 != 0) { // Only check adjacencies for non-zero colors in the input\n                for (auto& move : dx) {\n                    int ni = i + move.first;\n                    int nj = j + move.second;\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int c2 = initial_grid[ni][nj];\n                        if (c1 != c2) {\n                            adj[min(c1, c2)][max(c1, c2)] = true;\n                        }\n                    } else { // Neighbor is outside the grid, which means it's adjacent to color 0\n                        adj[min(c1, 0)][max(c1, 0)] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // BFS queue stores cells to process. We prioritize processing non-zero colors.\n    queue<pair<int, int>> q;\n\n    // Seed the grid with initial colors and add them to the queue\n    // Priority is given to non-zero colors.\n    for (int k = 1; k <= m; ++k) {\n        if (seeds[k].first != -1) {\n            int r = seeds[k].first;\n            int c = seeds[k].second;\n            if (output_grid[r][c] == -1) { // If cell is unassigned\n                output_grid[r][c] = k;\n                q.push({r, c});\n            }\n        }\n    }\n\n    // Initialize color 0 for cells that are initially 0 and on the border,\n    // or if the input color was 0. These ensure color 0 connectivity.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (initial_grid[i][j] == 0) {\n                if (output_grid[i][j] == -1) { // If unassigned and input was 0\n                    output_grid[i][j] = 0;\n                    // We don't push color 0 to the queue because color 0 expansion is implicit\n                    // and doesn't drive the assignment of non-zero colors.\n                    // However, if 0 is the *only* color assigned initially (e.g. all 0s input),\n                    // we might need to seed it if it's a border cell.\n                }\n            }\n        }\n    }\n    // Ensure border cells that are unassigned default to 0.\n    for (int i = 0; i < n; ++i) {\n        if (output_grid[i][0] == -1) { output_grid[i][0] = 0; }\n        if (output_grid[i][n-1] == -1) { output_grid[i][n-1] = 0; }\n    }\n    for (int j = 0; j < n; ++j) {\n        if (output_grid[0][j] == -1) { output_grid[0][j] = 0; }\n        if (output_grid[n-1][j] == -1) { output_grid[n-1][j] = 0; }\n    }\n\n\n    // BFS to fill the grid\n    // The queue `q` primarily contains seeds of non-zero colors.\n    // When a non-zero cell expands, it decides the color of its unassigned neighbors.\n    while (!q.empty()) {\n        pair<int, int> current_cell = q.front();\n        q.pop();\n        int r = current_cell.first;\n        int c = current_cell.second;\n        int current_color = output_grid[r][c];\n\n        for (auto& move : dx) {\n            int nr = r + move.first;\n            int nc = c + move.second;\n\n            if (nr >= 0 && nr < n && nc >= 0 && nc < n) {\n                if (output_grid[nr][nc] == -1) { // If neighbor is unassigned\n                    // Collect colors of already assigned neighbors of (nr, nc)\n                    set<int> neighbor_colors;\n                    for (auto& next_move : dx) {\n                        int nnr = nr + next_move.first;\n                        int nnc = nc + next_move.second;\n                        if (nnr >= 0 && nnr < n && nnc >= 0 && nnc < n) {\n                            if (output_grid[nnr][nnc] != -1) { // Collect colors of assigned neighbors\n                                neighbor_colors.insert(output_grid[nnr][nnc]);\n                            }\n                        }\n                    }\n\n                    int color_to_assign = -1;\n\n                    // Strategy:\n                    // 1. Try to assign color 0 if it's valid.\n                    // 2. If 0 is not valid, try to assign a non-zero color K.\n                    //    - Prioritize K if it's required by `current_color` (i.e., `adj[current_color][K]` is true).\n                    //    - If multiple such K exist, pick the smallest.\n                    //    - If no prioritized K is found, pick the smallest valid K.\n\n                    bool can_be_zero = is_valid(0, neighbor_colors);\n\n                    if (can_be_zero) {\n                        // Color 0 is valid. We prefer it to maximize score.\n                        // Assigning 0 means it remains 0 (since output_grid[nr][nc] was -1, and now becomes 0).\n                        // We do not push 0 to the queue as its expansion is implicit.\n                        color_to_assign = 0;\n                    } else {\n                        // Color 0 is NOT valid. We MUST assign a non-zero color.\n                        int best_k = -1;\n\n                        // First, try to find a K required by current_color\n                        if (current_color != 0) { // current_color is non-zero, check its adjacencies\n                            for (int k = 1; k <= m; ++k) {\n                                if (adj[min(current_color, k)][max(current_color, k)]) { // k is required by current_color\n                                    if (is_valid(k, neighbor_colors)) { // k is valid for this cell\n                                        best_k = k; // Found a candidate K\n                                        break; // Prioritize first such K\n                                    }\n                                }\n                            }\n                        }\n\n                        // If no prioritized K was found, find any valid non-zero color K\n                        if (best_k == -1) {\n                            for (int k = 1; k <= m; ++k) {\n                                if (is_valid(k, neighbor_colors)) {\n                                    best_k = k;\n                                    break; // Found first valid non-zero color K\n                                }\n                            }\n                        }\n                        color_to_assign = best_k;\n                    }\n\n                    // Assign the determined color and enqueue if it's non-zero.\n                    if (color_to_assign != -1) {\n                        output_grid[nr][nc] = color_to_assign;\n                        if (color_to_assign != 0) { // Only push non-zero colors to the queue\n                            q.push({nr, nc});\n                        }\n                    } else {\n                        // This case implies that no color (0 or 1..m) could be validly assigned.\n                        // This could happen if the problem constraints are impossible for this heuristic,\n                        // or if the seeding/expansion order leads to a dead end.\n                        // For a contest, leaving it as -1 and filling later might be an option,\n                        // but the problem implies a solution exists. We assume best_k is found if !can_be_zero.\n                        // As a fallback, we might assign 0 if it was valid but not preferred, or if problem implies any solution is fine.\n                        // However, the logic implies if !can_be_zero, then best_k MUST be found.\n                        // If it's not found, the strategy fails.\n                        // Given the scoring and heuristic nature, this state is unlikely if adjacencies are feasible.\n                    }\n                }\n            }\n        }\n    }\n\n    // Final pass: Fill any remaining unassigned cells (-1) with color 0.\n    // This ensures connectivity of color 0 and maximizes the score.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (output_grid[i][j] == -1) {\n                output_grid[i][j] = 0;\n            }\n        }\n    }\n\n    // Print the output grid\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << output_grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Use a large value for infinity in distance calculations.\n// Given N <= 100, a path length is at most N-1. Max difference per step is 1.\n// So N+5 should be sufficiently large for INF.\nconst long long INF = 1e18; \n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, d, q;\n    cin >> n >> d >> q;\n\n    // Stores the result of pairwise comparisons:\n    // comparison[i][j] = 1 if w_i < w_j\n    // comparison[i][j] = -1 if w_i > w_j\n    // comparison[i][j] = 0 if w_i = w_j\n    // comparison[i][j] = 2 if unknown\n    vector<vector<int>> comparison(n, vector<int>(n, 2));\n\n    int queries_budget = q;\n    int current_queries = 0;\n\n    // Phase 1: Prioritize comparisons between items with small index differences.\n    // This helps establish local relationships and might reveal structured weight distributions.\n    // We check differences from 1 up to a certain limit. The limit is capped by N/2\n    // to avoid redundant checks (e.g., diff=1 queries (0,1), (1,2), ..., (N-1,0). diff=N-1 queries (0,N-1), etc. which are inverse of diff=1).\n    // Also, cap the number of differences to check to not exceed Q.\n    int max_diff_to_check = min(10, n / 2); \n\n    for (int diff = 1; diff <= max_diff_to_check; ++diff) {\n        if (current_queries >= queries_budget) break;\n        for (int i = 0; i < n; ++i) {\n            if (current_queries >= queries_budget) break;\n            int j = (i + diff) % n; // Circular index difference\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1; // Symmetric relation\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1; // Symmetric relation\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0; // Symmetric relation\n                }\n            }\n        }\n    }\n    \n    // Phase 2: If budget remains, query arbitrary pairs (i, j) with i < j.\n    // This strategy aims to gather as many direct pairwise comparisons as possible.\n    for (int i = 0; i < n; ++i) {\n        if (current_queries >= queries_budget) break;\n        for (int j = i + 1; j < n; ++j) { // Iterate through unique pairs (i, j) with i < j\n            if (current_queries >= queries_budget) break;\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1;\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1;\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0;\n                }\n            }\n        }\n    }\n\n    // Initialize distance matrix for Floyd-Warshall algorithm.\n    // dist[i][j] will store the minimum possible value of (w_i - w_j).\n    // Weights w_i are positive integers (>= 1).\n    // If w_i < w_j, then w_i - w_j <= -1. The minimum possible difference is -1.\n    // If w_i > w_j, then w_i - w_j >= 1. The minimum possible difference is 1.\n    // If w_i = w_j, then w_i - w_j = 0.\n    vector<vector<long long>> dist(n, vector<long long>(n));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (i == j) {\n                dist[i][j] = 0; // Distance to self is 0\n            } else if (comparison[i][j] == 1) { // w_i < w_j => w_i - w_j <= -1\n                dist[i][j] = -1;\n            } else if (comparison[i][j] == -1) { // w_i > w_j => w_i - w_j >= 1\n                dist[i][j] = 1;\n            } else if (comparison[i][j] == 0) { // w_i = w_j\n                dist[i][j] = 0;\n            } else { // Unknown relationship\n                dist[i][j] = INF; // Initialize with infinity\n            }\n        }\n    }\n\n    // Run Floyd-Warshall to compute all-pairs shortest paths (minimum differences).\n    // This step integrates all pairwise comparisons to infer transitive relationships.\n    for (int k = 0; k < n; ++k) { // Intermediate node\n        for (int i = 0; i < n; ++i) { // Source node\n            for (int j = 0; j < n; ++j) { // Destination node\n                // If paths through k are possible, update distance\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    // Estimate weights based on the computed differences.\n    // We use dist[0][i] which represents the minimum inferred difference w_0 - w_i.\n    // So, w_i = w_0 + dist[0][i].\n    // To get an estimate of w_i's magnitude, we can use -dist[0][i] as a proxy.\n    // If dist[0][i] is -5, it implies w_i is roughly 5 units heavier than w_0. So -dist[0][i] = 5.\n    // If dist[0][i] is 3, it implies w_i is roughly 3 units lighter than w_0. So -dist[0][i] = -3.\n    // This gives a relative ordering.\n    vector<pair<long long, int>> estimated_weights(n);\n    long long min_estimated_val = 0; // To find the minimum estimated value for shifting\n    \n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i] = {-dist[0][i], i}; // Use -dist[0][i] as estimated weight\n        min_estimated_val = min(min_estimated_val, estimated_weights[i].first);\n    }\n\n    // Shift the estimated weights so that the minimum weight is 1.\n    // This ensures all estimated weights are positive integers, respecting the problem's constraint.\n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i].first = estimated_weights[i].first - min_estimated_val + 1;\n    }\n\n    // Sort items by their estimated weights in descending order.\n    // This is for the Largest Processing Time (LPT) heuristic, commonly used for multiway number partitioning.\n    sort(estimated_weights.rbegin(), estimated_weights.rend());\n\n    // Partitioning phase using the LPT heuristic.\n    // We want to assign items to 'd' bins such that the sum of weights in each bin is as equal as possible.\n    vector<long long> bin_sums(d, 0); // Stores the current total estimated weight for each bin\n    vector<int> assignment(n);       // Stores the final bin assignment for each item\n\n    for (const auto& item_pair : estimated_weights) {\n        long long weight = item_pair.first; // Estimated weight of the current item\n        int item_idx = item_pair.second;    // Original index of the item\n\n        // Find the bin with the minimum current sum of weights.\n        int best_bin = 0;\n        for (int b = 1; b < d; ++b) {\n            if (bin_sums[b] < bin_sums[best_bin]) {\n                best_bin = b;\n            }\n        }\n\n        // Assign the current item to the bin with the minimum sum.\n        assignment[item_idx] = best_bin;\n        bin_sums[best_bin] += weight; // Update the sum for this bin\n    }\n\n    // Output the final assignment of items to bins.\n    for (int i = 0; i < n; ++i) {\n        cout << assignment[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\n// Use 1-based indexing for boxes, 0-based for internal stack indices.\n// Output requires 1-based indexing for stacks.\n\nstruct BoxLocation {\n    int stack_idx; // 0-indexed\n    int pos_in_stack; // 0-indexed from bottom\n};\n\n// Global variables to store state\nstd::vector<std::vector<int>> stacks;\nstd::vector<BoxLocation> box_locations;\nstd::vector<bool> is_carried_out;\nint n_boxes, m_stacks;\nint next_box_to_carry_id = 1;\nstd::vector<std::pair<int, int>> operations; // pair {box_id, destination_stack_idx+1 or 0}\n\n// Helper to update box_locations after a stack modification\nvoid update_box_locations_in_stack(int stack_idx, const std::vector<int>& stack_content) {\n    for (int i = 0; i < stack_content.size(); ++i) {\n        int box_id = stack_content[i];\n        box_locations[box_id] = {stack_idx, i};\n    }\n}\n\n// Function to perform operation 1\n// Moves the block starting from `v_id` (and everything above it) from its current stack\n// to `dest_stack_idx`. The `v_id` is the box that initiates the move, as per problem statement.\nvoid perform_move_operation(int v_id, int dest_stack_idx) {\n    int src_stack_idx = box_locations[v_id].stack_idx;\n    int v_pos_in_src_stack = box_locations[v_id].pos_in_stack;\n    \n    std::vector<int>& src_stack = stacks[src_stack_idx];\n\n    // The block to move starts at v_id and goes to the top of the current stack.\n    int start_move_pos = v_pos_in_src_stack;\n    \n    std::vector<int> block_to_move;\n    for (int i = start_move_pos; i < src_stack.size(); ++i) {\n        block_to_move.push_back(src_stack[i]);\n    }\n    \n    // The first element of block_to_move is the box `v` for the operation.\n    // In this strategy, v_id is always `next_box_to_carry_id`, which is block_to_move[0].\n    // int op_v_id = block_to_move[0]; // This is guaranteed to be v_id in our strategy.\n\n    // Output operation (v_id, dest_stack_idx + 1). dest_stack_idx is 0-indexed.\n    operations.push_back({v_id, dest_stack_idx + 1});\n\n    // Update source stack: remove the block\n    src_stack.resize(start_move_pos);\n    // Update locations for boxes remaining in source stack\n    update_box_locations_in_stack(src_stack_idx, src_stack);\n\n    // Update destination stack: add the block\n    auto& dest_stack = stacks[dest_stack_idx];\n    for (int box_id : block_to_move) {\n        dest_stack.push_back(box_id);\n        box_locations[box_id] = {dest_stack_idx, dest_stack.size() - 1};\n    }\n}\n\nvoid solve() {\n    std::cin >> n_boxes >> m_stacks;\n\n    stacks.resize(m_stacks);\n    // box_locations will store {stack_idx, pos_in_stack} for each box ID (1 to n_boxes).\n    // Initialize with invalid values or resize as needed. Size n_boxes + 1 for 1-based indexing.\n    box_locations.resize(n_boxes + 1); \n\n    for (int i = 0; i < m_stacks; ++i) {\n        int num_boxes_in_stack = n_boxes / m_stacks; // Problem constraint\n        stacks[i].resize(num_boxes_in_stack);\n        for (int j = 0; j < num_boxes_in_stack; ++j) {\n            std::cin >> stacks[i][j];\n            // Record initial location for each box\n            box_locations[stacks[i][j]] = {i, j};\n        }\n    }\n\n    is_carried_out.resize(n_boxes + 1, false);\n\n    // Main loop: process boxes 1 to n in order.\n    while (next_box_to_carry_id <= n_boxes) {\n        int current_box_id = next_box_to_carry_id;\n        int src_stack_idx = box_locations[current_box_id].stack_idx;\n        int pos_in_stack = box_locations[current_box_id].pos_in_stack;\n        std::vector<int>& current_stack = stacks[src_stack_idx];\n\n        // Check if the current box is at the top of its stack\n        if (pos_in_stack == current_stack.size() - 1) { \n            // Operation 2: Carry out the box\n            operations.push_back({current_box_id, 0}); // 0 signifies carry-out\n            is_carried_out[current_box_id] = true;\n            current_stack.pop_back();\n            \n            // Update locations for any boxes that might have been affected (none in this case, as no boxes were above)\n            // For safety, call update on the stack, though pop_back doesn't shift elements' indices.\n            update_box_locations_in_stack(src_stack_idx, current_stack);\n            \n            next_box_to_carry_id++; // Move to the next box\n        } else { \n            // Operation 1 is required because `current_box_id` is NOT at the top.\n            // Heuristic for choosing destination stack:\n            // 1. Prefer an empty stack with the smallest index.\n            // 2. If no empty stacks exist, prefer a non-empty stack whose top element is MINIMIZED.\n            //    If there's a tie in minimum top element, pick the stack with the smallest index.\n            \n            int dest_stack_idx = -1;\n            int min_top_val = -1; // Sentinel for \"no suitable non-empty stack found yet\"\n            bool found_empty_stack = false;\n\n            for (int i = 0; i < m_stacks; ++i) {\n                if (i == src_stack_idx) continue; // Cannot move to the same stack.\n\n                if (stacks[i].empty()) {\n                    if (!found_empty_stack) { // Found the first empty stack\n                        dest_stack_idx = i;\n                        found_empty_stack = true;\n                    }\n                    // If multiple empty stacks, `dest_stack_idx` will naturally hold the smallest index encountered first.\n                } else { // Stack `i` is not empty\n                    if (!found_empty_stack) { // Only consider non-empty stacks if no empty ones were found\n                        int top_val = stacks[i].back();\n                        if (min_top_val == -1 || top_val < min_top_val) {\n                            min_top_val = top_val;\n                            dest_stack_idx = i;\n                        } else if (top_val == min_top_val) {\n                            // Tie-breaking: prefer smaller index\n                            if (i < dest_stack_idx) {\n                                dest_stack_idx = i;\n                            }\n                        }\n                    }\n                }\n            }\n\n            // Fallback: If for some reason dest_stack_idx wasn't set (e.g., m=1, which is not the case here),\n            // pick the first available stack other than the source.\n            if (dest_stack_idx == -1) {\n                 for(int i = 0; i < m_stacks; ++i) {\n                     if (i != src_stack_idx) {\n                         dest_stack_idx = i;\n                         break;\n                     }\n                 }\n            }\n\n            // Perform the move operation. The box initiating the move (v_id) is `current_box_id`.\n            perform_move_operation(current_box_id, dest_stack_idx);\n            \n            // `next_box_to_carry_id` does NOT increment because `current_box_id` is still not at the top\n            // of its NEW stack after the move. The loop will repeat for `current_box_id` again.\n        }\n    }\n\n    // Output all recorded operations\n    for (const auto& op : operations) {\n        std::cout << op.first << \" \" << op.second << \"\\n\";\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n    \n    solve();\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\nint N;\nvector<string> h_walls, v_walls;\nvector<vector<int>> d;\n\n// Adjacency list for grid graph\n// Stores pairs of {neighbor_row, neighbor_col, move_char, wall_type}\n// wall_type: 0 for no wall, 1 for horizontal wall, 2 for vertical wall\n// This information is not strictly needed if we check walls dynamically,\n// but could be useful for pathfinding. For this problem, we check walls directly.\nvector<pair<int, int>> adj[40][40];\n\nint dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar moves[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (r, c) to (nr, nc) is valid (no wall)\nbool is_valid_move(int r, int c, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n        return false;\n    }\n    if (nr == r - 1) { // Moving Up\n        if (v_walls[r][c] == '1') return false;\n    } else if (nr == r + 1) { // Moving Down\n        if (h_walls[r][c] == '1') return false;\n    } else if (nc == c - 1) { // Moving Left\n        if (v_walls[r][c-1] == '1') return false;\n    } else if (nc == c + 1) { // Moving Right\n        if (v_walls[r][c] == '1') return false;\n    }\n    return true;\n}\n\n// DFS to generate an initial path that visits all nodes\nstring initial_path_str;\nbool visited_dfs[40][40];\nint initial_path_len = 0;\nmap<pair<int, int>, int> visit_counts_dfs;\n\nvoid dfs_generate(int r, int c) {\n    visited_dfs[r][c] = true;\n    visit_counts_dfs[{r, c}]++;\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited_dfs[nr][nc]) {\n            if (is_valid_move(r, c, nr, nc)) {\n                initial_path_str += moves[i];\n                initial_path_len++;\n                dfs_generate(nr, nc);\n                initial_path_str += moves[i ^ 1]; // Move back\n                initial_path_len++;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[i];\n\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Build adjacency list implicitly by checking walls in is_valid_move\n    // DFS to generate initial path\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_dfs[i][j] = false;\n        }\n    }\n    dfs_generate(0, 0);\n    \n    // Ensure (0,0) is visited twice if DFS starts/ends there\n    // The DFS logic above adds return moves, so (0,0) is visited at start and end\n    // If initial_path_len is 0 (e.g. 1x1 grid, though N>=20), handle it.\n    if (N > 0 && initial_path_len == 0) { // For N=1, this might happen. But N>=20.\n        // If grid is just one cell (0,0), path is empty, length 0.\n        // But problem says N>=20. So DFS should generate a path.\n    }\n\n\n    // Target visit counts proportional to sqrt(d_i,j)\n    // Minimize sum( d_i,j / N_i,j^2 )\n    // Equivalent to maximizing sum( d_i,j / N_i,j^2 )\n    // For total visits V, N_i,j should be proportional to sqrt(d_i,j)\n    // N_i,j = C * sqrt(d_i,j)\n    // Sum(N_i,j) = V => C = V / Sum(sqrt(d_i,j))\n    // N_i,j = V * sqrt(d_i,j) / Sum(sqrt(d_k,m))\n\n    // Max path length is 100000.\n    // Initial path length L_dfs.\n    // Each additional visit can be achieved by a detour X->Y->X, adding 2 moves.\n    // Max number of extra visits K_max = (100000 - L_dfs) / 2\n    // Total max visits V_max = N*N + K_max\n\n    long double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((long double)d[i][j]);\n        }\n    }\n\n    int max_total_visits = 100000; // Maximum allowed path length\n\n    vector<long long> target_N(N * N, 0);\n    long long current_total_visits = 0;\n\n    // Ensure each cell is visited at least once\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            target_N[i * N + j] = 1;\n            current_total_visits++;\n        }\n    }\n    \n    // Distribute remaining visits greedily based on sqrt(d_i,j)\n    // We have `max_total_visits - current_total_visits` visits to distribute.\n    // This number is an upper bound on the sum of ADDITIONAL visits beyond the first one for each cell.\n    // Let's use the objective function to guide distribution: maximize sum(d_i,j / N_i,j^2)\n    // This implies N_i,j should be proportional to sqrt(d_i,j).\n\n    // Strategy: calculate proportional counts for all cells, then scale and adjust.\n    vector<pair<long double, pair<int, int>>> proportional_visits;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            proportional_visits.push_back({sqrt((long double)d[i][j]), {i, j}});\n        }\n    }\n    sort(proportional_visits.rbegin(), proportional_visits.rend());\n\n    // Distribute visits until total path length constraint is met.\n    // We have `max_total_visits` moves. Each visit adds at least 1 move, often 2 (detour).\n    // Let's use the rule that each visit adds 2 moves (detour)\n    // Total visits V should satisfy L_dfs + 2 * (V - N*N) <= 100000\n    // 2 * (V - N*N) <= 100000 - L_dfs\n    // V - N*N <= (100000 - L_dfs) / 2\n    // V <= N*N + (100000 - L_dfs) / 2\n    int max_additional_visits = (100000 - initial_path_len) / 2;\n    if (max_additional_visits < 0) max_additional_visits = 0;\n\n    current_total_visits = N * N; // All cells visited once initially\n\n    // Greedily assign additional visits to cells with high sqrt(d_i,j)\n    vector<long long> N_final(N * N, 1); // Start with 1 visit for each cell\n    long long visits_added_count = 0;\n\n    // First, distribute visits to reach max_additional_visits for sqrt(d_i,j) based proportional counts\n    vector<pair<long double, pair<int,int>>> sqrt_d_sorted;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) sqrt_d_sorted.push_back({sqrt((long double)d[i][j]), {i,j}});\n    sort(sqrt_d_sorted.rbegin(), sqrt_d_sorted.rend());\n    \n    for(const auto& p : sqrt_d_sorted) {\n        if (visits_added_count >= max_additional_visits) break;\n        int r = p.second.first;\n        int c = p.second.second;\n        N_final[r*N+c]++;\n        visits_added_count++;\n    }\n\n    // If we still have budget for more visits (e.g. if max_additional_visits was very large, and sum of sqrt(d_i,j) was small)\n    // we can add more visits to cells with highest d_i,j, using the priority queue logic.\n    // However, the proportional distribution up to max_additional_visits is likely optimal.\n\n    // If current_total_visits (N*N) + visits_added_count > 100000 (this check is redundant if max_additional_visits is calculated correctly)\n    // we need to cap it. But max_additional_visits ensures total length <= 100000.\n\n    // Current visit counts based on initial DFS and N_final assignment\n    map<pair<int, int>, int> current_N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_N[{i, j}] = visit_counts_dfs.count({i, j}) ? visit_counts_dfs[{i, j}] : 0;\n        }\n    }\n\n    // Adjust initial DFS counts to match N_final targets\n    // The DFS path might visit cells more than once initially.\n    // We need to reach N_final counts.\n    vector<pair<long double, pair<int, int>>> pq_cells; // (priority, {r, c})\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (current_N[{i, j}] < N_final[i * N + j]) {\n                pq_cells.push_back({ (long double)d[i][j] / (long double)(current_N[{i, j}] * current_N[{i, j}]), {i, j} });\n            }\n        }\n    }\n    sort(pq_cells.rbegin(), pq_cells.rend());\n\n    vector<pair<int, int>> cells_to_visit_extra; // Cells to add extra visits to\n    vector<int> extra_visits_count(N*N, 0);\n\n    int current_extra_visits_total = 0;\n    for(const auto& p : pq_cells) {\n        int r = p.second.first;\n        int c = p.second.second;\n        int needed = N_final[r*N+c] - current_N[{r,c}];\n        for(int k=0; k<needed; ++k) {\n            if (current_extra_visits_total >= max_additional_visits) break;\n            cells_to_visit_extra.push_back({r, c});\n            extra_visits_count[r*N+c]++;\n            current_extra_visits_total++;\n        }\n        if (current_extra_visits_total >= max_additional_visits) break;\n    }\n    \n    // Construct final path by adding detours\n    string final_path = initial_path_str;\n    int current_path_len = initial_path_len;\n\n    // Store path as sequence of cells for easier detour insertion\n    vector<pair<int, int>> path_cells;\n    path_cells.push_back({0,0});\n    int cur_r = 0, cur_c = 0;\n    for(char move : initial_path_str) {\n        if (move == 'U') cur_r--;\n        else if (move == 'D') cur_r++;\n        else if (move == 'L') cur_c--;\n        else if (move == 'R') cur_c++;\n        path_cells.push_back({cur_r, cur_c});\n    }\n\n    // Add detours\n    for (int r_target = 0; r_target < N; ++r_target) {\n        for (int c_target = 0; c_target < N; ++c_target) {\n            int count_to_add = extra_visits_count[r_target * N + c_target];\n            if (count_to_add == 0) continue;\n\n            // For each cell, add `count_to_add` detours.\n            // Simple detour: find last visit to (r_target, c_target) and insert a minimal path to it.\n            // This is complicated. A simpler approach: append detours from the END of current path.\n            // Path: P_dfs, then for each (r,c) to visit K times: append path(current_pos, r, c), append path(r,c, current_pos)\n            \n            for(int k=0; k<count_to_add; ++k) {\n                 if (current_path_len + 2 > 100000) break; // Safety break\n\n                // Find current end of path\n                cur_r = path_cells.back().first;\n                cur_c = path_cells.back().second;\n                \n                // Find shortest path from (cur_r, cur_c) to (r_target, c_target)\n                queue<pair<int, int>> q;\n                q.push({cur_r, cur_c});\n                vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited(N, vector<bool>(N, false));\n                visited[cur_r][cur_c] = true;\n                bool found = false;\n\n                while (!q.empty()) {\n                    pair<int, int> curr = q.front();\n                    q.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == r_target && c_curr == c_target) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited[nr][nc]) {\n                            visited[nr][nc] = true;\n                            parent[nr][nc] = {r_curr, c_curr};\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen as all cells are reachable */ continue; }\n\n                // Reconstruct path from (cur_r, cur_c) to (r_target, c_target)\n                vector<char> detour_fwd;\n                vector<pair<int, int>> detour_cells_fwd;\n                pair<int, int> trace = {r_target, c_target};\n                while (trace.first != cur_r || trace.second != cur_c) {\n                    pair<int, int> p_trace = parent[trace.first][trace.second];\n                    if (p_trace.first == -1) break; // Should not happen\n\n                    if (trace.first == p_trace.first - 1) detour_fwd.push_back('U');\n                    else if (trace.first == p_trace.first + 1) detour_fwd.push_back('D');\n                    else if (trace.second == p_trace.second - 1) detour_fwd.push_back('L');\n                    else if (trace.second == p_trace.second + 1) detour_fwd.push_back('R');\n                    \n                    detour_cells_fwd.push_back(trace);\n                    trace = p_trace;\n                }\n                reverse(detour_fwd.begin(), detour_fwd.end());\n                reverse(detour_cells_fwd.begin(), detour_cells_fwd.end());\n\n                // Add detour path to cells list\n                for(char move : detour_fwd) {\n                    path_cells.push_back({r_target,c_target}); // add target cell\n                    if (move == 'U') path_cells.push_back({path_cells.back().first - 1, path_cells.back().second});\n                    else if (move == 'D') path_cells.push_back({path_cells.back().first + 1, path_cells.back().second});\n                    else if (move == 'L') path_cells.push_back({path_cells.back().first, path_cells.back().second - 1});\n                    else if (move == 'R') path_cells.push_back({path_cells.back().first, path_cells.back().second + 1});\n                }\n                \n                // Add the final (r_target, c_target) cell itself\n                path_cells.push_back({r_target, c_target});\n                \n                // Now add path back to original current position (cur_r, cur_c)\n                // This is BFS from (r_target, c_target) to (cur_r, cur_c)\n                queue<pair<int, int>> q_ret;\n                q_ret.push({r_target, c_target});\n                vector<vector<pair<int, int>>> parent_ret(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited_ret(N, vector<bool>(N, false));\n                visited_ret[r_target][c_target] = true;\n                found = false;\n\n                while (!q_ret.empty()) {\n                    pair<int, int> curr = q_ret.front();\n                    q_ret.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == cur_r && c_curr == cur_c) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited_ret[nr][nc]) {\n                            visited_ret[nr][nc] = true;\n                            parent_ret[nr][nc] = {r_curr, c_curr};\n                            q_ret.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen */ continue; }\n\n                // Reconstruct path back\n                trace = {cur_r, cur_c};\n                while(trace.first != r_target || trace.second != c_target) {\n                     pair<int, int> p_trace = parent_ret[trace.first][trace.second];\n                     if (p_trace.first == -1) break;\n\n                     if (trace.first == p_trace.first - 1) path_cells.push_back({p_trace.first - 1, p_trace.second});\n                     else if (trace.first == p_trace.first + 1) path_cells.push_back({p_trace.first + 1, p_trace.second});\n                     else if (trace.second == p_trace.second - 1) path_cells.push_back({p_trace.second - 1, p_trace.second});\n                     else if (trace.second == p_trace.second + 1) path_cells.push_back({p_trace.second + 1, p_trace.second});\n                     trace = p_trace;\n                }\n\n                // Update current path length and position\n                current_path_len = path_cells.size() - 1;\n                if (current_path_len > 100000) { // Cap path length\n                    path_cells.resize(100000 + 1); // Keep start and end for length 100000\n                    current_path_len = 100000;\n                }\n            }\n        }\n    }\n\n    // Convert path_cells back to moves string, truncated if necessary\n    final_path = \"\";\n    for (size_t i = 0; i < path_cells.size() - 1; ++i) {\n        if (final_path.length() >= 100000) break;\n\n        int r1 = path_cells[i].first;\n        int c1 = path_cells[i].second;\n        int r2 = path_cells[i+1].first;\n        int c2 = path_cells[i+1].second;\n\n        if (r2 == r1 - 1) final_path += 'U';\n        else if (r2 == r1 + 1) final_path += 'D';\n        else if (c2 == c1 - 1) final_path += 'L';\n        else if (c2 == c1 + 1) final_path += 'R';\n    }\n\n    cout << final_path << endl;\n\n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <map>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nint N;\nchar grid[15][15];\nvector<string> t;\nint start_r, start_c;\n\n// For Dijkstra to find path for one string\n// dp[p][r][c]: min cost to type first p characters of target string, ending at (r,c)\n// where grid[r][c] matches the p-th character.\n// p from 1 to 5.\nlong long dp[6][15][15];\npair<int, int> pred[6][15][15]; // Stores previous coordinates to reconstruct path\n\n// Directions for BFS/Dijkstra\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nstruct State {\n    long long cost;\n    int r, c;\n\n    bool operator>(const State& other) const {\n        return cost > other.cost;\n    }\n};\n\n// Computes the minimum cost and path to type target_str starting from (sr, sc)\n// Returns {min_total_cost, end_r, end_c, sequence_of_operations}\ntuple<long long, int, int, vector<pair<int, int>>> compute_path(const string& target_str, int sr, int sc) {\n    for (int p = 0; p <= 5; ++p) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                dp[p][r][c] = INF;\n                pred[p][r][c] = {-1, -1};\n            }\n        }\n    }\n\n    char first_char = target_str[0];\n    \n    // Base case: p=1 (typing the first character)\n    // dp[1][r][c] = min cost to type first character (target_str[0]) ending at (r,c)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] == first_char) {\n                dp[1][r][c] = abs(r - sr) + abs(c - sc) + 1;\n                // pred[1][r][c] remains {-1, -1} to signify start\n            }\n        }\n    }\n\n    // Fill DP table for p = 2 to 5\n    for (int p = 2; p <= 5; ++p) {\n        char current_char_needed = target_str[p - 1];\n        \n        priority_queue<State, vector<State>, greater<State>> pq;\n        vector<vector<long long>> dist(N, vector<long long>(N, INF));\n        vector<vector<pair<int, int>>> layer_pred(N, vector<pair<int, int>>(N, {-1,-1}));\n\n        // Initialize Dijkstra PQ with costs from previous step (p-1)\n        // States in PQ are (cost_to_type_p-1_chars_ending_here, r, c)\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (dp[p - 1][r][c] != INF) {\n                    pq.push({dp[p - 1][r][c], r, c});\n                    dist[r][c] = dp[p - 1][r][c]; // dist here is min cost to reach (r,c) having typed p-1 chars\n                }\n            }\n        }\n\n        // Run Dijkstra\n        // We want to find min cost to reach any cell (nr, nc) for current_char_needed\n        // from any cell (r,c) which is a valid end for p-1 characters.\n        while (!pq.empty()) {\n            State current = pq.top();\n            pq.pop();\n\n            long long d = current.cost;\n            int r = current.r;\n            int c = current.c;\n\n            if (d > dist[r][c]) continue;\n\n            // Explore neighbors\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i];\n                int nc = c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    // Cost to move from (r,c) to (nr,nc) AND append grid[nr][nc]\n                    long long move_cost = abs(nr - r) + abs(nc - c) + 1;\n                    \n                    // If the neighbor cell (nr, nc) has the character needed for the current step (p)\n                    if (grid[nr][nc] == current_char_needed) {\n                        if (dist[r][c] + move_cost < dist[nr][nc]) {\n                            dist[nr][nc] = dist[r][c] + move_cost;\n                            layer_pred[nr][nc] = {r, c}; // Store predecessor for path reconstruction\n                            pq.push({dist[nr][nc], nr, nc});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Update DP table for step p\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (grid[r][c] == current_char_needed && dist[r][c] != INF) {\n                    dp[p][r][c] = dist[r][c];\n                    pred[p][r][c] = layer_pred[r][c]; // Store predecessor for path reconstruction\n                }\n            }\n        }\n    }\n\n    // Find the minimum cost to type the whole string (length 5)\n    long long min_total_cost = INF;\n    int final_r = -1, final_c = -1;\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[5][r][c] < min_total_cost) {\n                min_total_cost = dp[5][r][c];\n                final_r = r;\n                final_c = c;\n            }\n        }\n    }\n\n    // Reconstruct path\n    vector<pair<int, int>> path_ops;\n    if (final_r != -1) {\n        int curr_r = final_r;\n        int curr_c = final_c;\n        for (int p = 5; p >= 1; --p) {\n            path_ops.push_back({curr_r, curr_c});\n            if (p > 1) { // For p=1, pred is {-1,-1}\n                pair<int, int> prev_pos = pred[p][curr_r][curr_c];\n                curr_r = prev_pos.first;\n                curr_c = prev_pos.second;\n            }\n        }\n        reverse(path_ops.begin(), path_ops.end());\n    }\n    \n    return {min_total_cost, final_r, final_c, path_ops};\n}\n\n// Helper to check if string 'needle' is a substring of 'haystack'\nbool contains(const string& haystack, const string& needle) {\n    return haystack.find(needle) != string::npos;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M >> start_r >> start_c;\n    --start_r; --start_c; // 0-indexed\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    t.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> t[i];\n    }\n\n    vector<pair<int, int>> operations;\n    set<int> uncovered_indices;\n    for (int i = 0; i < M; ++i) {\n        uncovered_indices.insert(i);\n    }\n\n    int current_r = start_r;\n    int current_c = start_c;\n    long long total_cost = 0;\n    \n    // We can perform at most 5000 operations.\n    // Our strategy is to greedily type the cheapest full string that is not yet covered.\n    // Each typed string requires 5 operations.\n    // We continue this until we have typed 1000 strings (total 5000 operations)\n    // or until all strings are covered.\n\n    int max_strings_to_type = 1000; \n\n    for (int iter = 0; iter < max_strings_to_type; ++iter) {\n        if (uncovered_indices.empty()) break; // All strings are covered\n\n        long long min_iter_cost = INF;\n        int best_t_idx = -1;\n        int best_end_r = -1, best_end_c = -1;\n        vector<pair<int, int>> ops_for_best_t;\n\n        // Find the cheapest string to type among the currently uncovered ones\n        for (int idx : uncovered_indices) {\n            auto [cost, end_r, end_c, current_ops] = compute_path(t[idx], current_r, current_c);\n            \n            if (cost < min_iter_cost) {\n                min_iter_cost = cost;\n                best_t_idx = idx;\n                best_end_r = end_r;\n                best_end_c = end_c;\n                ops_for_best_t = current_ops;\n            }\n        }\n\n        // If no string can be typed (e.g., required chars not on grid, which is guaranteed not to happen)\n        if (best_t_idx == -1) { \n            break;\n        }\n\n        // Append operations for the chosen string\n        operations.insert(operations.end(), ops_for_best_t.begin(), ops_for_best_t.end());\n        current_r = best_end_r;\n        current_c = best_end_c;\n        total_cost += min_iter_cost;\n        \n        // Remove the typed string from the set of uncovered indices\n        uncovered_indices.erase(best_t_idx);\n    }\n\n    // Output the operations\n    cout << operations.size() << endl;\n    for (const auto& op : operations) {\n        cout << op.first + 1 << \" \" << op.second + 1 << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath> // Included for completeness, though not directly used in the final strategy.\n#include <iomanip> // Included for completeness, though not directly used in the final strategy.\n#include <utility> // Required for std::pair.\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // This can significantly speed up input/output operations, which is crucial\n    // for problems with large I/O or strict time limits.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // The size of the island grid (N x N). Constraints: 10 <= N <= 20.\n    int m; // The number of unexplored oil fields. Constraints: 2 <= M <= 20.\n    double epsilon; // The error parameter for the noisy divine query operation. Constraints: 0.01 <= epsilon <= 0.2.\n\n    // Read the initial problem parameters from standard input.\n    std::cin >> n >> m >> epsilon;\n\n    // Read the shapes of the M oil fields.\n    // Each shape is defined by its area (d) and a list of relative coordinates\n    // for the squares it occupies.\n    // For the chosen strategy (drilling every square), this information is not directly used.\n    // A more complex heuristic or optimization strategy might leverage these shapes\n    // to infer potential locations or prune search spaces.\n    for (int k = 0; k < m; ++k) {\n        int d; // The number of squares in the k-th oil field (area).\n        std::cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int r, c; // Relative coordinates (row, column) of a square within the k-th oil field shape.\n            std::cin >> r >> c;\n            // The current strategy ignores these shapes.\n        }\n    }\n\n    // This vector will store the coordinates (row, column) of all squares\n    // that are found to contain oil reserves (i.e., v(i,j) > 0).\n    // This list will form the basis of our final \"guess\" operation.\n    std::vector<std::pair<int, int>> positive_oil_squares;\n\n    // --- Chosen Strategy: Drill every square on the island ---\n    //\n    // This is a deterministic, brute-force approach. It queries each of the N*N squares\n    // individually to reveal its exact oil reserve value v(i,j).\n    //\n    // Cost Analysis:\n    // - Operation Type: \"Drill\" (q 1 i j). Cost per operation: 1.\n    // - Total number of squares on the island: N*N.\n    // - Total cost for performing N*N drill operations: N*N.\n    //\n    // Operation Limit Analysis:\n    // - The problem statement allows a maximum of 2*N*N operations in total.\n    // - For the maximum island size N=20, N*N = 400 operations, and 2*N*N = 800 operations.\n    // - The N*N cost of this strategy is well within the allowed operation limit.\n    //\n    // Correctness Guarantee:\n    // - By drilling every square, we obtain the exact value of v(i,j) for every cell.\n    // - This guarantees that we can precisely identify *all* squares where v(i,j) > 0.\n    // - The final \"guess\" operation will therefore be 100% accurate, leading to a successful completion.\n    //\n    // Justification for ignoring the \"divine\" operation:\n    // - The \"divine\" operation (querying a set S of k squares) has a cost of 1/sqrt(k) but returns a noisy sum.\n    // - The noise (variance) increases with k, making it difficult to obtain precise information about individual v(i,j) values,\n    //   especially small values or distinguishing v(i,j)=0 from v(i,j)=1.\n    // - To guarantee identifying *all* squares with v(i,j) > 0, definitive information is required. Drilling provides this.\n    // - Given the small constraints on N (N <= 20), the total cost of N*N is sufficiently low. The guaranteed correctness\n    //   and simplicity of the drilling strategy make it a robust choice for achieving a high score. More complex strategies\n    //   involving divine queries might offer marginal benefits only for much larger grid sizes.\n    //\n    // Implementation Loop:\n    // - We iterate through each row 'i' from 0 to N-1.\n    // - Within each row, we iterate through each column 'j' from 0 to N-1.\n    // - For every square (i, j), we issue a \"drill\" query.\n    // - We then read the revealed oil reserves for that square.\n    // - If the reserves are positive, we record the square's coordinates.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            // Output the drill query command: \"q 1 <row> <column>\"\n            // std::endl automatically flushes the output buffer.\n            std::cout << \"q 1 \" << i << \" \" << j << std::endl;\n\n            int reserves; // The value v(i, j) revealed for the current square.\n            std::cin >> reserves; // Read the result from standard input.\n\n            // If the square contains oil (reserves > 0), store its coordinates.\n            if (reserves > 0) {\n                positive_oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // --- Output the Final Guess ---\n    //\n    // Once all squares have been drilled, the 'positive_oil_squares' vector contains\n    // the exact set of squares that have oil reserves. We now form the final \"guess\" operation.\n    //\n    // The format for the guess operation is: \"a <d> <i1> <j1> <i2> <j2> ...\"\n    // where 'd' is the total number of squares guessed to have oil.\n    std::cout << \"a \" << positive_oil_squares.size();\n    for (const auto& p : positive_oil_squares) {\n        std::cout << \" \" << p.first << \" \" << p.second;\n    }\n    std::cout << std::endl; // Flush the output buffer to ensure the guess is sent.\n\n    // --- Read Confirmation from Judge ---\n    //\n    // The judge will respond with '1' if our guess is correct and '0' if it is incorrect.\n    // Given the deterministic nature of the drilling strategy, we expect this to always be '1'.\n    int correct;\n    std::cin >> correct;\n\n    // If the guess was correct, the program has successfully completed its task.\n    if (correct == 1) {\n        return 0; // Exit with a success code.\n    } else {\n        // If the guess was incorrect (correct == 0), this indicates an unexpected issue.\n        // The N^2 drilling strategy is designed to be infallible for this problem.\n        // If this branch is reached, it might point to a subtle problem interpretation error\n        // or an extremely rare edge case. We exit with a non-zero code to signal abnormal termination.\n        return 1; \n    }\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n#include <string> // For structure names\n\nusing namespace std;\n\nlong long W;\nint D, N;\n\nstruct Rect {\n    int x0, y0, x1, y1;\n    long long area;\n};\n\n// Structure to hold a list of N rectangles and their total cost for a particular partition layout.\nstruct PartitionStructure {\n    vector<Rect> rects; // The N generated rectangles for this structure. Order might not be important initially.\n    long long total_cost = -1; // The total area cost over all days using this structure and greedy assignment.\n    string name; // A descriptive name for the structure (e.g., \"VerticalStrips\").\n\n    // Comparator for sorting Rects by area in descending order.\n    static bool compareRects(const Rect& a, const Rect& b) {\n        return a.area > b.area;\n    }\n};\n\n// --- Partition Generation Functions ---\n\n// Recursive helper function to generate rectangles for a balanced subdivision.\n// It splits the current bounding box (x0,y0)-(x1,y1) into `count_needed` rectangles.\n// The split is always along the larger dimension to try and maintain aspect ratios closer to 1.\nvoid generate_recursive_helper(vector<Rect>& rects, int x0, int y0, int x1, int y1, int count_needed) {\n    if (count_needed == 0) return;\n\n    // Base case: if only one rectangle is needed, create it.\n    if (count_needed == 1) {\n        rects.push_back({x0, y0, x1, y1, (long long)(x1 - x0) * (y1 - y0)});\n        return;\n    }\n\n    long long total_width = x1 - x0;\n    long long total_height = y1 - y0;\n\n    // Divide `count_needed` into two parts for the children.\n    int num_left_child = count_needed / 2;\n    int num_right_child = count_needed - num_left_child;\n\n    // Split along the larger dimension.\n    if (total_width >= total_height) { // Split vertically\n        // Calculate the split point `mid_x` such that the resulting child areas are proportional to the number of rectangles they will hold.\n        long long mid_x = x0 + total_width * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, mid_x, y1, num_left_child);\n        generate_recursive_helper(rects, mid_x, y0, x1, y1, num_right_child);\n    } else { // Split horizontally\n        long long mid_y = y0 + total_height * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, x1, mid_y, num_left_child);\n        generate_recursive_helper(rects, x0, mid_y, x1, y1, num_right_child);\n    }\n}\n\n// Initializes the generation of N rectangles using the recursive subdivision strategy.\nvoid generate_recursive_rects(vector<Rect>& rects, int num_rects) {\n    generate_recursive_helper(rects, 0, 0, W, W, num_rects);\n}\n\n// Generates N vertical strips of as equal width as possible.\nvoid generate_vertical_strips(vector<Rect>& rects, int num_strips) {\n    long long base_w = W / num_strips;\n    long long remainder_w = W % num_strips; // Number of strips that will get an extra pixel of width.\n    int current_x = 0;\n    for (int i = 0; i < num_strips; ++i) {\n        long long w = base_w + (i < remainder_w ? 1 : 0);\n        if (w > 0) { // Ensure width is positive (important if N > W, though constraints prevent this).\n            rects.push_back({current_x, 0, current_x + (int)w, (int)W, w * W});\n            current_x += w;\n        }\n    }\n}\n\n// Generates N horizontal strips of as equal height as possible.\nvoid generate_horizontal_strips(vector<Rect>& rects, int num_strips) {\n    long long base_h = W / num_strips;\n    long long remainder_h = W % num_strips; // Number of strips that will get an extra pixel of height.\n    int current_y = 0;\n    for (int i = 0; i < num_strips; ++i) {\n        long long h = base_h + (i < remainder_h ? 1 : 0);\n        if (h > 0) { // Ensure height is positive.\n            rects.push_back({0, current_y, (int)W, current_y + (int)h, W * h});\n            current_y += h;\n        }\n    }\n}\n\n// --- Cost Calculation ---\n\n// Calculates the total area cost for a given partition structure across all days.\n// It uses greedy assignment: the i-th largest desired area is assigned to the i-th largest available base rectangle area.\n// This strategy assumes a fixed partition layout for all days, thus partition change cost is effectively zero.\nlong long calculate_total_cost(const vector<Rect>& base_rects_for_structure, const vector<vector<pair<int, int>>>& a_d_k_sorted_by_area) {\n    // Create a mutable copy of the base rectangles and sort them by area in descending order.\n    vector<Rect> sorted_base_rects = base_rects_for_structure;\n    sort(sorted_base_rects.begin(), sorted_base_rects.end(), PartitionStructure::compareRects);\n\n    // Extract just the sorted areas of the base rectangles.\n    vector<long long> sorted_base_areas(N);\n    for (int i = 0; i < N; ++i) {\n        sorted_base_areas[i] = sorted_base_rects[i].area;\n    }\n\n    long long current_total_area_cost = 0;\n    // Iterate through each day to calculate its area cost.\n    for (int d = 0; d < D; ++d) {\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; // This is already sorted by area descending.\n\n        // Greedily assign the i-th largest desired area to the i-th largest available base rectangle area.\n        for (int i = 0; i < N; ++i) {\n            long long required_area = daily_reservations_sorted[i].first;\n            long long assigned_area = sorted_base_areas[i];\n            current_total_area_cost += 100LL * max(0LL, required_area - assigned_area);\n        }\n    }\n    \n    return current_total_area_cost;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> W >> D >> N;\n\n    // Store desired areas for each reservation on each day.\n    // `a_d_k_sorted_by_area[d][i]` will store {area, original_k} for the reservation\n    // that has the i-th largest area on day `d`.\n    vector<vector<pair<int, int>>> a_d_k_sorted_by_area(D, vector<pair<int, int>>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a_d_k_sorted_by_area[d][k].first;\n            a_d_k_sorted_by_area[d][k].second = k; // Store original index (0 to N-1).\n        }\n        // Sort reservations for day `d` by area in descending order.\n        sort(a_d_k_sorted_by_area[d].rbegin(), a_d_k_sorted_by_area[d].rend());\n    }\n\n    vector<PartitionStructure> candidate_structures;\n\n    // --- Generate candidate partition structures ---\n\n    // Structure 1: Recursive balanced subdivision.\n    vector<Rect> rects1;\n    generate_recursive_rects(rects1, N);\n    candidate_structures.push_back({rects1, -1, \"RecursiveBalanced\"});\n\n    // Structure 2: Vertical strips.\n    vector<Rect> rects2;\n    generate_vertical_strips(rects2, N);\n    candidate_structures.push_back({rects2, -1, \"VerticalStrips\"});\n\n    // Structure 3: Horizontal strips.\n    vector<Rect> rects3;\n    generate_horizontal_strips(rects3, N);\n    candidate_structures.push_back({rects3, -1, \"HorizontalStrips\"});\n\n    // --- Evaluate each structure ---\n    long long min_total_cost = -1;\n    int best_structure_idx = -1;\n\n    // Iterate through all candidate structures, calculate their total cost, and find the best one.\n    for (int i = 0; i < candidate_structures.size(); ++i) {\n        candidate_structures[i].total_cost = calculate_total_cost(candidate_structures[i].rects, a_d_k_sorted_by_area);\n        \n        // Update best structure if this one is better.\n        if (best_structure_idx == -1 || candidate_structures[i].total_cost < min_total_cost) {\n            min_total_cost = candidate_structures[i].total_cost;\n            best_structure_idx = i;\n        }\n    }\n\n    // --- Output the best structure ---\n    const auto& best_structure = candidate_structures[best_structure_idx];\n    \n    // The output requires rectangles for each day, in the order of the original input reservations for that day.\n    // We need to determine which of the N base rectangles from the best structure is assigned to which original reservation `k` for each day `d`.\n\n    // Get the N base rectangles from the chosen best structure.\n    vector<Rect> N_base_rects_from_best_structure = best_structure.rects;\n\n    // Sort these N rectangles by area in descending order. This sorted list represents the available slots\n    // when applying the greedy assignment strategy (i-th largest area slot is sorted_base_rects_by_area[i]).\n    vector<Rect> sorted_base_rects_by_area = N_base_rects_from_best_structure;\n    sort(sorted_base_rects_by_area.begin(), sorted_base_rects_by_area.end(), PartitionStructure::compareRects);\n\n    // `assignments_per_day[d][k]` will store the Rect object (coordinates) assigned to the original reservation `k` on day `d`.\n    vector<vector<Rect>> assignments_per_day(D, vector<Rect>(N));\n\n    // For each day, map the sorted reservations to the sorted base rectangles.\n    for (int d = 0; d < D; ++d) {\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; // Sorted by area descending ({area, original_k})\n        \n        // Iterate through the ranks of reservations by area (i=0 is largest area reservation).\n        for (int i = 0; i < N; ++i) {\n            // Get the original index of the reservation that has the i-th largest area on day `d`.\n            int original_reservation_k = daily_reservations_sorted[i].second; \n            \n            // Assign the i-th largest base rectangle (sorted_base_rects_by_area[i])\n            // to this reservation `original_reservation_k` for day `d`.\n            assignments_per_day[d][original_reservation_k] = sorted_base_rects_by_area[i];\n        }\n    }\n\n    // Output the assignments in the required format: N lines for day 0, then N for day 1, etc.,\n    // where the k-th line corresponds to the k-th original reservation for that day.\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) { // Output for reservation k (original index) on day d.\n            const Rect& r = assignments_per_day[d][k];\n            cout << r.x0 << \" \" << r.y0 << \" \" << r.x1 << \" \" << r.y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global constants and variables for the problem.\n// N, M, K are small enough that long long is not strictly necessary for them,\n// but using it for consistency and to avoid potential issues with larger constraints.\nlong long N_val, M_val, K_val; \nconst long long MOD = 998244353; // The modulus for scoring.\n\n// Structure to hold a state in the beam search.\n// A state includes the current board configuration, the sequence of operations to reach it,\n// and its total score.\nstruct State {\n    vector<vector<long long>> board; // The board configuration for this state.\n    vector<tuple<int, int, int>> operations; // The sequence of operations to reach this state.\n    long long current_score; // The score of this state (sum of board[i][j] % MOD).\n\n    // Operator for comparison in a priority queue.\n    // We want states with higher scores to have higher priority.\n    // std::priority_queue is a max-heap by default, so it will keep the element with the largest value\n    // (based on this operator) at the top.\n    bool operator<(const State& other) const {\n        return current_score < other.current_score;\n    }\n};\n\n/**\n * @brief Calculates the immediate score gain by applying a specific stamp at a given position on a given board.\n * \n * The gain is the sum of (new_cell_value % MOD - old_cell_value % MOD) for all affected cells.\n * This value can be positive, zero, or negative. Only positive gains are considered for extending the search.\n * \n * @param current_board The current board state.\n * @param stamp_idx The index of the stamp to consider (0 to M-1).\n * @param p The top row coordinate on the board where the stamp's (0,0) is placed.\n * @param q The left column coordinate on the board where the stamp's (0,0) is placed.\n * @param stamps The collection of all stamps.\n * @return The total score gain (sum of modulo differences) for this operation.\n */\nlong long calculate_gain_for_state(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    long long current_gain_sum = 0; // Accumulates the score change.\n    \n    // Iterate over the 3x3 squares of the stamp.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int r = p + i; // Corresponding row on the board.\n            int c = q + j; // Corresponding column on the board.\n\n            // The current score contribution of the cell (r, c) to the total score.\n            // Using (val % MOD + MOD) % MOD ensures the result is in [0, MOD-1],\n            // though input values are non-negative, this is good practice.\n            long long current_score_contrib = (current_board[r][c] % MOD + MOD) % MOD;\n            \n            // The value from the stamp at relative position (i, j).\n            long long stamp_val = stamps[stamp_idx][i][j];\n            \n            // The new total value on the board cell (r, c) after applying the stamp.\n            long long new_board_val = current_board[r][c] + stamp_val;\n            \n            // The new score contribution of the cell (r, c) after the operation.\n            long long new_score_contrib = (new_board_val % MOD + MOD) % MOD;\n            \n            // The change in score for this specific cell.\n            long long delta = new_score_contrib - current_score_contrib;\n            \n            current_gain_sum += delta; // Add the cell's score change to the total gain.\n        }\n    }\n    return current_gain_sum;\n}\n\n/**\n * @brief Applies a stamp to a board and returns the new board state.\n * \n * This function creates a copy of the board and applies the stamp values to it.\n * \n * @param current_board The board to apply the stamp to.\n * @param stamp_idx The index of the stamp to apply.\n * @param p The top row coordinate for placement.\n * @param q The left column coordinate for placement.\n * @param stamps The collection of all stamps.\n * @return A new board with the stamp applied.\n */\nvector<vector<long long>> apply_stamp_to_board(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    vector<vector<long long>> next_board = current_board; // Copy the board to avoid modifying the original state.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            next_board[p + i][q + j] += stamps[stamp_idx][i][j];\n        }\n    }\n    return next_board;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read board dimensions (N) and number of stamps (M), and max operations (K).\n    cin >> N_val >> M_val >> K_val;\n\n    // Initialize the board with the given initial values and calculate initial score.\n    vector<vector<long long>> initial_board(N_val, vector<long long>(N_val));\n    long long initial_score = 0;\n    for (int i = 0; i < N_val; ++i) {\n        for (int j = 0; j < N_val; ++j) {\n            cin >> initial_board[i][j];\n            // Calculate initial score: sum of (value % MOD).\n            // Using (val % MOD + MOD) % MOD for robustness.\n            initial_score = (initial_score + (initial_board[i][j] % MOD + MOD) % MOD) % MOD;\n        }\n    }\n\n    // Read the values for all M stamps.\n    vector<vector<vector<long long>>> stamps(M_val, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M_val; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n\n    // --- Beam Search Strategy ---\n    // Beam search explores multiple promising states simultaneously to escape local optima.\n    // BEAM_WIDTH determines how many of the best states are kept at each step.\n    // Increased BEAM_WIDTH from 5 to 10 to explore more potential paths, aiming for higher scores.\n    const int BEAM_WIDTH = 10; \n    \n    // Priority queue to store states for the current step. `std::priority_queue` is a max-heap by default,\n    // so states with higher scores will be at the top.\n    priority_queue<State> pq;\n\n    // Create the initial state and push it into the priority queue.\n    State initial_state;\n    initial_state.board = initial_board;\n    initial_state.current_score = initial_score;\n    pq.push(initial_state);\n\n    // Track the best overall state found throughout the search.\n    State best_overall_state = initial_state;\n\n    // Perform beam search for up to K_val steps. Each step represents applying one more operation.\n    for (int k = 0; k < K_val; ++k) {\n        // Store candidate next states generated from the current step's states.\n        vector<State> candidates;\n\n        // Process up to BEAM_WIDTH states from the current priority queue.\n        int states_to_process = min((int)pq.size(), BEAM_WIDTH);\n        \n        // If no states are left to process or the priority queue is empty, break the loop.\n        if (states_to_process == 0) break;\n\n        for(int i = 0; i < states_to_process; ++i) {\n            State current_state = pq.top();\n            pq.pop();\n\n            // Explore all possible next operations (stamp type and position) from this state.\n            for (int m = 0; m < M_val; ++m) {\n                for (int p = 0; p <= N_val - 3; ++p) { // Possible top-left row for stamp placement.\n                    for (int q = 0; q <= N_val - 3; ++q) { // Possible top-left column for stamp placement.\n                        \n                        // Calculate the immediate score gain from this potential operation.\n                        long long gain = calculate_gain_for_state(current_state.board, m, p, q, stamps);\n\n                        // Only consider operations that strictly increase the score.\n                        // This ensures we always move towards a better score and avoid unnecessary operations.\n                        if (gain > 0) {\n                            // Create a new state by applying the operation.\n                            State next_state;\n                            next_state.board = apply_stamp_to_board(current_state.board, m, p, q, stamps);\n                            next_state.operations = current_state.operations; // Copy operations from current state.\n                            next_state.operations.emplace_back(m, p, q); // Add the new operation.\n                            \n                            // Update the score: current score + gain. The gain is already the sum of modulo differences.\n                            next_state.current_score = current_state.current_score + gain;\n                            \n                            // Add this new state to the list of candidates for the next step.\n                            candidates.push_back(next_state);\n\n                            // Update the best overall state found so far if this new state is better.\n                            if (next_state.current_score > best_overall_state.current_score) {\n                                best_overall_state = next_state;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If no operations resulted in a positive gain from any of the processed states,\n        // it means we cannot improve the score further with positive gain operations.\n        // We can stop the search early.\n        if (candidates.empty()) {\n            break;\n        }\n\n        // Sort the generated candidates by their score in descending order.\n        sort(candidates.begin(), candidates.end(), [](const State& a, const State& b){\n            return a.current_score > b.current_score;\n        });\n\n        // Push the top BEAM_WIDTH candidates into the priority queue for the next iteration.\n        // This prunes the search space, keeping only the most promising states.\n        for(int i = 0; i < min((int)candidates.size(), BEAM_WIDTH); ++i) {\n            pq.push(candidates[i]);\n        }\n    }\n\n    // --- Output ---\n    // The 'best_overall_state' now holds the sequence of operations that yielded the highest score.\n    cout << best_overall_state.operations.size() << endl;\n    for (const auto& op : best_overall_state.operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << endl;\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int MAX_TURNS = 10000;\nint N;\n\n// Grid state\nvector<vector<int>> grid; // container ID, -1 if empty\nvector<vector<int>> crane_id_at; // crane ID, -1 if empty\n\n// Crane state\nstruct Crane {\n    int id;\n    pair<int, int> pos;\n    int holding_container_id; // -1 if not holding\n    bool is_large;\n    int base_priority; // For task assignment logic\n};\nvector<Crane> cranes;\n\n// Container state is implicitly managed by grid and crane_holding_id\n\n// Receiving Gate state\nvector<int> receiving_gate_next_container_idx; // For each receiving gate i, index into A[i]\n\n// Dispatch Gate state\nvector<int> dispatch_gate_expected_container; // For each dispatch gate i, the ID of the next container to be dispatched. -1 if all dispatched.\n\n// Container to Target Gate mapping\nvector<int> container_target_gate;\n\n// Temporary storage cells\nvector<pair<int, int>> temp_storage_cells;\n\n// Helper to check if a cell is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Helper to get target dispatch gate for a container\nint get_target_gate(int container_id) {\n    if (container_id < 0) return -1; // Should not happen for valid containers\n    return container_id / N;\n}\n\n// Greedy best-step pathfinding to target_pos\npair<int, int> get_next_step(pair<int, int> current_pos, pair<int, int> target_pos) {\n    if (current_pos == target_pos) return current_pos;\n\n    int r = current_pos.first;\n    int c = current_pos.second;\n    int tr = target_pos.first;\n    int tc = target_pos.second;\n\n    int dr = tr - r;\n    int dc = tc - c;\n\n    // Prioritize moving vertically if difference is larger or equal, otherwise horizontally.\n    if (abs(dr) >= abs(dc)) { \n        if (dr > 0) return {r + 1, c}; // D\n        else if (dr < 0) return {r - 1, c}; // U\n    }\n    // If vertical difference is smaller or zero, prioritize horizontal movement.\n    if (abs(dc) > abs(dr)) {\n        if (dc > 0) return {r, c + 1}; // R\n        else if (dc < 0) return {r, c - 1}; // L\n    }\n    \n    // Fallback: This should ideally not be reached if current_pos != target_pos.\n    // It means dr=0 and dc=0, which is handled by the initial check.\n    return current_pos; \n}\n\n// Crane Task types for priority\nenum TaskType {\n    WAIT,\n    PICKUP_REC,       // Pickup from Receiving Gate\n    PICKUP_TEMP,      // Pickup from Temporary Storage\n    STORE_CONTAINER,  // Store container in Temporary Storage\n    DELIVER_TO_GATE   // Deliver container to Dispatch Gate\n};\n\n// Structure to hold a crane's task and its priority\nstruct CraneTask {\n    TaskType type;\n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n};\n\n// Function to determine the crane's highest priority task\nCraneTask determine_crane_task(int crane_idx) {\n    Crane& crane = cranes[crane_idx];\n    pair<int, int> current_pos = crane.pos;\n\n    // Assign base priority. Large crane has highest base priority.\n    // Small cranes have priority decreasing with their initial index.\n    // Adjusted priorities for better separation and SC distinctiveness.\n    int current_base_priority = crane.is_large ? 1000 : 100 * (N - 1 - crane_idx); \n\n    // Task 4: DELIVER_TO_GATE\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n        \n        // Check if the container is the *next expected* for its target dispatch gate\n        if (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]) {\n            pair<int, int> deliver_pos = {target_gate, N - 1};\n            // Highest priority task: DELIVER_TO_GATE\n            return {DELIVER_TO_GATE, deliver_pos, current_base_priority + 100}; // Very high priority\n        }\n    }\n\n    // Task 1 & 2: PICKUP_REQ (from Receiving Gate or Temp Storage) for required containers\n    if (crane.holding_container_id == -1) { // Only pick up if not holding anything\n        // Check for required containers at dispatch gates\n        for (int i = 0; i < N; ++i) { // Iterate through dispatch gates\n            int expected_container_id = dispatch_gate_expected_container[i];\n            if (expected_container_id != -1) { // If a container is still expected for this gate\n                // Check if this container belongs to gate i (redundant check but good for clarity)\n                if (get_target_gate(expected_container_id) == i) {\n                    // Find its current location\n                    // Check Receiving Gates (Task 1: PICKUP_REC)\n                    if (grid[i][0] == expected_container_id) {\n                        // High priority: PICKUP_REC for required container\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 80}; // High priority\n                    }\n                    // Check Temporary Storage Cells (Task 2: PICKUP_TEMP)\n                    for (const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == expected_container_id) {\n                            // High priority: PICKUP_TEMP for required container\n                            return {PICKUP_TEMP, cell, current_base_priority + 70}; // High priority\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 3: STORE_CONTAINER\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n\n        // If the container is NOT the next one needed for its dispatch gate, and we have somewhere to store it.\n        bool is_needed_now = (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]);\n        if (!is_needed_now) {\n            pair<int, int> temp_storage_target = {-1, -1};\n            for (const auto& cell : temp_storage_cells) {\n                // Cell must be empty (no container, no crane)\n                if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                    temp_storage_target = cell;\n                    break;\n                }\n            }\n            if (temp_storage_target != make_pair(-1, -1)) {\n                // Medium priority: STORE_CONTAINER\n                return {STORE_CONTAINER, temp_storage_target, current_base_priority + 50}; // Medium priority\n            }\n        }\n    }\n    \n    // Task 1 (low priority): Proactive fetch from Receiving Gates\n    // Only if not holding a container and not already going to pick up a *required* container\n    if (crane.holding_container_id == -1) {\n        for (int i = 0; i < N; ++i) { // Iterate through receiving gates\n            if (receiving_gate_next_container_idx[i] < N) { // If containers are still arriving\n                // Check if cell (i,0) has an arrived container and is not occupied by a crane\n                if (grid[i][0] != -1 && crane_id_at[i][0] == -1) { \n                    // Check if there's an available temporary storage cell to move it to\n                    pair<int, int> temp_storage_target = {-1, -1};\n                    for(const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                            temp_storage_target = cell;\n                            break;\n                        }\n                    }\n                    if (temp_storage_target != make_pair(-1, -1)) {\n                        // Low priority: PICKUP_REC (proactive)\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 20}; // Low priority\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 0: WAIT\n    return {WAIT, current_pos, current_base_priority}; // Default to WAIT\n}\n\n// Structure to hold a crane's requested move for collision resolution\nstruct MoveRequest {\n    int crane_idx;\n    // Renamed 'type' to 'task_kind' to avoid potential compiler issues with reserved names or conflicts.\n    TaskType task_kind; \n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n\n    bool operator<(const MoveRequest& other) const {\n        // Sort by priority descending. If priorities are equal, sort by crane_idx ascending\n        // to ensure deterministic behavior.\n        if (priority != other.priority) {\n            return priority > other.priority;\n        }\n        return crane_idx < other.crane_idx; \n    }\n};\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    grid.assign(N, vector<int>(N, -1));\n    crane_id_at.assign(N, vector<int>(N, -1));\n    receiving_gate_next_container_idx.assign(N, 0);\n    dispatch_gate_expected_container.assign(N, -1); // Initialize with -1\n\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n        }\n    }\n\n    // Initialize container_target_gate mapping\n    container_target_gate.resize(N * N);\n    for (int i = 0; i < N * N; ++i) {\n        container_target_gate[i] = get_target_gate(i);\n    }\n\n    // Initialize dispatch gate expected containers\n    for (int i = 0; i < N; ++i) {\n        dispatch_gate_expected_container[i] = N * i;\n    }\n\n    // Initialize cranes\n    cranes.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].id = i;\n        cranes[i].pos = {i, 0};\n        cranes[i].holding_container_id = -1;\n        cranes[i].is_large = (i == 0);\n        // Base priority: LC highest, SCs decreasing.\n        cranes[i].base_priority = (i == 0) ? 1000 : 100 * (N - 1 - i); \n\n        crane_id_at[i][0] = i; // Place cranes on grid\n    }\n\n    // Initialize temporary storage cells. Aim for inner cells, away from edges.\n    // Prioritize cells further from receiving/dispatch gates.\n    for (int r = 1; r < N - 1; ++r) {\n        for (int c = 1; c < N - 1; ++c) {\n            temp_storage_cells.push_back({r, c});\n        }\n    }\n    // If N is small (e.g., N=1, N=2), the inner grid might not exist. Add cells from other rows/columns if available.\n    // Add cells on inner columns (not edges) first.\n    if (temp_storage_cells.empty() && N > 1) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 1; c < N - 1; ++c) { // Cells not on the left edge (receiving gates)\n                temp_storage_cells.push_back({r, c});\n            }\n        }\n    }\n    // Add remaining cells if still empty (e.g., N=1 or N=2).\n    if (temp_storage_cells.empty() && N > 1) { // Avoid adding (0,0) which is LC start\n         for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Avoid receiving gates (c=0), dispatch gates (c=N-1), and LC start position for initial temp cells\n                // Prefer inner cells (c=1 to N-2).\n                if (c > 0 && c < N-1) { \n                     temp_storage_cells.push_back({r,c});\n                }\n            }\n        }\n    }\n    // Sort temp storage cells by distance from LC start {0,0} to potentially prioritize closer ones first for initial storage.\n    sort(temp_storage_cells.begin(), temp_storage_cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n        int dist_a = abs(a.first - 0) + abs(a.second - 0);\n        int dist_b = abs(b.first - 0) + abs(b.second - 0);\n        return dist_a < dist_b;\n    });\n\n\n    vector<string> output_ops(N, \"\");\n\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        // Step 1: Container Arrival\n        for (int i = 0; i < N; ++i) { // For each receiving gate row i\n            if (receiving_gate_next_container_idx[i] < N) {\n                // Place container if receiving gate cell (i,0) is empty (no container, no crane)\n                if (grid[i][0] == -1 && crane_id_at[i][0] == -1) {\n                    int container_id = A[i][receiving_gate_next_container_idx[i]];\n                    grid[i][0] = container_id;\n                    receiving_gate_next_container_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        vector<MoveRequest> requests;\n        \n        // Determine desired tasks for all cranes\n        for (int i = 0; i < N; ++i) {\n            CraneTask task = determine_crane_task(i);\n            requests.push_back({i, task.type, task.target_pos, task.priority});\n        }\n\n        // Sort requests by priority (highest first). The operator< in MoveRequest handles this.\n        sort(requests.begin(), requests.end());\n\n        // `next_crane_id_at` stores the state of crane positions *after* all actions in this turn are resolved.\n        vector<vector<int>> next_crane_id_at = crane_id_at; \n        \n        // Keep track of the final state for each crane after its action for this turn.\n        vector<pair<int, int>> final_crane_pos(N);\n        vector<int> final_crane_holding(N);\n        vector<char> final_crane_action(N);\n        vector<bool> crane_action_committed(N, false); // Track if crane committed to an action/move\n\n        // Initialize with current state, assuming no action initially.\n        for(int i=0; i<N; ++i) {\n            final_crane_pos[i] = cranes[i].pos;\n            final_crane_holding[i] = cranes[i].holding_container_id;\n            final_crane_action[i] = '.';\n        }\n\n        // Iterate through sorted requests to resolve conflicts.\n        for (const auto& req : requests) {\n            int k = req.crane_idx; // Current crane index\n\n            // If crane k has already committed to an action (e.g., due to higher priority or being part of a prior committed move), skip.\n            if (crane_action_committed[k]) continue;\n\n            Crane& current_crane_state = cranes[k]; // Reference to the actual crane object\n            pair<int, int> current_pos = current_crane_state.pos; // Its position BEFORE this turn's action\n            \n            // Determine the intended next position and action based on the request.\n            pair<int, int> intended_next_pos = current_pos;\n            char intended_action_char = '.';\n            bool action_possible = true;\n\n            // Assign intended action based on task type\n            if (req.task_kind == DELIVER_TO_GATE || req.task_kind == STORE_CONTAINER) { // Tasks involving releasing a container\n                if (current_pos == req.target_pos) { // Already at target for Q action\n                    intended_action_char = 'Q';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to eventually drop\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target (already there or blocked by logic)\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else if (req.task_kind == PICKUP_REC || req.task_kind == PICKUP_TEMP) { // Tasks involving picking up a container\n                if (current_pos == req.target_pos) { // Already at target for P action\n                    intended_action_char = 'P';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to pick up\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else { // WAIT or other task not requiring specific movement now\n                intended_action_char = '.';\n                intended_next_pos = current_pos;\n            }\n\n            // --- Collision and Constraint Checking ---\n            \n            // 1. Basic validity of destination\n            if (!is_valid(intended_next_pos.first, intended_next_pos.second)) {\n                action_possible = false; // Cannot move out of bounds\n            }\n\n            // 2. Check for crane-crane conflicts at destination (intended_next_pos)\n            // This check depends on the state *after* higher priority cranes have committed their moves.\n            // `next_crane_id_at` stores committed crane positions for the next turn.\n            if (action_possible && intended_next_pos != current_pos && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1) {\n                // Destination is occupied by another crane. Since `next_crane_id_at` is updated progressively,\n                // if it's occupied by `occupying_crane_id` != `k`, it means `occupying_crane_id` has higher or equal priority and has already committed to being there.\n                // Thus, crane `k` cannot move to `intended_next_pos`.\n                action_possible = false; \n            }\n\n            // 3. Small crane carrying container to a cell with a container (not allowed)\n            if (action_possible && !current_crane_state.is_large && current_crane_state.holding_container_id != -1) {\n                if (grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Small crane carrying cannot move to cell with a container\n                }\n            }\n            \n            // 4. If intended action is Pick/Drop, check if the cell itself is valid for the action\n            if (action_possible && (intended_action_char == 'P' || intended_action_char == 'Q')) {\n                // Cell must contain the container for 'P', and be empty for 'Q' (except for the crane)\n                // Check if the cell has a container if trying to pick up\n                if (intended_action_char == 'P' && grid[current_pos.first][current_pos.second] == -1) {\n                    action_possible = false; // Cannot pick up from empty cell\n                }\n                // Check if the cell is already occupied by a container if trying to drop\n                // This check must consider the state *after* crane movement, so check `grid` at `intended_next_pos`.\n                if (intended_action_char == 'Q' && grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Cannot drop into an occupied cell\n                }\n                // If attempting P/Q, the destination cell must not be occupied by another crane.\n                // This is already handled by point 2 for movement, but P/Q is an action at the *current* pos or *intended_next_pos*.\n                // If action is 'P', current_pos = intended_next_pos.\n                // If action is 'Q', intended_next_pos is the target.\n                if (next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1 && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != k) {\n                     action_possible = false; // Cannot P/Q if destination cell occupied by other crane\n                }\n            }\n\n\n            if (action_possible) {\n                // Crane k successfully commits to its action and move.\n                final_crane_action[k] = intended_action_char;\n                final_crane_pos[k] = intended_next_pos;\n                crane_action_committed[k] = true;\n\n                // Update crane's holding status and grid state if 'P' or 'Q'\n                if (intended_action_char == 'P') {\n                    // Crane picks up container from its current cell.\n                    int container_id = grid[current_pos.first][current_pos.second]; \n                    grid[current_pos.first][current_pos.second] = -1; // Remove container from cell\n                    final_crane_holding[k] = container_id; // Crane now holds it\n                } else if (intended_action_char == 'Q') {\n                    // Crane drops container at its intended next position.\n                    int container_id = current_crane_state.holding_container_id;\n                    grid[intended_next_pos.first][intended_next_pos.second] = container_id; // Place container in destination cell\n                    final_crane_holding[k] = -1; // Crane no longer holds it\n                }\n                \n                // Update `next_crane_id_at` for collision detection for *subsequent* (lower priority) cranes in this turn.\n                // Mark old position as empty, new position as occupied by crane k.\n                if (current_pos != intended_next_pos) { // Only update if crane actually moved\n                    next_crane_id_at[current_pos.first][current_pos.second] = -1; \n                    next_crane_id_at[intended_next_pos.first][intended_next_pos.second] = k;\n                } else {\n                    // If crane stayed put (action '.' or 'P'/'Q' at same spot), its position in next_crane_id_at is already correct from initialization.\n                    // If P/Q happened at current_pos, it still occupies current_pos.\n                }\n            } else {\n                // Crane k is blocked or action is impossible. It stays put and does nothing.\n                final_crane_action[k] = '.';\n                final_crane_pos[k] = current_pos; // Stays at current position\n                final_crane_holding[k] = current_crane_state.holding_container_id; // Holding status unchanged\n                // crane_action_committed[k] remains false. Its position in next_crane_id_at is unchanged.\n            }\n        }\n        \n        // Apply the final state changes for all cranes after conflict resolution.\n        for(int i=0; i<N; ++i) {\n            cranes[i].pos = final_crane_pos[i];\n            cranes[i].holding_container_id = final_crane_holding[i];\n            output_ops[i] += final_crane_action[i];\n        }\n        // Update crane_id_at to reflect the final positions for the START of the next turn.\n        crane_id_at = next_crane_id_at; \n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; ++i) { // For each dispatch gate row i\n            if (dispatch_gate_expected_container[i] != -1 && grid[i][N - 1] != -1) {\n                if (grid[i][N - 1] == dispatch_gate_expected_container[i]) {\n                    // Dispatch container\n                    grid[i][N - 1] = -1; // Remove from dispatch gate\n                    \n                    // Update expected container for this dispatch gate\n                    dispatch_gate_expected_container[i]++;\n                    if (dispatch_gate_expected_container[i] >= N * (i + 1)) {\n                        dispatch_gate_expected_container[i] = -1; // All containers for this gate dispatched\n                    }\n                }\n            }\n        }\n        \n        // Optional: Early exit condition if all containers are dispatched.\n        // This might save time if the simulation finishes before MAX_TURNS.\n        bool all_dispatched = true;\n        for(int i=0; i<N; ++i) {\n            if (dispatch_gate_expected_container[i] != -1) {\n                all_dispatched = false;\n                break;\n            }\n        }\n        if (all_dispatched && turn > 0) { // Check if all were dispatched in this turn or previous\n             // Break loop, padding will handle the rest.\n             // However, the problem states output length must be between 1 and 10000.\n             // So, we must ensure padding up to MAX_TURNS if we break early.\n             // The padding at the end handles this.\n             break; \n        }\n    }\n\n    // Pad output strings with '.' if they are shorter than MAX_TURNS\n    for (int i = 0; i < N; ++i) {\n        while (output_ops[i].length() < MAX_TURNS) {\n            output_ops[i] += '.';\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << output_ops[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n\nusing namespace std;\n\nint N;\nvector<vector<int>> current_height;\npair<int, int> current_pos;\nlong long truck_load;\nvector<string> operations;\n\n// Helper to add an operation to the list.\nvoid add_op(const string& op) {\n    operations.push_back(op);\n}\n\n// Helper to add a load ('+') or unload ('-') operation with a specified amount 'd'.\nvoid add_load_unload(char type, long long d) {\n    // The problem statement specifies d > 0 for load/unload.\n    // Our logic derives d from height differences, which are at most 100, so d will always be > 0 if called.\n    add_op(string(1, type) + to_string(d));\n}\n\n// Helper function to move the truck from its current position to a target cell.\n// It generates the sequence of move operations ('U', 'D', 'L', 'R') and updates current_pos.\nvoid move_to(int target_r, int target_c) {\n    // Move vertically: Up or Down\n    while (current_pos.first < target_r) {\n        add_op(\"D\");\n        current_pos.first++;\n    }\n    while (current_pos.first > target_r) {\n        add_op(\"U\");\n        current_pos.first--;\n    }\n    // Move horizontally: Left or Right\n    while (current_pos.second < target_c) {\n        add_op(\"R\");\n        current_pos.second++;\n    }\n    while (current_pos.second > target_c) {\n        add_op(\"L\");\n        current_pos.second--;\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output, crucial for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the grid size N.\n    cin >> N;\n\n    // Initialize the current_height grid with input heights. This grid will be modified as soil is moved.\n    current_height.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> current_height[i][j];\n        }\n    }\n\n    // Initialize truck state: starting at (0,0) with an empty load.\n    current_pos = {0, 0};\n    truck_load = 0;\n\n    // --- Define a systematic traversal path (Snake Pattern) ---\n    // This path visits every cell in the grid exactly once. It's chosen as a heuristic\n    // to ensure all cells are processed and to provide a structured, deterministic movement.\n    // The path order is (0,0) -> (0,1) -> ... -> (0,N-1) -> (1,N-1) -> (1,N-2) -> ... -> (1,0) -> (2,0) -> ...\n    vector<pair<int, int>> snake_path;\n    snake_path.reserve(N * N); // Reserve memory to avoid reallocations for efficiency.\n    for (int r = 0; r < N; ++r) {\n        if (r % 2 == 0) { // Even rows: traverse from left to right.\n            for (int c = 0; c < N; ++c) {\n                snake_path.push_back({r, c});\n            }\n        } else { // Odd rows: traverse from right to left.\n            for (int c = N - 1; c >= 0; --c) {\n                snake_path.push_back({r, c});\n            }\n        }\n    }\n\n    // --- Pass 1: Collect all positive soil ---\n    // The goal of this pass is to visit all cells that initially have positive height\n    // and load all of their soil onto the truck. This ensures all soil that needs to be\n    // moved out of positive cells is gathered before distribution.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell in the snake path.\n\n        // If the cell has excess soil (positive height), load it onto the truck.\n        if (current_height[r][c] > 0) {\n            long long amount_to_load = current_height[r][c]; // The amount to load is the entire positive height.\n            add_load_unload('+', amount_to_load); // Add the load operation.\n            truck_load += amount_to_load; // Update truck's current load.\n            current_height[r][c] = 0; // The cell's height becomes zero after its excess soil is loaded.\n        }\n    }\n\n    // --- Pass 2: Distribute soil to negative cells ---\n    // After collecting all available soil in Pass 1, this pass aims to unload soil\n    // into cells that need it (have negative height).\n    // The truck's position `current_pos` is already at the end of the last move from Pass 1,\n    // allowing for continuous movement through the grid for this pass.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If the cell needs soil (has negative height).\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c]; // Calculate how much soil is needed (absolute value of negative height).\n            // Unload the minimum of what's needed for this cell and what's currently available on the truck.\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) { // If we can unload any soil (i.e., truck has soil and cell needs it).\n                add_load_unload('-', to_unload); // Add the unload operation.\n                truck_load -= to_unload; // Update truck's load.\n                current_height[r][c] += to_unload; // Add soil to the cell, reducing its deficit.\n            }\n        }\n    }\n\n    // --- Pass 3: Deliver any remaining truck load ---\n    // This is a crucial cleanup pass designed to resolve any remaining imbalances.\n    // It addresses two potential scenarios:\n    // 1. If `truck_load` is still positive after Pass 2, it means there's soil left on the truck\n    //    that needs to be delivered to some cell.\n    // 2. If some cells still have negative height after Pass 2, they still require soil.\n    // The snake path is traversed for a third time. This ensures that any remaining soil on the truck\n    // is delivered to cells that still have a deficit, thereby bringing all cell heights to zero.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        move_to(r, c); // Move the truck to the current cell.\n\n        // If this cell still needs soil, unload from the truck.\n        if (current_height[r][c] < 0) {\n            long long needed = -current_height[r][c];\n            long long to_unload = min(needed, truck_load);\n            \n            if (to_unload > 0) {\n                add_load_unload('-', to_unload);\n                truck_load -= to_unload;\n                current_height[r][c] += to_unload;\n            }\n        }\n    }\n\n    // The problem statement guarantees that the sum of initial heights across the grid is exactly 0.\n    // This fundamental property ensures that the total amount of soil loaded in Pass 1 will be\n    // exactly equal to the total amount of soil that needs to be unloaded into negative-height cells.\n    // Therefore, after these three passes, `truck_load` is guaranteed to be 0, and all `current_height` values\n    // are guaranteed to be 0. No further loops or checks are needed to ensure all cells are leveled.\n    // The `min(needed, truck_load)` logic in Passes 2 and 3 handles the distribution correctly.\n\n    // Output all the generated operations, one per line.\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <numeric> // Not strictly necessary as sum is manual, but good practice to include if using numeric algorithms.\n#include <algorithm> // For std::sort\n\n// Use long long for sums to avoid potential overflow.\n// With M=15 and max value 100 per component, the max sum for a single seed is 15*100 = 1500,\n// which fits in a 32-bit integer. However, using `long long` is safer practice and has no performance penalty here.\nusing ll = long long;\n\n// Structure to hold seed information: its identifier, evaluation vector, and sum of values.\nstruct Seed {\n    int id; // Identifier of the seed within the current generation (0 to seed_count-1).\n    std::vector<int> evaluation_vector;\n    ll sum_v;\n\n    // Custom comparison operator for sorting seeds by sum_v in descending order.\n    // std::sort uses operator< to sort in ascending order. By defining it such that\n    // `a < b` if `a.sum_v > b.sum_v`, we achieve descending order sorting.\n    bool operator<(const Seed& other) const {\n        return sum_v > other.sum_v;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // Disables synchronization with C stdio and unties cin from cout for faster I/O.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, T;\n    std::cin >> N >> M >> T;\n\n    // Total number of seeds in each generation.\n    // For N=6, this is 2 * 6 * (6 - 1) = 2 * 6 * 5 = 60 seeds.\n    int seed_count = 2 * N * (N - 1);\n\n    // Vector to hold the current generation of seeds.\n    std::vector<Seed> current_seeds(seed_count);\n\n    // Read initial seeds. Their initial indices are implicitly 0, 1, ..., seed_count-1.\n    for (int i = 0; i < seed_count; ++i) {\n        current_seeds[i].id = i; // Assign initial ID for this seed.\n        current_seeds[i].evaluation_vector.resize(M);\n        ll current_sum = 0;\n        for (int j = 0; j < M; ++j) {\n            std::cin >> current_seeds[i].evaluation_vector[j];\n            current_sum += current_seeds[i].evaluation_vector[j];\n        }\n        current_seeds[i].sum_v = current_sum;\n    }\n\n    // Main loop for T turns of the operation.\n    for (int t = 0; t < T; ++t) {\n        // 1. Sort the current seeds based on their sum_v in descending order.\n        // The `std::sort` function uses the `operator<` defined in the `Seed` struct.\n        std::sort(current_seeds.begin(), current_seeds.end());\n\n        // 2. Select the top N*N seeds for planting.\n        // These are the first N*N seeds in the sorted `current_seeds` vector.\n        // We need to output their `id`s arranged in the N*N grid.\n        std::vector<std::vector<int>> A(N, std::vector<int>(N));\n        \n        // Assign selected seeds to grid cells in row-major order.\n        // The seed placed at A[i][j] is the (i*N + j)-th best seed from the sorted list.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                // `current_seeds[i * N + j]` refers to the Seed struct which is the (i*N + j)-th best.\n                // Its `id` field holds the identifier of this seed within the current generation.\n                A[i][j] = current_seeds[i * N + j].id;\n            }\n        }\n\n        // 3. Output the grid assignment to standard output.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                std::cout << A[i][j] << (j == N - 1 ? \"\" : \" \"); // Space separated values, no space after last element in a row.\n            }\n            std::cout << std::endl; // Newline after each row.\n        }\n        std::cout.flush(); // Ensure the output is sent immediately to the judge.\n\n        // 4. Read the evaluation vectors of the newly generated seeds for the next generation.\n        std::vector<Seed> next_seeds(seed_count);\n        for (int i = 0; i < seed_count; ++i) {\n            // Assign new sequential IDs (0 to seed_count-1) for the seeds in the next generation.\n            next_seeds[i].id = i; \n            next_seeds[i].evaluation_vector.resize(M);\n            ll current_sum = 0;\n            for (int j = 0; j < M; ++j) {\n                std::cin >> next_seeds[i].evaluation_vector[j];\n                current_sum += next_seeds[i].evaluation_vector[j];\n            }\n            next_seeds[i].sum_v = current_sum;\n        }\n\n        // 5. Replace the current seeds with the newly generated ones.\n        // `std::move` is used for efficiency, as it transfers ownership of the\n        // `next_seeds` vector's internal buffer to `current_seeds` without copying elements.\n        current_seeds = std::move(next_seeds);\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <numeric> // For std::iota\n\n// Global variables for grid and arm parameters\nint N_GRID, M_TAKOYAKI, V_ARM;\n\n// Structure for 2D points\nstruct Point {\n    int r, c;\n    // Equality operators for comparisons\n    bool operator==(const Point& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Manhattan distance for grid movement cost\nint manhattan_distance(Point p1, Point p2) {\n    return std::abs(p1.r - p2.r) + std::abs(p1.c - p2.c);\n}\n\n// --- Arm Design Parameters ---\nint V_prime; // Actual number of vertices in the arm (<= V_ARM)\nstd::vector<int> parent_map; // parent_map[i] is parent of vertex i+1 (0-indexed for edge array)\nstd::vector<int> edge_lengths; // edge_lengths[i] is length of edge connected to vertex i+1\nstd::vector<int> edge_orientations; // Current orientation of edges: 0:R(0,+1), 1:D(+1,0), 2:L(0,-1), 3:U(-1,0)\n\nPoint root_pos; // Current position of the arm's root\nstd::vector<Point> vertex_pos; // Stores current positions of all arm vertices\nstd::vector<int> fingertip_vertex_ids; // Vertex IDs that are fingertips\nstd::vector<int> joint_vertex_ids; // Vertex IDs that are joints (internal nodes, can rotate subtrees)\n\n// Direction vectors for R, D, L, U\nint dr[] = {0, 1, 0, -1}; // Corresponds to orientations 0, 1, 2, 3\nint dc[] = {1, 0, -1, 0}; // Corresponds to orientations 0, 1, 2, 3\n\n// Function to calculate the positions of all vertices based on root_pos and edge_orientations\nvoid calculate_vertex_positions() {\n    vertex_pos.assign(V_prime, {0, 0});\n    vertex_pos[0] = root_pos;\n\n    // Use BFS-like approach to calculate positions layer by layer\n    // For a tree, we can use a queue or simply iterate based on parent-child relationships.\n    // Let's build adjacency list for easier traversal.\n    std::vector<std::vector<std::pair<int, int>>> adj(V_prime); // {child_vertex_id, edge_index}\n    std::vector<int> edge_idx_for_child(V_prime, -1); // edge_idx_for_child[v] gives index for edge (p,v)\n\n    for (int i = 0; i < V_prime - 1; ++i) {\n        int p = parent_map[i];\n        int child = i + 1; // Vertex ID of child in path graph\n        adj[p].push_back({child, i});\n        edge_idx_for_child[child] = i;\n    }\n\n    std::vector<int> q;\n    q.push_back(0);\n    std::vector<bool> visited(V_prime, false);\n    visited[0] = true;\n\n    int head = 0;\n    while(head < q.size()) {\n        int u = q[head++];\n        \n        // Iterate through children of u\n        for (auto& edge_info : adj[u]) {\n            int v = edge_info.first;\n            int edge_idx = edge_info.second;\n\n            if (!visited[v]) {\n                int orientation = edge_orientations[edge_idx];\n                int length = edge_lengths[edge_idx];\n                \n                vertex_pos[v].r = vertex_pos[u].r + dr[orientation] * length;\n                vertex_pos[v].c = vertex_pos[u].c + dc[orientation] * length;\n                \n                q.push_back(v);\n                visited[v] = true;\n            }\n        }\n    }\n}\n\n// --- Takoyaki and Target Management ---\nstruct Takoyaki {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_taken; // Whether this takoyaki is currently held by a fingertip\n};\nstruct Target {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_filled; // Whether this target square is occupied by a takoyaki\n};\n\nstd::vector<Takoyaki> takoyaki_list;\nstd::vector<Target> target_list;\n\n// --- Fingertip State Management ---\nstruct Fingertip {\n    int vertex_id; // The vertex ID of this fingertip in the arm\n    bool is_holding; // True if currently holding a takoyaki\n    int holding_takoyaki_idx; // Index in takoyaki_list if holding, -1 otherwise\n    int assigned_pickup_source_idx; // Index in takoyaki_list for planned pickup, -1 if none\n    int assigned_drop_target_idx; // Index in target_list for planned drop, -1 if none\n};\nstd::vector<Fingertip> fingertips;\n\n// --- Operation String Generation ---\n// Generates the operation string for the current turn.\nstd::string generate_operation_string(int current_turn) {\n    std::string S(2 * V_prime, '.'); // Initialize with no operations\n\n    // 1. Update Arm Positions: Calculate current positions of all vertices.\n    calculate_vertex_positions();\n\n    // 2. Task Assignment: Assign takoyaki to free fingertips and targets to holding fingertips.\n    // Reset previous assignments for this turn.\n    for (auto& ft : fingertips) {\n        ft.assigned_pickup_source_idx = -1;\n        ft.assigned_drop_target_idx = -1;\n    }\n    \n    // Greedily assign pickups to fingertips that are not holding anything.\n    std::vector<bool> source_assigned_for_pickup(takoyaki_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (!ft.is_holding) { // If fingertip is empty\n            int best_takoyaki_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2; // Initialize with a large distance\n\n            // Find the closest available takoyaki\n            for (size_t j = 0; j < takoyaki_list.size(); ++j) {\n                if (!takoyaki_list[j].is_taken && !source_assigned_for_pickup[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], takoyaki_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_takoyaki_idx = j;\n                    }\n                }\n            }\n            // Assign the best takoyaki if found\n            if (best_takoyaki_idx != -1) {\n                ft.assigned_pickup_source_idx = best_takoyaki_idx;\n                source_assigned_for_pickup[best_takoyaki_idx] = true;\n            }\n        }\n    }\n\n    // Greedily assign drops to fingertips that are holding a takoyaki.\n    std::vector<bool> target_assigned_for_drop(target_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (ft.is_holding) { // If fingertip is holding\n            int best_target_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2;\n\n            // Find the closest available target\n            for (size_t j = 0; j < target_list.size(); ++j) {\n                if (!target_list[j].is_filled && !target_assigned_for_drop[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], target_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_target_idx = j;\n                    }\n                }\n            }\n            // Assign the best target if found\n            if (best_target_idx != -1) {\n                ft.assigned_drop_target_idx = best_target_idx;\n                target_assigned_for_drop[best_target_idx] = true;\n            }\n        }\n    }\n    \n    // 3. Determine Root Move (S[0])\n    int total_delta_r = 0;\n    int total_delta_c = 0;\n    int num_tasks_with_goal = 0;\n\n    // Calculate the aggregated movement required by all fingertips towards their goals\n    for (auto& ft : fingertips) {\n        Point current_pos = vertex_pos[ft.vertex_id];\n        Point goal_pos = {-1, -1}; // Sentinel value indicating no assigned goal\n\n        if (ft.is_holding) { // If holding, the goal is to reach its assigned drop target\n            if (ft.assigned_drop_target_idx != -1) {\n                goal_pos = target_list[ft.assigned_drop_target_idx].pos;\n            }\n        } else { // If not holding, the goal is to reach its assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1) {\n                goal_pos = takoyaki_list[ft.assigned_pickup_source_idx].pos;\n            }\n        }\n\n        // If a goal is assigned, contribute its delta to the total\n        if (goal_pos.r != -1) {\n            total_delta_r += (goal_pos.r - current_pos.r);\n            total_delta_c += (goal_pos.c - current_pos.c);\n            num_tasks_with_goal++;\n        }\n    }\n\n    // Determine the dominant direction for root movement\n    char root_move = '.'; // Default to no movement\n    if (num_tasks_with_goal > 0) {\n        int abs_delta_r = std::abs(total_delta_r);\n        int abs_delta_c = std::abs(total_delta_c);\n\n        // Prioritize movement in the direction with larger displacement sum\n        if (abs_delta_r > abs_delta_c) {\n            if (total_delta_r > 0) root_move = 'D'; // Move Down if total delta_r is positive\n            else if (total_delta_r < 0) root_move = 'U'; // Move Up if total delta_r is negative\n        } else if (abs_delta_c > abs_delta_r) {\n            if (total_delta_c > 0) root_move = 'R'; // Move Right if total delta_c is positive\n            else if (total_delta_c < 0) root_move = 'L'; // Move Left if total delta_c is negative\n        } else { // If tied, pick one direction, e.g., prefer vertical then horizontal\n            if (total_delta_r > 0) root_move = 'D';\n            else if (total_delta_r < 0) root_move = 'U';\n            else if (total_delta_c > 0) root_move = 'R';\n            else if (total_delta_c < 0) root_move = 'L';\n        }\n    }\n    S[0] = root_move; // Set the root movement character\n\n    // 4. Rotations (S[1] to S[V_prime-1])\n    // Currently, this strategy does NOT implement rotations for simplicity and speed.\n    // All rotation characters remain '.'\n    // If performance is insufficient, rotations for joints (vertices 1 to V_prime-2) could be added.\n\n    // 5. Fingertip Actions (S[V_prime] to S[2*V_prime-1])\n    // The action for vertex `vid` is at index `V_prime + vid` in string S.\n    for (const auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = '.'; // Default to no action\n        Point current_pos = vertex_pos[vid];\n        \n        if (ft.is_holding) { // If currently holding a takoyaki\n            // Check if at the assigned drop target\n            if (ft.assigned_drop_target_idx != -1 && current_pos == target_list[ft.assigned_drop_target_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        } else { // If not holding any takoyaki\n            // Check if at the assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1 && current_pos == takoyaki_list[ft.assigned_pickup_source_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        }\n        S[V_prime + vid] = action; // Set the action character for this vertex\n    }\n\n    return S;\n}\n\n// --- State Update Function ---\n// Applies the operations from the generated string and updates the game state.\nvoid apply_operation(const std::string& op_string) {\n    // Update root position based on the first character (root move)\n    char root_move = op_string[0];\n    if (root_move == 'U') root_pos.r--;\n    else if (root_move == 'D') root_pos.r++;\n    else if (root_move == 'L') root_pos.c--;\n    else if (root_move == 'R') root_pos.c++;\n\n    // Update rotations - THIS PART IS NOT IMPLEMENTED FOR NOW.\n    // The logic would go here if rotations were to be used.\n\n    // Apply fingertip actions ('P' for pickup/drop)\n    for (auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = op_string[V_prime + vid]; // Action character for this vertex\n        \n        if (action == 'P') {\n            if (ft.is_holding) { // Finger was holding, attempting to drop\n                int target_idx = ft.assigned_drop_target_idx;\n                // Check if the fingertip is at the assigned target location\n                if (target_idx != -1 && target_list[target_idx].pos == vertex_pos[vid]) {\n                    // Successfully dropped takoyaki\n                    target_list[target_idx].is_filled = true; // Mark target as filled\n                    takoyaki_list[ft.holding_takoyaki_idx].is_taken = false; // Release the takoyaki from being \"taken\"\n                    \n                    ft.is_holding = false; // Fingertip is now empty\n                    ft.holding_takoyaki_idx = -1; // No longer holding a takoyaki\n                    ft.assigned_drop_target_idx = -1; // Clear the drop assignment\n                } else {\n                    // If 'P' action occurs but not at target, it's an invalid/ineffective action.\n                    // This indicates a potential issue in assignment or movement logic.\n                }\n            } else { // Finger was not holding, attempting to pick up\n                int source_idx = ft.assigned_pickup_source_idx;\n                // Check if the fingertip is at the assigned source location\n                if (source_idx != -1 && takoyaki_list[source_idx].pos == vertex_pos[vid]) {\n                    // Successfully picked up takoyaki\n                    takoyaki_list[source_idx].is_taken = true; // Mark takoyaki as taken\n                    ft.is_holding = true; // Fingertip is now holding\n                    ft.holding_takoyaki_idx = source_idx; // Record which takoyaki is held\n                    ft.assigned_pickup_source_idx = -1; // Clear the pickup assignment\n                } else {\n                    // If 'P' action occurs but not at source, it's an invalid/ineffective action.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Read input parameters\n    std::cin >> N_GRID >> M_TAKOYAKI >> V_ARM;\n\n    // Read initial takoyaki positions\n    takoyaki_list.resize(M_TAKOYAKI);\n    int current_takoyaki_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store takoyaki: {position, initial_index, is_taken=false}\n                takoyaki_list[current_takoyaki_idx] = {{i, j}, current_takoyaki_idx, false};\n                current_takoyaki_idx++;\n            }\n        }\n    }\n\n    // Read target positions\n    target_list.resize(M_TAKOYAKI);\n    int current_target_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store target: {position, initial_index, is_filled=false}\n                target_list[current_target_idx] = {{i, j}, current_target_idx, false};\n                current_target_idx++;\n            }\n        }\n    }\n\n    // --- Design the Robotic Arm ---\n    V_prime = V_ARM; // Use the maximum available vertices\n    parent_map.resize(V_prime - 1);\n    edge_lengths.resize(V_prime - 1);\n    edge_orientations.resize(V_prime - 1);\n    vertex_pos.resize(V_prime); // Pre-allocate space for vertex positions\n    fingertips.clear();\n    joint_vertex_ids.clear();\n\n    // Arm Design: Path graph 0-1-2-...-V-1\n    // Parent of vertex i+1 is vertex i.\n    // Edge lengths are uniformly 1.\n    // Initial edge orientations are all 0 (Right).\n    for (int i = 0; i < V_prime - 1; ++i) {\n        parent_map[i] = i;          // Parent of vertex i+1 is vertex i\n        edge_lengths[i] = 1;        // Edge length is 1\n        edge_orientations[i] = 0;   // Initial orientation is Right (0)\n    }\n\n    // Initial root position: Center of the grid.\n    root_pos = {N_GRID / 2, N_GRID / 2};\n\n    // Identify fingertips and joints based on the path graph structure.\n    if (V_prime == 1) {\n        // If only one vertex, it's the root and also a fingertip. No joints.\n        fingertip_vertex_ids.push_back(0);\n    } else {\n        // For V' > 1, vertices 0 and V'-1 are leaves (fingertips).\n        fingertip_vertex_ids.push_back(0);\n        fingertip_vertex_ids.push_back(V_prime - 1);\n        // Vertices 1 to V'-2 are internal nodes (joints) where rotations can occur.\n        for (int i = 1; i < V_prime - 1; ++i) {\n            joint_vertex_ids.push_back(i);\n        }\n    }\n\n    // Initialize fingertip state trackers.\n    fingertips.resize(fingertip_vertex_ids.size());\n    for (size_t i = 0; i < fingertip_vertex_ids.size(); ++i) {\n        fingertips[i].vertex_id = fingertip_vertex_ids[i];\n        fingertips[i].is_holding = false;\n        fingertips[i].holding_takoyaki_idx = -1; // Tracks index in takoyaki_list IF holding\n        fingertips[i].assigned_pickup_source_idx = -1; // Tracks index in takoyaki_list for planned pickup\n        fingertips[i].assigned_drop_target_idx = -1; // Tracks index in target_list for planned drop\n    }\n\n    // Output the designed robotic arm structure.\n    std::cout << V_prime << std::endl;\n    for (int i = 0; i < V_prime - 1; ++i) {\n        std::cout << parent_map[i] << \" \" << edge_lengths[i] << std::endl;\n    }\n    std::cout << root_pos.r << \" \" << root_pos.c << std::endl;\n\n    // --- Operation Phase ---\n    int delivered_count = 0;\n    int max_turns = 100000; // Set a limit to prevent TLE.\n\n    // Main loop for executing turns.\n    for (int turn = 0; turn < max_turns; ++turn) {\n        // If all takoyaki are delivered, stop early.\n        if (delivered_count == M_TAKOYAKI) {\n            break;\n        }\n\n        // Generate the operation string for the current turn.\n        std::string op_string = generate_operation_string(turn);\n        \n        // Output the operation string.\n        std::cout << op_string << std::endl;\n        \n        // Apply the generated operations to update the game state.\n        apply_operation(op_string);\n\n        // Recalculate the number of delivered takoyaki after applying operations.\n        delivered_count = 0;\n        for(const auto& target : target_list) {\n            if (target.is_filled) {\n                delivered_count++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <map>\n\nstruct Point {\n    int x, y;\n    int type; // 0 for mackerel, 1 for sardine\n};\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n;\n    std::cin >> n;\n\n    std::vector<Point> points(2 * n);\n    std::vector<int> x_coords_all, y_coords_all;\n    x_coords_all.reserve(2 * n);\n    y_coords_all.reserve(2 * n);\n\n    for (int i = 0; i < 2 * n; ++i) {\n        points[i].type = (i < n) ? 0 : 1;\n        std::cin >> points[i].x >> points[i].y;\n        x_coords_all.push_back(points[i].x);\n        y_coords_all.push_back(points[i].y);\n    }\n\n    // Sort and unique coordinates to get candidate boundary points.\n    std::sort(x_coords_all.begin(), x_coords_all.end());\n    x_coords_all.erase(std::unique(x_coords_all.begin(), x_coords_all.end()), x_coords_all.end());\n    std::sort(y_coords_all.begin(), y_coords_all.end());\n    y_coords_all.erase(std::unique(y_coords_all.begin(), y_coords_all.end()), y_coords_all.end());\n\n    // K_cand is the number of candidate coordinate values to consider along each axis.\n    // A larger K_cand increases the chances of finding an optimal rectangle but also increases runtime.\n    // K_cand = 100 is chosen to balance search space and performance.\n    int K_cand = 100; \n\n    std::vector<int> sx, sy;\n    sx.reserve(K_cand);\n    sy.reserve(K_cand);\n\n    // Always include the bounding box coordinates 0 and 100000.\n    sx.push_back(0);\n    sx.push_back(100000);\n    sy.push_back(0);\n    sy.push_back(100000);\n\n    // Select K_cand-2 points from all unique x-coordinates, attempting to space them evenly.\n    // This ensures candidate boundaries cover the distribution of points.\n    if (x_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            // Select index: (i * (total_unique - 1)) / (num_points_to_select - 1)\n            // This samples points from the available unique coordinates.\n            sx.push_back(x_coords_all[(i * (x_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (x_coords_all.size() > 0) {\n        // If there are fewer than 2 unique coordinates (excluding 0 and 100000 if they are not present),\n        // add some of the existing unique coordinates to ensure some variation.\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, x_coords_all.size()); ++i) {\n            sx.push_back(x_coords_all[i]);\n        }\n    }\n    \n    // Select K_cand-2 points from all unique y-coordinates, similar to x-coordinates.\n    if (y_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            sy.push_back(y_coords_all[(i * (y_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (y_coords_all.size() > 0) {\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, y_coords_all.size()); ++i) {\n            sy.push_back(y_coords_all[i]);\n        }\n    }\n    \n    // Sort and remove duplicates from candidate coordinates to ensure valid intervals.\n    std::sort(sx.begin(), sx.end());\n    sx.erase(std::unique(sx.begin(), sx.end()), sx.end());\n    std::sort(sy.begin(), sy.end());\n    sy.erase(std::unique(sy.begin(), sy.end()), sy.end());\n\n    int num_sx = sx.size();\n    int num_sy = sy.size();\n\n    // `grid_diff` is a 2D difference array.\n    // `grid_diff[i][j]` stores the value that starts contributing to cells starting at `sx[i]` and `sy[j]`.\n    // Specifically, it applies a value change to the grid cell starting at `[sx[i], sx[i+1]) x [sy[j], sy[j+1])`.\n    // The size is `num_sx` x `num_sy` to handle points correctly.\n    std::vector<std::vector<int>> grid_diff(num_sx, std::vector<int>(num_sy, 0));\n\n    for (const auto& p : points) {\n        // Determine the grid cell index `ix` for point `p.x`.\n        // `ix` should be the index `i` such that `sx[i] <= p.x < sx[i+1]`.\n        // `std::upper_bound(sx.begin(), sx.end(), p.x)` finds the first element `sx[k]` strictly greater than `p.x`.\n        // The index `k` indicates that `p.x` is in the interval `[sx[k-1], sx[k])`. So `ix = k-1`.\n        auto it_x = std::upper_bound(sx.begin(), sx.end(), p.x);\n        int ix = (it_x - sx.begin()) - 1;\n        \n        // Similarly, determine the grid cell index `iy` for point `p.y`.\n        auto it_y = std::upper_bound(sy.begin(), sy.end(), p.y);\n        int iy = (it_y - sy.begin()) - 1;\n        \n        int val = (p.type == 0 ? 1 : -1); // +1 for mackerel, -1 for sardine.\n\n        // Apply the difference array update.\n        // `val` is added at the top-left corner of the cell `(ix, iy)`.\n        // It's subtracted at `(ix+1, iy)` and `(ix, iy+1)` to limit its effect to the cell `(ix, iy)`.\n        // It's added back at `(ix+1, iy+1)` to correct the double subtraction.\n        // Indices must be within bounds.\n        if (ix < num_sx && iy < num_sy) {\n            grid_diff[ix][iy] += val;\n            if (ix + 1 < num_sx) grid_diff[ix + 1][iy] -= val;\n            if (iy + 1 < num_sy) grid_diff[ix][iy + 1] -= val;\n            if (ix + 1 < num_sx && iy + 1 < num_sy) grid_diff[ix + 1][iy + 1] += val;\n        }\n    }\n    \n    // `grid_ps[i][j]` will store the cumulative sum for the rectangle `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n    // This is computed using 2D prefix sums on `grid_diff`.\n    std::vector<std::vector<int>> grid_ps(num_sx, std::vector<int>(num_sy, 0));\n    for (int i = 0; i < num_sx; ++i) {\n        for (int j = 0; j < num_sy; ++j) {\n            grid_ps[i][j] = grid_diff[i][j];\n            if (i > 0) grid_ps[i][j] += grid_ps[i-1][j];\n            if (j > 0) grid_ps[i][j] += grid_ps[i][j-1];\n            if (i > 0 && j > 0) grid_ps[i][j] -= grid_ps[i-1][j-1];\n        }\n    }\n\n    // Lambda function `get_ps_val` to safely retrieve prefix sum values.\n    // It handles out-of-bounds indices (e.g., for calculations involving `index-1`) by returning 0.\n    // `grid_ps[r_idx][c_idx]` stores the sum of points `p` such that `p.x < sx[r_idx+1]` and `p.y < sy[c_idx+1]`.\n    auto get_ps_val = [&](int r_idx, int c_idx) {\n        if (r_idx < 0 || c_idx < 0) return 0;\n        // Clamp indices to be within the bounds of grid_ps.\n        // This handles cases where calculation might exceed max index.\n        r_idx = std::min(r_idx, num_sx - 1);\n        c_idx = std::min(c_idx, num_sy - 1);\n        return grid_ps[r_idx][c_idx];\n    };\n\n    long long max_score_diff = -2e18; // Initialize with a very small value to find the maximum.\n    int best_x1_idx = -1, best_x2_idx = -1, best_y1_idx = -1, best_y2_idx = -1;\n\n    // Iterate through all possible rectangles defined by pairs of candidate coordinates.\n    // A rectangle is defined by its bottom-left corner (sx[i1], sy[j1]) and top-right corner (sx[i2], sy[j2]).\n    for (int i1 = 0; i1 < num_sx; ++i1) {\n        for (int i2 = i1; i2 < num_sx; ++i2) {\n            for (int j1 = 0; j1 < num_sy; ++j1) {\n                for (int j2 = j1; j2 < num_sy; ++j2) {\n                    \n                    // Variable to store the score difference (mackerels - sardines) for the current rectangle.\n                    long long current_score_diff = 0; \n\n                    // Calculate the score for the rectangle defined by [sx[i1], sx[i2]] x [sy[j1], sy[j2]].\n                    // This score is calculated using the 2D prefix sums for a rectangle query:\n                    // Sum(X_max, Y_max) - Sum(X_min-1, Y_max) - Sum(X_max, Y_min-1) + Sum(X_min-1, Y_min-1)\n                    // Here, Sum(X, Y) denotes the sum of points `p` such that `p.x <= X` and `p.y <= Y`.\n                    // Using `grid_ps`:\n                    // Sum(sx[i2], sy[j2]) corresponds to `get_ps_val(i2, j2)`\n                    // Sum(sx[i1]-1, sy[j2]) corresponds to `get_ps_val(i1-1, j2)`\n                    // Sum(sx[i2], sy[j1]-1) corresponds to `get_ps_val(i2, j1-1)`\n                    // Sum(sx[i1]-1, sy[j1]-1) corresponds to `get_ps_val(i1-1, j1-1)`\n                    current_score_diff = get_ps_val(i2, j2) \n                                       - get_ps_val(i1 - 1, j2) \n                                       - get_ps_val(i2, j1 - 1) \n                                       + get_ps_val(i1 - 1, j1 - 1);\n\n                    // Calculate the perimeter of the rectangle.\n                    long long current_perimeter = 2LL * ((long long)(sx[i2] - sx[i1]) + (long long)(sy[j2] - sy[j1]));\n\n                    // Check if the perimeter constraint is satisfied.\n                    if (current_perimeter <= 400000LL) {\n                        // If the current rectangle has a better score difference, update the best found rectangle.\n                        if (current_score_diff > max_score_diff) {\n                            max_score_diff = current_score_diff;\n                            best_x1_idx = i1;\n                            best_x2_idx = i2;\n                            best_y1_idx = j1;\n                            best_y2_idx = j2;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If no valid rectangle was found (e.g., all rectangles exceeded perimeter, or all had non-positive score diff),\n    // default to a minimal valid rectangle: a single point at (0,0) if (0,0) is a candidate.\n    // The indices sx[0], sy[0] are always 0. So this effectively picks (0,0) as the rectangle.\n    // This rectangle has perimeter 0 and a score difference of 0 if no points are at (0,0),\n    // resulting in a score of max(0, 0+1)=1, which is a valid baseline.\n    if (best_x1_idx == -1) {\n        best_x1_idx = 0;\n        best_x2_idx = 0;\n        best_y1_idx = 0;\n        best_y2_idx = 0;\n    }\n    \n    // Output the 4 vertices of the best rectangle found.\n    // The vertices are (sx[best_x1_idx], sy[best_y1_idx]), (sx[best_x2_idx], sy[best_y1_idx]),\n    // (sx[best_x2_idx], sy[best_y2_idx]), and (sx[best_x1_idx], sy[best_y2_idx}).\n    std::cout << 4 << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y2_idx] << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y2_idx] << std::endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <utility> // for std::pair\n\n// Structure to hold noisy dimensions for a rectangle\nstruct Rect {\n    long long w_prime, h_prime;\n};\n\n// Structure to hold information about a rectangle after placement\nstruct PlacedRect {\n    int id; // original index of the rectangle\n    long long x, y, w, h; // position (top-left) and dimensions\n};\n\n// Structure to represent an entry in the output placement sequence for a turn\nstruct OutputEntry {\n    int p; // rectangle index\n    int r; // rotation (0: original, 1: 90 deg rotated)\n    char d; // direction ('U' for Up, 'L' for Left)\n    int b; // reference rectangle index (-1 for origin, or index in current_placed_rects)\n};\n\nint main() {\n    // Improve I/O performance\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N; // Number of rectangles\n    int T; // Number of turns\n    long long sigma; // Standard deviation of measurement error\n    std::cin >> N >> T >> sigma;\n\n    // Read noisy dimensions for each rectangle\n    std::vector<Rect> rects(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> rects[i].w_prime >> rects[i].h_prime;\n    }\n\n    // Pre-calculate the sum of (w'_i + h'_i) for all suffixes of rectangles.\n    // penalty_sum[k] will store sum_{i=k to N-1} (rects[i].w_prime + rects[i].h_prime).\n    // This is used to quickly calculate the penalty for unused rectangles.\n    std::vector<long long> penalty_sum(N + 1, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        penalty_sum[i] = penalty_sum[i + 1] + rects[i].w_prime + rects[i].h_prime;\n    }\n\n    // Main loop for each turn\n    for (int t = 0; t < T; ++t) {\n        // Variables to store the best placement strategy found for the current turn\n        std::vector<OutputEntry> best_output_sequence;\n        int best_n = 0; // Number of rectangles to place in this turn\n        long long best_turn_score = -1; // Score for the best strategy in this turn\n\n        // Iterate through all possible numbers of rectangles to place, from N down to 0.\n        // We try to place `num_to_place` rectangles, specifically indices 0, 1, ..., num_to_place - 1.\n        // This is because rectangles must be placed in ascending order of their original indices.\n        for (int num_to_place = N; num_to_place >= 0; --num_to_place) {\n            // Case: placing 0 rectangles.\n            if (num_to_place == 0) {\n                // The score is 0 (W+H) + penalty for all N unused rectangles.\n                long long current_score = 0 + 0 + penalty_sum[0];\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = 0;\n                    best_output_sequence.clear(); // Empty sequence\n                }\n                continue; // Move to the next iteration of `num_to_place`\n            }\n\n            // State for placing `num_to_place` rectangles:\n            std::vector<PlacedRect> current_placed_rects; // Stores info about rectangles placed so far in this attempt.\n            std::vector<OutputEntry> current_output_sequence; // Stores the placement instructions for this attempt.\n            bool possible_to_place_all = true; // Flag to check if all `num_to_place` can be placed validly.\n\n            long long current_max_W = 0; // Current bounding box width after placing rectangles so far.\n            long long current_max_H = 0; // Current bounding box height after placing rectangles so far.\n\n            // Attempt to place rectangles 0, 1, ..., num_to_place - 1 in order.\n            for (int i = 0; i < num_to_place; ++i) {\n                int current_rect_idx = i; // The original index of the rectangle being considered for placement.\n\n                // Define the two possible dimensions (original and rotated) for the current rectangle.\n                std::pair<long long, long long> dims[2];\n                dims[0] = {rects[current_rect_idx].w_prime, rects[current_rect_idx].h_prime}; // r = 0 (no rotation)\n                dims[1] = {rects[current_rect_idx].h_prime, rects[current_rect_idx].w_prime}; // r = 1 (rotated 90 degrees)\n\n                // Variables to track the best placement found for the current rectangle `i`.\n                long long best_x = -1, best_y = -1; // Best position (top-left corner)\n                int best_r = -1; // Best rotation option (0 or 1)\n                char best_d_char = ' '; // Best direction ('U' or 'L')\n                int best_b_idx_in_placed = -1; // Index of the reference rectangle in `current_placed_rects` (-1 if origin).\n                long long min_placement_cost = -1; // The cost (W+H) of the best found placement for this rectangle.\n\n                // Iterate through all possible reference rectangles.\n                // `b_place_idx` is the index in `current_placed_rects`. -1 refers to the origin (0,0).\n                for (int b_place_idx = -1; b_place_idx < current_placed_rects.size(); ++b_place_idx) {\n                    // Get reference rectangle's properties if b_place_idx is valid.\n                    long long ref_x = 0, ref_y = 0, ref_w = 0, ref_h = 0;\n                    if (b_place_idx != -1) {\n                        ref_x = current_placed_rects[b_place_idx].x;\n                        ref_y = current_placed_rects[b_place_idx].y;\n                        ref_w = current_placed_rects[b_place_idx].w;\n                        ref_h = current_placed_rects[b_place_idx].h;\n                    }\n\n                    // Iterate through rotation options (0 or 1).\n                    for (int r_opt = 0; r_opt < 2; ++r_opt) {\n                        long long W = dims[r_opt].first; // Width of the rectangle in this orientation.\n                        long long H = dims[r_opt].second; // Height of the rectangle in this orientation.\n\n                        // Iterate through placement directions ('U' or 'L').\n                        for (char d_char : {'U', 'L'}) {\n                            long long cur_x, cur_y; // Proposed position for the top-left corner.\n\n                            if (d_char == 'U') {\n                                // Place upwards: align left edge with ref's right edge, top edge with ref's bottom edge.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x + ref_w);\n                                cur_y = (b_place_idx == -1) ? 0 : (ref_y + ref_h);\n                            } else { // d_char == 'L'\n                                // Place leftwards: align right edge with ref's left edge, top edge with ref's top edge.\n                                // The resulting x-coordinate must be non-negative.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x - W);\n                                cur_y = (b_place_idx == -1) ? 0 : ref_y;\n                                \n                                // Constraint: rectangles must be placed in x >= 0 and y >= 0.\n                                // For 'L' placement, if `ref_x - W` results in a negative x-coordinate,\n                                // this specific alignment with `ref_x` is not possible without going left of the origin.\n                                // The rule implies stopping at x=0. If `ref_x < W`, the rectangle cannot be placed \n                                // such that its right edge is at `ref_x` AND its left edge is >= 0.\n                                // Thus, `ref_x` must be at least `W` for this alignment to be possible.\n                                if (cur_x < 0) { \n                                    continue; // This placement combination is invalid.\n                                }\n                            }\n\n                            // Calculate the resulting bounding box dimensions if this rectangle is placed at (cur_x, cur_y).\n                            // `current_max_W` and `current_max_H` store the bounding box of already placed rectangles.\n                            long long candidate_W = std::max(current_max_W, cur_x + W);\n                            long long candidate_H = std::max(current_max_H, cur_y + H);\n                            \n                            // The cost for this placement is the sum of the bounding box dimensions.\n                            long long current_placement_cost = candidate_W + candidate_H;\n\n                            // If this is the first valid placement found, or if it yields a better (smaller) cost, update best found.\n                            if (min_placement_cost == -1 || current_placement_cost < min_placement_cost) {\n                                min_placement_cost = current_placement_cost;\n                                best_x = cur_x;\n                                best_y = cur_y;\n                                best_r = r_opt;\n                                best_d_char = d_char;\n                                best_b_idx_in_placed = b_place_idx;\n                            }\n                        } // End of loop for `d_char`\n                    } // End of loop for `r_opt`\n                } // End of loop for `b_place_idx`\n\n                // If no valid placement was found for the current rectangle `i` with the current `num_to_place` setting.\n                if (best_x == -1) {\n                    possible_to_place_all = false; // This `num_to_place` strategy is not feasible.\n                    break; // Stop trying to place more rectangles for this `num_to_place` value.\n                }\n\n                // Record the best placement found for rectangle `i`.\n                current_placed_rects.push_back({current_rect_idx, best_x, best_y, dims[best_r].first, dims[best_r].second});\n                current_output_sequence.push_back({current_rect_idx, best_r, best_d_char, best_b_idx_in_placed});\n                \n                // Update the overall bounding box dimensions with the newly placed rectangle.\n                current_max_W = std::max(current_max_W, best_x + dims[best_r].first);\n                current_max_H = std::max(current_max_H, best_y + dims[best_r].second);\n\n            } // End of loop for `i` (placing rectangles 0 to num_to_place - 1)\n\n            // If we successfully placed all `num_to_place` rectangles:\n            if (possible_to_place_all) {\n                // Calculate the total score for this specific `num_to_place` strategy.\n                // Score = (final W + final H of placed rectangles) + (penalty sum of unused rectangles).\n                long long current_score = current_max_W + current_max_H + penalty_sum[num_to_place];\n                \n                // If this score is better than the best score found so far for this turn, update bests.\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = num_to_place;\n                    best_output_sequence = current_output_sequence;\n                }\n            }\n        } // End of loop for `num_to_place` (trying different counts of rectangles to place)\n\n        // Output the chosen placement strategy for the current turn.\n        std::cout << best_n << std::endl;\n        for (const auto& p : best_output_sequence) {\n            std::cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << std::endl;\n        }\n        std::cout << std::flush; // Ensure output is sent immediately.\n\n        // Read the measured bounding box dimensions for this turn.\n        // These are not used by the current strategy, but are required by the problem protocol.\n        long long measured_W_prime, measured_H_prime;\n        std::cin >> measured_W_prime >> measured_H_prime;\n    } // End of loop for turns `t`\n\n    return 0; // Program finished successfully.\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <tuple>\n\nusing namespace std;\n\n// Structure to store information about a representative of a DSU set.\n// Each representative corresponds to the root of a tree in our problem.\nstruct DSU_Rep_Info {\n    int root_vertex;    // The actual vertex ID that is the root of this tree.\n    int max_height;     // The maximum height among all vertices in this tree, relative to root_vertex.\n    long long sum_beauty; // The sum of beauty values of all vertices in this tree.\n};\n\nvector<int> dsu_parent; // Standard DSU parent array. dsu_parent[i] stores the parent of vertex i in the DSU structure.\nvector<DSU_Rep_Info> rep_info; // Stores information about each representative. Indexed by the representative's vertex ID.\n\n// Finds the representative of the set containing vertex v.\n// Implements path compression for efficiency.\nint find_set(int v) {\n    if (v == dsu_parent[v])\n        return v;\n    return dsu_parent[v] = find_set(dsu_parent[v]);\n}\n\n// Merges the set represented by root_c_repr into the set represented by root_p_repr.\n// This function is called when we decide to make the tree rooted at root_c_vertex a child\n// of the tree rooted at root_p_vertex.\n// root_p_repr: DSU representative of the parent tree.\n// root_c_repr: DSU representative of the child tree.\n// root_p_vertex: Actual vertex ID that is the root of the parent tree.\n// root_c_vertex: Actual vertex ID that is the root of the child tree.\n// H: Maximum allowed height for any vertex in any tree.\n// adj: Adjacency list of the graph. (Not used in this function, but kept as part of general graph processing.)\n// p: The final parent array to be constructed. p[v] will store the parent of vertex v, or -1 if v is a root.\n// rep_info: Reference to the vector storing DSU representative information.\n// dsu_parent: Reference to the DSU parent array.\nvoid union_sets(int root_p_repr, int root_c_repr, int root_p_vertex, int root_c_vertex, int H, const vector<vector<int>>& adj, vector<int>& p, vector<DSU_Rep_Info>& rep_info, vector<int>& dsu_parent) {\n    \n    // Perform the union in DSU structure: make root_c_repr's DSU tree point to root_p_repr.\n    dsu_parent[root_c_repr] = root_p_repr;\n    \n    // Update the parent pointer for the actual root of the child tree.\n    // The root of the child tree (root_c_vertex) now becomes a child of the root of the parent tree (root_p_vertex).\n    p[root_c_vertex] = root_p_vertex;\n\n    // Update the information for the new representative (root_p_repr).\n    // The sum of beauties is the sum of beauties of both trees.\n    rep_info[root_p_repr].sum_beauty += rep_info[root_c_repr].sum_beauty;\n    // The new maximum height is the maximum of the parent tree's height and the child tree's height increased by 1.\n    rep_info[root_p_repr].max_height = max(rep_info[root_p_repr].max_height, rep_info[root_c_repr].max_height + 1);\n    \n    // The actual root vertex of the merged component remains root_p_vertex.\n    rep_info[root_p_repr].root_vertex = root_p_vertex; \n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n; // Number of vertices\n    int m; // Number of edges\n    int h_limit; // Maximum allowed height\n    cin >> n >> m >> h_limit;\n\n    vector<long long> a(n); // Beauty values of vertices\n    for (int i = 0; i < n; ++i) {\n        cin >> a[i];\n    }\n\n    vector<vector<int>> adj(n); // Adjacency list for the graph\n    vector<pair<int, int>> edges; // List of all edges\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        edges.push_back({u, v});\n    }\n\n    // Initialize DSU structure. Initially, each vertex is in its own set.\n    dsu_parent.resize(n);\n    iota(dsu_parent.begin(), dsu_parent.end(), 0); // dsu_parent[i] = i for all i\n    \n    rep_info.resize(n);\n    for (int i = 0; i < n; ++i) {\n        // Initially, each vertex is a root of its own tree:\n        // root_vertex is itself, max_height is 0, sum_beauty is its own beauty value.\n        rep_info[i] = {i, 0, a[i]}; \n    }\n\n    // Priority queue to store potential merges.\n    // Stores tuples: {gain, h_child, h_parent_sum_beauty, h_parent_height, parent_root_repr_id, child_root_repr_id}.\n    // - gain: The sum of beauties of the component being merged (primary greedy criterion).\n    // - h_child: The maximum height of the child component (secondary criterion: prefer deeper children).\n    // - h_parent_sum_beauty: Sum of beauties of the parent component (tertiary criterion: prefer merging into higher-beauty parents).\n    // - h_parent_height: The maximum height of the parent component (quaternary criterion: prefer deeper parents).\n    // - parent_root_repr_id: Vertex ID of the representative of the parent component.\n    // - child_root_repr_id: Vertex ID of the representative of the child component.\n    // Using positive values for tie-breakers, as PQ is a max-heap.\n    priority_queue<tuple<long long, int, long long, int, int, int>> pq;\n\n    // Populate the priority queue with initial merge candidates.\n    // For each edge (u, v), consider merging the tree rooted at v into the tree rooted at u,\n    // and vice versa, provided the height constraint is met.\n    for (const auto& edge : edges) {\n        int u_vtx = edge.first;\n        int v_vtx = edge.second;\n\n        // Get current representatives for u_vtx and v_vtx\n        int root_u_repr = find_set(u_vtx);\n        int root_v_repr = find_set(v_vtx);\n\n        // If they are already in the same component, this edge doesn't form a new merge candidate between components.\n        if (root_u_repr == root_v_repr) continue;\n\n        // Option 1: Make v's component a child of u's component.\n        // Parent representative: root_u_repr, Child representative: root_v_repr.\n        if (rep_info[root_v_repr].max_height + 1 <= h_limit) {\n            long long gain = rep_info[root_v_repr].sum_beauty;\n            pq.push({gain, rep_info[root_v_repr].max_height, rep_info[root_u_repr].sum_beauty, rep_info[root_u_repr].max_height, root_u_repr, root_v_repr});\n        }\n        // Option 2: Make u's component a child of v's component.\n        // Parent representative: root_v_repr, Child representative: root_u_repr.\n        if (rep_info[root_u_repr].max_height + 1 <= h_limit) {\n            long long gain = rep_info[root_u_repr].sum_beauty;\n            pq.push({gain, rep_info[root_u_repr].max_height, rep_info[root_v_repr].sum_beauty, rep_info[root_v_repr].max_height, root_v_repr, root_u_repr});\n        }\n    }\n\n    // Initialize the final parent array. -1 indicates a root vertex.\n    vector<int> p(n, -1); \n\n    // Greedily process merges from the priority queue.\n    while (!pq.empty()) {\n        auto [gain, h_child, h_parent_sum_beauty, h_parent_height, parent_root_id, child_root_id] = pq.top();\n        pq.pop();\n\n        // Find current representatives.\n        int current_parent_repr = find_set(parent_root_id);\n        int current_child_repr = find_set(child_root_id);\n\n        // If they are already in the same set, this merge is redundant.\n        if (current_parent_repr == current_child_repr) continue;\n        \n        // Stale entry check: if the vertex IDs stored in PQ are no longer the current representatives.\n        if (current_parent_repr != parent_root_id || current_child_repr != child_root_id) {\n             continue; // Stale entry.\n        }\n\n        // Re-check height constraint using the current max heights from `rep_info`.\n        // The `h_child` from PQ is stale, we must use `rep_info[child_root_id].max_height`.\n        if (rep_info[child_root_id].max_height + 1 > h_limit) {\n            continue; // Height limit violated with the current configuration.\n        }\n\n        // Perform the union.\n        union_sets(parent_root_id, child_root_id, rep_info[parent_root_id].root_vertex, rep_info[child_root_id].root_vertex, h_limit, adj, p, rep_info, dsu_parent);\n    }\n\n    // Output the resulting parent array.\n    for (int i = 0; i < n; ++i) {\n        cout << p[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    cin >> n;\n\n    // Read the initial board configuration.\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> board[i];\n    }\n\n    // Precompute safety information for each cell.\n    // has_fuku_above[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k < r.\n    // has_fuku_below[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k > r.\n    // has_fuku_left[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k < c.\n    // has_fuku_right[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k > c.\n    // These precomputed values allow O(1) safety checks for each direction.\n    vector<vector<bool>> has_fuku_above(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_below(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_left(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_right(n, vector<bool>(n, false));\n\n    // Compute has_fuku_above and has_fuku_below for all columns.\n    for (int c = 0; c < n; ++c) {\n        bool found_fuku_in_col = false;\n        // Scan downwards: for each cell (r, c), check if any Fuku was found in previous rows (k < r).\n        for (int r = 0; r < n; ++r) {\n            has_fuku_above[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column above current row.\n            }\n        }\n        \n        found_fuku_in_col = false; // Reset for scanning downwards to compute has_fuku_below.\n        // Scan upwards: for each cell (r, c), check if any Fuku was found in subsequent rows (k > r).\n        for (int r = n - 1; r >= 0; --r) {\n            has_fuku_below[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column below current row.\n            }\n        }\n    }\n\n    // Compute has_fuku_left and has_fuku_right for all rows.\n    for (int r = 0; r < n; ++r) {\n        bool found_fuku_in_row = false;\n        // Scan rightwards: for each cell (r, c), check if any Fuku was found in previous columns (k < c).\n        for (int c = 0; c < n; ++c) {\n            has_fuku_left[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the left of current column.\n            }\n        }\n        \n        found_fuku_in_row = false; // Reset for scanning rightwards to compute has_fuku_right.\n        // Scan leftwards: for each cell (r, c), check if any Fuku was found in subsequent columns (k > c).\n        for (int c = n - 1; c >= 0; --c) {\n            has_fuku_right[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the right of current column.\n            }\n        }\n    }\n\n    // Stores the sequence of operations to be performed.\n    vector<pair<char, int>> operations;\n    const int INF = 1e9; // A large enough value to represent infinity for costs.\n\n    // Iterate through each cell of the board.\n    for (int r = 0; r < n; ++r) {\n        for (int c = 0; c < n; ++c) {\n            // If the cell contains an Oni ('x').\n            if (board[r][c] == 'x') {\n                // Find the safest and cheapest direction to remove this specific Oni.\n                // The goal is to minimize operations (T) for the score 8N^2 - T.\n                int min_cost = INF;\n                char best_op_char = ' ';\n                int best_op_idx = -1;\n\n                // --- Evaluate Upward push ---\n                // Cost: r + 1 operations. An Oni at (r,c) moves up to (0,c) in 'r' steps, and then is removed by the (r+1)th UP shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k < r. This is checked by !has_fuku_above[r][c].\n                if (!has_fuku_above[r][c]) {\n                    int cost = r + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'U'; // Upward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Downward push ---\n                // Cost: N - r operations. An Oni at (r,c) moves down to (N-1,c) in (N-1)-r steps, and then is removed by the (N-r)th DOWN shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k > r. This is checked by !has_fuku_below[r][c].\n                if (!has_fuku_below[r][c]) {\n                    int cost = n - r;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'D'; // Downward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Leftward push ---\n                // Cost: c + 1 operations. An Oni at (r,c) moves left to (r,0) in 'c' steps, and then is removed by the (c+1)th LEFT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k < c. This is checked by !has_fuku_left[r][c].\n                if (!has_fuku_left[r][c]) {\n                    int cost = c + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'L'; // Leftward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // --- Evaluate Rightward push ---\n                // Cost: N - c operations. An Oni at (r,c) moves right to (r,N-1) in (N-1)-c steps, and then is removed by the (N-c)th RIGHT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k > c. This is checked by !has_fuku_right[r][c].\n                if (!has_fuku_right[r][c]) {\n                    int cost = n - c;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'R'; // Rightward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // The problem guarantees that for every Oni, at least one direction is safe.\n                // Thus, min_cost will be less than INF and greater than or equal to 1.\n                // We add 'min_cost' operations of the chosen type. This ensures each Oni is removed.\n                // The total number of operations T will be the sum of these minimum costs for each Oni.\n                // This greedy strategy aims to minimize T by making the locally optimal choice for each Oni.\n                for (int k = 0; k < min_cost; ++k) {\n                    operations.push_back({best_op_char, best_op_idx});\n                }\n            }\n        }\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output each operation in the specified format.\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N; // Number of employees\nlong long L; // Total number of weeks\nvector<long long> T; // Target counts for each employee\n\n// l_counts[i] = ceil(T[i] / 2.0)\n// r_counts[i] = floor(T[i] / 2.0)\n// These represent the number of times employee i directs the process\n// to a_i (if its count becomes odd) or b_i (if its count becomes even).\nvector<long long> l_counts; \nvector<long long> r_counts; \n\n// current_O[j] stores the total count of \"odd-parity\" assignments directed to employee j.\n// This sum comes from all i such that a_i = j, contributing l_counts[i].\nvector<long long> current_O; \n// current_E[j] stores the total count of \"even-parity\" assignments directed to employee j.\n// This sum comes from all i such that b_i = j, contributing r_counts[i].\nvector<long long> current_E; \n\n// a[i] and b[i] store the chosen successors for employee i.\nvector<int> a;\nvector<int> b;\n\n// Calculates the total error based on current O and E counts.\n// Error is sum of absolute differences between target T_j and actual assignments (O_j + E_j).\nlong long calculate_total_error() {\n    long long error = 0;\n    for (int j = 0; j < N; ++j) {\n        error += abs((current_O[j] + current_E[j]) - T[j]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Precompute l_counts and r_counts for each employee\n    l_counts.resize(N);\n    r_counts.resize(N);\n    for (int i = 0; i < N; ++i) {\n        l_counts[i] = (T[i] + 1) / 2; // Equivalent to ceil(T[i] / 2.0)\n        r_counts[i] = T[i] / 2;      // Equivalent to floor(T[i] / 2.0)\n    }\n\n    current_O.resize(N, 0);\n    current_E.resize(N, 0);\n    a.resize(N);\n    b.resize(N);\n\n    // Initialize: each employee i initially directs assignments to itself.\n    // a[i] = i, b[i] = i.\n    // Update current_O and current_E based on this initial assignment.\n    for (int i = 0; i < N; ++i) {\n        a[i] = i;\n        b[i] = i;\n        current_O[i] += l_counts[i];\n        current_E[i] += r_counts[i];\n    }\n\n    // Calculate initial total error\n    long long current_total_error = calculate_total_error();\n\n    // The core of the solution is a local search heuristic.\n    // We iterate a fixed number of times. In each iteration, for each employee i,\n    // we try to find the best pair (u, v) for (a[i], b[i]) that minimizes the total error.\n    // The total number of iterations is a hyperparameter. For N=100, N^3 complexity per iteration\n    // implies a limit around 1000-2000 iterations to stay within time limits.\n    // We chose 1500 iterations as a balance between exploration and performance.\n    int num_iterations = 1500; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        bool improved_in_iter = false; // Flag to check if any improvement was made in this iteration\n\n        // Iterate through each employee i to potentially change their a[i] and b[i]\n        for (int i = 0; i < N; ++i) {\n            int old_a = a[i]; // Store old assignment for a[i]\n            int old_b = b[i]; // Store old assignment for b[i]\n            \n            // Keep track of the best assignment found so far for employee i in this iteration\n            int best_new_a = old_a;\n            int best_new_b = old_b;\n            long long min_err_for_i = current_total_error; // Minimum error achievable by changing a[i], b[i]\n\n            // Try all possible pairs (u, v) for (a[i], b[i])\n            for (int u = 0; u < N; ++u) { // New target for a[i]\n                for (int v = 0; v < N; ++v) { // New target for b[i]\n                    \n                    // Store current counts before modification for backtracking\n                    long long temp_O_old_a = current_O[old_a];\n                    long long temp_O_u = current_O[u];\n                    long long temp_E_old_b = current_E[old_b];\n                    long long temp_E_v = current_E[v];\n\n                    // --- Calculate potential new total error if a[i] becomes u and b[i] becomes v ---\n                    // We need to efficiently update current_O and current_E.\n                    // If old_a != u, the contribution of l_counts[i] shifts from old_a to u.\n                    // If old_b != v, the contribution of r_counts[i] shifts from old_b to v.\n                    \n                    // Revert contributions of old assignments\n                    if (old_a != u) {\n                        current_O[old_a] -= l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] -= r_counts[i];\n                    }\n                    \n                    // Apply new contributions\n                    if (old_a != u) {\n                        current_O[u] += l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[v] += r_counts[i];\n                    }\n\n                    // Handle cases where u == old_a or v == old_b.\n                    // If u == old_a, the l_counts[i] contribution remains at old_a, so current_O[old_a] and current_O[u] are unchanged relative to each other for THIS i's contribution.\n                    // The logic above handles this correctly: if old_a == u, we do not subtract from old_a and do not add to u, keeping them as they were.\n                    // Same applies for b[i] and v.\n                    // If u == v == old_a == old_b, no changes happen.\n\n                    // Calculate the new total error with these tentative assignments\n                    long long temp_error = calculate_total_error();\n\n                    // If this new assignment (u, v) results in a lower total error, update best found for i\n                    if (temp_error < min_err_for_i) {\n                        min_err_for_i = temp_error;\n                        best_new_a = u;\n                        best_new_b = v;\n                        improved_in_iter = true; // Mark that an improvement has been made\n                    }\n                    \n                    // --- Backtrack: restore counts to their state before trying this (u,v) pair ---\n                    // This is crucial because current_O and current_E are global and used for next (u,v) pair.\n                    if (old_a != u) {\n                        current_O[old_a] = temp_O_old_a; // Restore old_a's count\n                        current_O[u] = temp_O_u;         // Restore u's count\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] = temp_E_old_b; // Restore old_b's count\n                        current_E[v] = temp_E_v;         // Restore v's count\n                    }\n                }\n            }\n            \n            // After trying all (u,v) for employee i, apply the best found assignment\n            if (min_err_for_i < current_total_error) {\n                // Update the global counts based on the best move for employee i\n                // First, remove the contribution of the old assignment\n                if (old_a != best_new_a) {\n                    current_O[old_a] -= l_counts[i];\n                    current_O[best_new_a] += l_counts[i];\n                }\n                if (old_b != best_new_b) {\n                    current_E[old_b] -= r_counts[i];\n                    current_E[best_new_b] += r_counts[i];\n                }\n                \n                // Update a[i] and b[i] to the best choice\n                a[i] = best_new_a;\n                b[i] = best_new_b;\n                current_total_error = min_err_for_i; // Update the global minimum error\n            }\n        }\n        // If no improvement was made in this iteration for any employee, we can stop early.\n        if (!improved_in_iter) {\n            break;\n        }\n    }\n\n    // Output the resulting a[i] and b[i] values\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n#include <numeric>\n#include <set>\n\n// Structure to hold city information\nstruct City {\n    int id;\n    long long lx, rx, ly, ry;\n    double est_x, est_y; // Estimated coordinates (center of bounding box)\n};\n\n// Structure to represent an edge with estimated weight for sorting\nstruct Edge {\n    int u, v;\n    long long weight; // Use estimated distance as weight\n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) {\n            return weight < other.weight;\n        }\n        if (u != other.u) {\n            return u < other.u;\n        }\n        return v < other.v;\n    }\n};\n\n// Disjoint Set Union (DSU) data structure for Kruskal's algorithm\nstruct DSU {\n    std::vector<int> parent;\n    DSU(int n) {\n        parent.resize(n);\n        std::iota(parent.begin(), parent.end(), 0); // Initialize each node as its own parent\n    }\n    // Find the root of the set containing element i\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n    // Unite the sets containing elements i and j\n    void unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j; // Union by rank/size can be added for optimization, but N is not extremely large\n        }\n    }\n};\n\n// Function to query MST for a subset of cities\n// Returns a vector of pairs (u, v) representing MST edges, sorted lexicographically.\nstd::vector<std::pair<int, int>> query_mst(const std::vector<int>& cities) {\n    std::cout << \"? \" << cities.size();\n    for (int city_idx : cities) {\n        std::cout << \" \" << city_idx;\n    }\n    std::cout << std::endl;\n\n    std::vector<std::pair<int, int>> mst_edges;\n    int l = cities.size();\n    for (int i = 0; i < l - 1; ++i) {\n        int u, v;\n        std::cin >> u >> v;\n        if (u > v) std::swap(u, v); // Ensure lexicographical order (u < v)\n        mst_edges.push_back({u, v});\n    }\n    // The problem states response is sorted lexicographically by (u,v) pair.\n    // No need to sort here.\n    return mst_edges;\n}\n\n// Calculate estimated Euclidean distance between two cities using their estimated coordinates\nlong long estimated_dist(const City& c1, const City& c2) {\n    long long dx = static_cast<long long>(std::round(c1.est_x)) - static_cast<long long>(std::round(c2.est_x));\n    long long dy = static_cast<long long>(std::round(c1.est_y)) - static_cast<long long>(std::round(c2.est_y));\n    return static_cast<long long>(std::sqrt(dx * dx + dy * dy));\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, Q, L, W;\n    std::cin >> N >> M >> Q >> L >> W;\n\n    std::vector<int> G(M); // Target sizes for each group\n    for (int i = 0; i < M; ++i) {\n        std::cin >> G[i];\n    }\n\n    std::vector<City> cities(N);\n    std::vector<int> p(N); // Permutation for sorting cities by estimated position\n    for (int i = 0; i < N; ++i) {\n        cities[i].id = i;\n        std::cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n        // Estimate city coordinates as the center of its bounding box\n        cities[i].est_x = (cities[i].lx + cities[i].rx) / 2.0;\n        cities[i].est_y = (cities[i].ly + cities[i].ry) / 2.0;\n        p[i] = i; // Initialize permutation with city indices\n    }\n\n    // Sort cities based on their estimated coordinates (lexicographically by x, then y)\n    std::sort(p.begin(), p.end(), [&](int i, int j) {\n        if (cities[i].est_x != cities[j].est_x) {\n            return cities[i].est_x < cities[j].est_x;\n        }\n        return cities[i].est_y < cities[j].est_y;\n    });\n\n    // Initial grouping: Assign cities greedily to groups based on sorted estimated positions\n    // This is a heuristic and may not be optimal, but provides a starting point.\n    std::vector<std::vector<int>> final_groups(M); // Stores city IDs for each group\n    std::vector<int> city_to_group_idx(N); // Maps city ID to its group index\n    int current_city_p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < G[k]; ++i) {\n            int city_id = p[current_city_p_idx++];\n            final_groups[k].push_back(city_id);\n            city_to_group_idx[city_id] = k;\n        }\n    }\n\n    // Store all discovered edges from queries. We don't get true weights, only pairs.\n    // We use estimated distance as a proxy weight for sorting and prioritization.\n    std::vector<Edge> collected_queried_edges;\n    std::set<std::pair<int, int>> queried_edge_pairs_set; // To efficiently check if an edge was queried\n\n    int queries_used = 0;\n\n    // Phase 1: Query groups that are small enough (size <= L) to get their exact MST edges.\n    // This uses one query per such group.\n    for (int k = 0; k < M; ++k) {\n        if (final_groups[k].size() <= L && queries_used < Q) {\n            std::vector<std::pair<int, int>> mst_edges = query_mst(final_groups[k]);\n            for (const auto& edge_pair : mst_edges) {\n                int u = edge_pair.first;\n                int v = edge_pair.second;\n                collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n                queried_edge_pairs_set.insert({u, v});\n            }\n            queries_used++;\n        }\n    }\n\n    // Phase 2: Use remaining queries to get more edges by querying overlapping windows.\n    // This strategy aims to cover all cities and discover relationships.\n    int num_windows_to_query = Q - queries_used;\n    for (int i = 0; i < num_windows_to_query; ++i) {\n        std::vector<int> subset;\n        // Create a subset of size L by taking L consecutive cities from the sorted list 'p'.\n        // Use modulo arithmetic for cyclic access to 'p' to ensure all cities can be part of some subset.\n        for (int j = 0; j < L; ++j) {\n            subset.push_back(p[(i + j) % N]);\n        }\n        // Ensure subset size is at least 2 for a valid query\n        if (subset.size() < 2) continue;\n        \n        std::vector<std::pair<int, int>> mst_edges = query_mst(subset);\n        for (const auto& edge_pair : mst_edges) {\n            int u = edge_pair.first;\n            int v = edge_pair.second;\n            collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(cities[u], cities[v]))});\n            queried_edge_pairs_set.insert({u, v});\n        }\n    }\n\n    // Sort all collected queried edges based on their estimated distances.\n    // This heuristic prioritizes queried edges that are likely to be shorter (and thus better for MST).\n    std::sort(collected_queried_edges.begin(), collected_queried_edges.end());\n\n    // Collect candidate edges for MST construction for each group.\n    // This includes all queried edges and all pairs not covered by queries, using estimated distances.\n    std::vector<Edge> all_candidate_edges;\n    for(const auto& edge : collected_queried_edges) {\n        all_candidate_edges.push_back(edge);\n    }\n\n    // Add edges based on estimated distances for pairs not covered by queries.\n    for(int i=0; i<N; ++i) {\n        for(int j=i+1; j<N; ++j) {\n            if(queried_edge_pairs_set.find({i, j}) == queried_edge_pairs_set.end()) {\n                 all_candidate_edges.push_back({i, j, static_cast<int>(estimated_dist(cities[i], cities[j]))});\n            }\n        }\n    }\n    // Sort all candidate edges by estimated weight\n    std::sort(all_candidate_edges.begin(), all_candidate_edges.end());\n\n    // Build the final MST for each group using the sorted candidate edges.\n    std::vector<std::vector<std::pair<int, int>>> final_group_edges(M);\n    for (int k = 0; k < M; ++k) {\n        DSU dsu(N); // Initialize DSU for all N cities to correctly track components across groups\n        \n        // Add edges greedily using Kruskal's algorithm\n        for (const auto& edge : all_candidate_edges) {\n            // We need G[k]-1 edges for group k. Stop if we have enough.\n            if (final_group_edges[k].size() >= G[k] - 1) break;\n\n            int u = edge.u;\n            int v = edge.v;\n\n            // Check if both cities belong to the current group k\n            if (city_to_group_idx[u] == k && city_to_group_idx[v] == k) {\n                // If adding this edge does not create a cycle within group k's MST\n                if (dsu.find(u) != dsu.find(v)) {\n                    dsu.unite(u, v);\n                    final_group_edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n\n    // Output the final answer: groups and their MST edges\n    std::cout << \"!\" << std::endl;\n    for (int k = 0; k < M; ++k) {\n        // Output cities in the group\n        for (int city_id : final_groups[k]) {\n            std::cout << city_id << \" \";\n        }\n        std::cout << std::endl;\n        // Output edges for the group's MST\n        for (const auto& edge : final_group_edges[k]) {\n            std::cout << edge.first << \" \" << edge.second << std::endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Global variables to store game state and parameters\nint N; // Size of the skating rink (N x N)\nint M; // Total number of points given in input (start position + M-1 targets)\nvector<pair<int, int>> all_points; // Stores all M points: start and targets\nset<pair<int, int>> blocks; // Stores coordinates of all placed blocks\npair<int, int> current_pos; // Current position of the player\n\n// --- Helper Functions ---\n\n// Checks if a given coordinate (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Returns the change in (row, column) for a given direction character.\npair<int, int> get_delta(char dir) {\n    if (dir == 'U') return {-1, 0}; // Up: decrease row\n    if (dir == 'D') return {1, 0};  // Down: increase row\n    if (dir == 'L') return {0, -1}; // Left: decrease column\n    if (dir == 'R') return {0, 1};  // Right: increase column\n    return {0, 0}; // Should not happen with valid input\n}\n\n// --- Game Simulation and Action Execution ---\n\n// Executes a chosen action and direction.\n// This function simulates the action's effect on the game state (current_pos, blocks)\n// and prints the action to standard output for the judge system.\nvoid execute_action(char action, char dir) {\n    pair<int, int> delta = get_delta(dir);\n    int dx = delta.first;\n    int dy = delta.second;\n\n    if (action == 'M') { // Move action\n        // Update current position by one step in the given direction.\n        current_pos.first += dx;\n        current_pos.second += dy;\n        cout << action << ' ' << dir << endl;\n    } else if (action == 'A') { // Alter action\n        // Calculate the coordinates of the adjacent square to alter.\n        int alter_r = current_pos.first + dx;\n        int alter_c = current_pos.second + dy;\n        \n        // Ensure the target square for alteration is within bounds.\n        if (is_valid(alter_r, alter_c)) {\n            // If a block exists, remove it. Otherwise, place a new block.\n            if (blocks.count({alter_r, alter_c})) {\n                blocks.erase({alter_r, alter_c});\n            } else {\n                blocks.insert({alter_r, alter_c});\n            }\n        }\n        cout << action << ' ' << dir << endl;\n        // The player's position (current_pos) does not change during an Alter action.\n    } else if (action == 'S') { // Slide action\n        int cx = current_pos.first;\n        int cy = current_pos.second;\n        int slide_dist = 0;\n        \n        // Simulate the slide step-by-step to determine how far it goes.\n        // The slide stops just before hitting a block or going out of bounds.\n        for (int k = 1; ; ++k) {\n            int r = cx + k * dx;\n            int c = cy + k * dy;\n            \n            // Stop if the next square is out of bounds or contains a block.\n            if (!is_valid(r, c) || blocks.count({r, c})) {\n                slide_dist = k - 1; // The actual distance slid is k-1 squares.\n                break;\n            }\n            // Note: The problem states \"If you slide over a target square without stopping on it, it is not considered visited.\"\n            // This means the slide continues until a block/boundary, even if it passes targets.\n            // Our simulation accurately finds the stopping point.\n        }\n        \n        // Update current position by the calculated slide distance.\n        current_pos.first += slide_dist * dx;\n        current_pos.second += slide_dist * dy;\n        cout << action << ' ' << dir << endl;\n    }\n}\n\n// --- Main Logic ---\n\nint main() {\n    // Optimize standard I/O operations.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input parameters: grid size N and number of points M.\n    cin >> N >> M; \n    // M points are provided: (i_0, j_0) is the starting position,\n    // and (i_1, j_1) through (i_{M-1}, j_{M-1}) are the M-1 targets to visit in sequence.\n    all_points.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> all_points[i].first >> all_points[i].second;\n    }\n\n    // Initialize the player's current position to the starting point.\n    current_pos = all_points[0]; \n\n    // Iterate through each target point that needs to be visited.\n    // The targets are all_points[1] up to all_points[M-1].\n    for (int target_idx = 1; target_idx < M; ++target_idx) {\n        pair<int, int> target_pos = all_points[target_idx]; // The current target to reach.\n\n        // Keep planning and executing actions until the current position matches the target position.\n        while (current_pos != target_pos) {\n            int cx = current_pos.first;\n            int cy = current_pos.second;\n            int tx = target_pos.first;\n            int ty = target_pos.second;\n\n            // --- Determine Primary Direction to Move ---\n            char dir_char = ' ';\n            int dr = tx - cx; // Row difference\n            int dc = ty - cy; // Column difference\n\n            // Decide the primary direction:\n            // If the row difference is larger, prioritize vertical movement (Up/Down).\n            // Otherwise, prioritize horizontal movement (Left/Right).\n            // If row and column differences are equal, prioritize horizontal movement.\n            if (abs(dr) > abs(dc)) {\n                if (dr > 0) dir_char = 'D'; // Target is below\n                else dir_char = 'U';        // Target is above\n            } else { \n                if (dc > 0) dir_char = 'R'; // Target is to the right\n                else dir_char = 'L';        // Target is to the left\n            }\n\n            pair<int, int> delta = get_delta(dir_char);\n            int dx = delta.first;\n            int dy = delta.second;\n\n            // Calculate the position of the immediate next square in the chosen direction.\n            int next_r = cx + dx;\n            int next_c = cy + dy;\n\n            // Check if the target square itself contains a block.\n            bool is_target_blocked = blocks.count({tx, ty});\n            char action_to_take = ' '; // Variable to store the determined action.\n\n            // --- Decision Logic for Choosing Action ---\n\n            // Case 1: The target square is blocked AND we are exactly one step away from it.\n            // To visit the target, we must first remove the block.\n            if ((next_r == tx && next_c == ty) && is_target_blocked) {\n                action_to_take = 'A'; // Use Alter to remove the block at the target.\n            }\n            // Case 2: The very next square in our primary direction is blocked.\n            // This means there's an intermediate obstacle. We must clear it to proceed.\n            else if (blocks.count({next_r, next_c})) {\n                action_to_take = 'A'; // Use Alter to remove the intermediate block.\n            }\n            // Case 3: The next square is clear.\n            else {\n                // Calculate the Manhattan distance to the target.\n                int distance_to_target = abs(tx - cx) + abs(ty - cy);\n\n                // Heuristic strategy:\n                // For longer distances (heuristic threshold of 4), and if the target is clear,\n                // using Slide is more efficient for covering ground quickly.\n                // For shorter distances, or if the target is blocked (and we are not adjacent),\n                // using Move provides better precision and control.\n                if (distance_to_target > 4 && !is_target_blocked) {\n                    action_to_take = 'S'; // Prefer Slide for longer distances.\n                } else {\n                    action_to_take = 'M'; // Prefer Move for shorter distances or when target is blocked.\n                }\n            }\n            \n            // Execute the chosen action. This prints the action/direction and updates the game state.\n            execute_action(action_to_take, dir_char);\n        }\n    }\n\n    return 0; // Program finishes after all targets are visited.\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\n// Use long long for area and large coordinates if needed.\n// For this problem, coordinates are up to 10000, area up to 10^8.\n// int is fine for coordinates. long long for area.\nusing ll = long long;\n\n// Represents an axis-aligned rectangle. Coordinates are [x1, x2) x [y1, y2).\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const { return (ll)(x2 - x1) * (y2 - y1); }\n    int width() const { return x2 - x1; }\n    int height() const { return y2 - y1; }\n};\n\n// Represents a company with its desired location and area.\nstruct Company {\n    int id;\n    int x, y; // Desired point is (x+0.5, y+0.5)\n    ll r;     // Desired area\n};\n\n// Global random number generators for reproducibility and better distribution.\n// Seeded with current time for different runs.\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> dist_01(0.0, 1.0);\n\n// Function to calculate satisfaction for a single company.\n// p_i = 1 - (1 - min(r_i, s_i) / max(r_i, s_i))^2\ndouble calculate_satisfaction(ll r_i, ll s_i) {\n    if (s_i == 0) return 0.0; // Should not happen with positive area constraint\n    double ratio = (double)min(r_i, s_i) / max(r_i, s_i);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Function to find all divisors of a number n.\n// Returns divisors in ascending order.\nvector<ll> get_divisors(ll n) {\n    vector<ll> divisors;\n    for (ll i = 1; i * i <= n; ++i) {\n        if (n % i == 0) {\n            divisors.push_back(i);\n            if (i * i != n) {\n                divisors.push_back(n / i);\n            }\n        }\n    }\n    sort(divisors.begin(), divisors.end());\n    return divisors;\n}\n\n// Structure to hold the result of one complete assignment attempt (one iteration).\nstruct AssignmentResult {\n    // Stores (a, b, c, d) for each company's assigned rectangle.\n    vector<tuple<int, int, int, int>> assignments; \n    // Total satisfaction achieved in this assignment.\n    double total_satisfaction = -1.0; // Initialize to a value lower than any possible satisfaction (0.0).\n};\n\nint N; // Number of companies\nvector<Company> companies_data; // Stores input data for each company.\nvector<Rect> initial_available_regions; // The initial bounding box for space partitioning.\n\n// Number of random trials to perform. This is a key parameter for randomized algorithms.\n// More iterations generally lead to better results but take more time.\nconst int NUM_ITERATIONS = 200; \n\n// The main solver function implementing a randomized recursive partitioning strategy.\nAssignmentResult solve() {\n    AssignmentResult overall_best_result;\n    overall_best_result.assignments.resize(N); // Pre-size for N companies.\n\n    // Indices of companies, used for shuffling and tracking.\n    vector<int> company_indices(N);\n    iota(company_indices.begin(), company_indices.end(), 0); // Fill with 0, 1, ..., N-1.\n\n    // Perform multiple independent trials to explore different random choices.\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<Rect> available_regions = initial_available_regions; // Start with the full 10000x10000 area.\n        vector<int> current_unassigned_companies = company_indices; // Companies yet to be assigned in this iteration.\n        vector<tuple<int, int, int, int>> current_assignments(N); // Stores assignments for this iteration.\n        double current_total_satisfaction = 0.0;\n        bool iteration_failed = false; // Flag to mark if this iteration produced an invalid state.\n\n        // Shuffle companies to process them in a random order for this iteration.\n        shuffle(current_unassigned_companies.begin(), current_unassigned_companies.end(), rng);\n\n        // Assign companies one by one until all are assigned.\n        while (!current_unassigned_companies.empty()) {\n            // Pick the next company to assign. It's the last one in the shuffled list.\n            int company_idx = current_unassigned_companies.back();\n            current_unassigned_companies.pop_back();\n            \n            const Company& company = companies_data[company_idx];\n            ll r_i = company.r;\n\n            // Pick an available region to place this company's ad.\n            // Heuristic: Randomly choose an available region. Other heuristics could be min area, etc.\n            if (available_regions.empty()) {\n                 // This scenario implies an issue: unassigned companies but no space left.\n                 // It suggests the partitioning logic or previous choices were flawed.\n                 iteration_failed = true; \n                 break; // Abandon this iteration.\n            }\n            \n            uniform_int_distribution<int> region_dist(0, available_regions.size() - 1);\n            int region_to_use_idx = region_dist(rng);\n            Rect region = available_regions[region_to_use_idx];\n\n            // Find all possible integer (width, height) pairs that form the desired area r_i\n            // and fit within the chosen region.\n            vector<pair<int, int>> valid_dims;\n            vector<ll> r_i_divisors = get_divisors(r_i); // Get divisors of desired area.\n\n            // Check each divisor 'w' to see if corresponding 'h' fits.\n            for (ll w_ll : r_i_divisors) {\n                int w = static_cast<int>(w_ll); // Cast is safe as w is limited by region.width() <= 10000.\n                if (w > 0 && w <= region.width()) {\n                    ll h_ll = r_i / w;\n                    if (h_ll > 0 && h_ll <= region.height()) {\n                        // If both width and height fit, this is a valid dimension pair.\n                        valid_dims.push_back({w, static_cast<int>(h_ll)}); // Cast is safe as h is limited by region.height() <= 10000.\n                    }\n                }\n            }\n\n            if (valid_dims.empty()) {\n                // If no valid (w, h) pair can form area r_i and fit in the region,\n                // this indicates that the chosen region is too small or has incompatible dimensions for r_i.\n                // Since sum of r_i equals total area, an exact fit should ideally be possible with proper partitioning.\n                // This means the current random choices led to an unresolvable state for this iteration.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose dimensions (w, h) from the list of valid options.\n            // Heuristic: Pick a random pair from valid_dims to explore different shapes.\n            uniform_int_distribution<int> dims_dist(0, valid_dims.size() - 1);\n            pair<int, int> dim = valid_dims[dims_dist(rng)];\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Determine the valid range for the top-left corner (a, b) of the rectangle.\n            // The rectangle [a, a+w) x [b, b+h) must cover the point (company.x+0.5, company.y+0.5).\n            // This means: a <= company.x < a+w AND b <= company.y < b+h.\n            // With integer coordinates, this translates to:\n            // a <= company.x AND a+w >= company.x + 1  => a >= company.x + 1 - w\n            // b <= company.y AND b+h >= company.y + 1  => b >= company.y + 1 - h\n            // Additionally, the rectangle must be within the selected region:\n            // region.x1 <= a AND a+w <= region.x2  => a <= region.x2 - w\n            // region.y1 <= b AND b+h <= region.y2  => b <= region.y2 - h\n            \n            // Combining these constraints to find the valid range for 'a' and 'b'.\n            int min_a = max(region.x1, company.x + 1 - w);\n            int max_a = min(region.x2 - w, company.x);\n            int min_b = max(region.y1, company.y + 1 - h);\n            int max_b = min(region.y2 - h, company.y);\n\n            if (min_a > max_a || min_b > max_b) {\n                // If the valid ranges are empty, it means no position 'a' or 'b' exists\n                // to satisfy all conditions simultaneously. This should ideally not happen\n                // if previous steps (finding valid_dims) were correct and the point is indeed within the region.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose the placement (a, b).\n            // Heuristic: Push the rectangle to the top-left corner (min_a, min_b) of its valid placement range.\n            // This aims to leave larger contiguous areas in the remaining space, potentially aiding future assignments.\n            int a = min_a;\n            int b = min_b;\n            \n            // Assign the rectangle [a, a+w) x [b, b+h) to the company.\n            current_assignments[company_idx] = {a, b, a + w, b + h};\n            ll s_i = (ll)w * h; // Actual area assigned.\n            // Accumulate satisfaction for this company.\n            current_total_satisfaction += calculate_satisfaction(r_i, s_i);\n\n            // Update the list of available regions.\n            // Remove the region that was just used.\n            available_regions.erase(available_regions.begin() + region_to_use_idx);\n\n            // Add the new regions created by partitioning the used region R with the assigned rectangle R_idx.\n            Rect assigned_rect = {a, b, a + w, b + h};\n            \n            // Add region to the left of the assigned rectangle, if it has positive width.\n            if (region.x1 < assigned_rect.x1) {\n                available_regions.push_back({region.x1, region.y1, assigned_rect.x1, region.y2});\n            }\n            // Add region to the right, if it has positive width.\n            if (assigned_rect.x2 < region.x2) {\n                available_regions.push_back({assigned_rect.x2, region.y1, region.x2, region.y2});\n            }\n            // Add region below the assigned rectangle, if it has positive height.\n            if (region.y1 < assigned_rect.y1) {\n                available_regions.push_back({assigned_rect.x1, region.y1, assigned_rect.x2, assigned_rect.y1});\n            }\n            // Add region above the assigned rectangle, if it has positive height.\n            if (assigned_rect.y2 < region.y2) {\n                available_regions.push_back({assigned_rect.x1, assigned_rect.y2, assigned_rect.x2, region.y2});\n            }\n        } // End of while loop: assigning companies within one iteration.\n\n        // After assigning all companies for this iteration, check if it was successful and if it's better than the overall best found so far.\n        if (!iteration_failed && current_total_satisfaction > overall_best_result.total_satisfaction) {\n            overall_best_result.total_satisfaction = current_total_satisfaction;\n            overall_best_result.assignments = current_assignments;\n        }\n    } // End of loop: performing multiple iterations.\n\n    // The problem implies a valid solution is always achievable. If overall_best_result.total_satisfaction is still -1.0,\n    // it means all iterations failed, indicating a potential issue with the algorithm or heuristics.\n    // However, with enough iterations and a reasonable algorithm, at least one should yield a valid assignment.\n\n    return overall_best_result;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n    companies_data.resize(N);\n    ll total_r_sum = 0; // For verification, though problem guarantees sum r_i = 10^8.\n    for (int i = 0; i < N; ++i) {\n        companies_data[i].id = i;\n        cin >> companies_data[i].x >> companies_data[i].y >> companies_data[i].r;\n        total_r_sum += companies_data[i].r;\n    }\n\n    // The problem statement guarantees that the sum of desired areas equals the total area of the 10000x10000 space.\n    // This is a strong hint that an optimal solution involves no wasted space (sum of assigned areas = total area).\n\n    // Initialize the initial available region: the entire 10000x10000 canvas.\n    initial_available_regions.push_back({0, 0, 10000, 10000});\n\n    // Run the solver to get the best assignment found.\n    AssignmentResult final_assignment = solve();\n\n    // Output the resulting rectangle coordinates for each company.\n    for (int i = 0; i < N; ++i) {\n        cout << get<0>(final_assignment.assignments[i]) << \" \"\n             << get<1>(final_assignment.assignments[i]) << \" \"\n             << get<2>(final_assignment.assignments[i]) << \" \"\n             << get<3>(final_assignment.assignments[i]) << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <vector> // Included for general utility, though not strictly used by the final greedy logic\n#include <algorithm> // Included for general utility, e.g., std::fill could be used for initialization\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 50;\n\n// Global arrays for grid data and visited status.\n// Static allocation is used as the grid size is fixed and memory limits are generous.\nint grid[N][N]; // Stores the score p_ij for each square (0 <= p_ij <= 99)\nint tile_map[N][N]; // Stores the tile ID t_ij for each square (0 <= t_ij <= M-1)\nint max_tile_id_plus_1 = 0; // Tracks the total number of unique tiles (M). M is max_tile_id + 1.\n\nbool visited_squares[N][N]; // Boolean matrix to ensure path simplicity (no revisiting squares).\n// The maximum possible tile ID is N*N - 1 (e.g., if all tiles are 1x1 and N*N distinct tiles exist).\n// Thus, an array of size N*N is sufficient to cover all possible tile IDs from 0 to N*N-1.\nbool used_tiles[N * N]; \n\n// Movement directions: Up, Down, Left, Right.\n// These arrays define the change in row (dr) and column (dc) for each of the four cardinal directions.\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\n// Corresponding characters for outputting the path. 'U' for Up, 'D' for Down, 'L' for Left, 'R' for Right.\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize C++ standard streams for faster input/output operations, crucial in competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial position (si, sj) from standard input.\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read the grid scores p_ij for all 50x50 squares.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Read the tile map t_ij for all squares and determine the total number of unique tiles (M).\n    // The problem states that tile IDs range from 0 to M-1, so M is `max_tile_id + 1`.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile_map[i][j];\n            // Update `max_tile_id_plus_1` if a tile ID implies a larger total number of tiles.\n            if (tile_map[i][j] + 1 > max_tile_id_plus_1) {\n                max_tile_id_plus_1 = tile_map[i][j] + 1;\n            }\n        }\n    }\n\n    // Initialize `visited_squares` matrix. Initially, no squares have been visited.\n    // A simple nested loop is efficient for initializing fixed-size arrays.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_squares[i][j] = false;\n        }\n    }\n    \n    // Initialize `used_tiles` array. Initially, no tiles are considered used.\n    // We only need to initialize entries corresponding to actual tile IDs, from 0 up to M-1.\n    for(int i = 0; i < max_tile_id_plus_1; ++i) {\n        used_tiles[i] = false;\n    }\n\n    string path_string = \"\"; // This string will store the sequence of moves (e.g., \"UDLRU\").\n    int current_r = si;    // Initialize current row position to the starting row.\n    int current_c = sj;    // Initialize current column position to the starting column.\n\n    // Mark the starting square as visited and its corresponding tile as used.\n    // This is because Takahashi starts on this square, and it counts as being stepped on.\n    visited_squares[current_r][current_c] = true;\n    // The tile ID at the starting position is guaranteed to be a valid index into `used_tiles`.\n    used_tiles[tile_map[current_r][current_c]] = true;\n\n    // Main loop for constructing the path using a greedy strategy.\n    // The loop continues as long as there are valid moves to make.\n    while (true) {\n        int best_neighbor_score = -1; // Stores the score of the best valid neighbor found. Initialized to -1 to ensure any non-negative score is considered better.\n        int best_dr = -1, best_dc = -1; // Stores the row and column delta for the best move.\n        char best_move_char = ' ';      // Stores the character representation ('U', 'D', 'L', 'R') of the best move.\n\n        // Explore all 4 possible adjacent squares from the current position.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current_r + dr[i]; // Calculate the row of the neighboring square.\n            int nc = current_c + dc[i]; // Calculate the column of the neighboring square.\n\n            // Constraint 1: Boundary Check.\n            // Ensure the neighboring square is within the 50x50 grid limits.\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n                continue; // Skip this neighbor if it's out of bounds.\n            }\n\n            // Constraint 2: Path Simplicity Check.\n            // Ensure the neighboring square has not been visited before in the current path.\n            if (visited_squares[nr][nc]) {\n                continue; // Skip if the square is already visited.\n            }\n\n            // Constraint 3: Tile Usage Check.\n            // Ensure the tile covering this neighboring square has not been used yet.\n            // `tile_map[nr][nc]` is a valid index because `max_tile_id_plus_1` was determined from all tile IDs present in the input.\n            if (used_tiles[tile_map[nr][nc]]) {\n                continue; // Skip if the tile is already used.\n            }\n\n            // If the move to (nr, nc) is valid according to all constraints:\n            // Apply the greedy heuristic: Select the valid neighbor that offers the highest score (`grid[nr][nc]`).\n            if (grid[nr][nc] > best_neighbor_score) {\n                best_neighbor_score = grid[nr][nc]; // Update the highest score found so far.\n                best_dr = dr[i];                    // Record the direction of this best move.\n                best_dc = dc[i];\n                best_move_char = move_char[i];      // Record the character for this best move.\n            }\n        } // End of loop exploring neighbors.\n\n        // If `best_neighbor_score` remained -1, it means no valid moves were found from the current position.\n        // This signifies the end of the path.\n        if (best_neighbor_score == -1) {\n            break; // Exit the path construction loop.\n        }\n\n        // Execute the best move identified:\n        // Update the current position to the coordinates of the chosen neighbor.\n        current_r += best_dr;\n        current_c += best_dc;\n        // Mark the newly entered square as visited to maintain path simplicity.\n        visited_squares[current_r][current_c] = true; \n        // Mark the tile covering this new square as used, enforcing the tile constraint.\n        used_tiles[tile_map[current_r][current_c]] = true; \n        // Append the character representing this move to the output path string.\n        path_string += best_move_char; \n    }\n\n    // Output the generated path string to standard output.\n    cout << path_string << endl;\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cmath>\n#include <iomanip>\n#include <limits>\n#include <algorithm> // For std::reverse, std::min, std::max\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 30;\n// Represents infinity for distances\nconst double INF = numeric_limits<double>::infinity();\n\n// --- Edge Weights ---\n// h_weights[i][j] stores the weight of the horizontal edge between (i, j) and (i, j+1).\n// i: row index (0 to 29), j: column index (0 to 28).\ndouble h_weights[N][N - 1];\n// v_weights[i][j] stores the weight of the vertical edge between (i, j) and (i+1, j).\n// i: row index (0 to 28), j: column index (0 to 29).\ndouble v_weights[N - 1][N];\n\n// --- Dijkstra's Algorithm Data Structures ---\n// Stores the predecessor vertex for path reconstruction. pred[r][c] = {pr, pc}\npair<int, int> pred[N][N];\n// Stores the shortest estimated distance from the start node to (r, c).\ndouble dist[N][N];\n\n// --- Constants for Learning ---\n// Initial learning rate for simple linear decay (INITIAL_LR / k).\n// The current best score was achieved with INITIAL_LR = 5.0.\n// Trying a further increase to 6.0 to potentially accelerate learning slightly,\n// while retaining the successful linear decay strategy and no tanh.\nconst double INITIAL_LR = 6.0; \n\n// Maximum absolute value for a single edge weight update (delta_per_edge).\n// Prevents extreme weight changes that could destabilize learning. 2000.0 was used in the\n// successful submission (score 39.26B), so we keep it.\nconst double MAX_DELTA_PER_EDGE = 2000.0; \n\n// --- Helper Functions ---\n\n// Gets the weight of the edge between two adjacent vertices (r1, c1) and (r2, c2).\n// Assumes (r1, c1) and (r2, c2) are indeed adjacent.\ndouble get_weight(int r1, int c1, int r2, int c2) {\n    if (r1 == r2) { // Horizontal edge: same row, different columns\n        // Ensure c_min is the smaller column index for array access\n        int c_min = min(c1, c2);\n        return h_weights[r1][c_min];\n    } else { // Vertical edge: same column, different rows\n        // Ensure r_min is the smaller row index for array access\n        int r_min = min(r1, r2);\n        return v_weights[r_min][c1]; // c1 == c2 for vertical edges\n    }\n}\n\n// Updates the weight of the edge between (r1, c1) and (r2, c2) by adding 'delta'.\n// Ensures the weight does not drop below 1.0 (as edge weights must be positive).\nvoid update_weight(int r1, int c1, int r2, int c2, double delta) {\n    if (r1 == r2) { // Horizontal edge\n        int c_min = min(c1, c2);\n        h_weights[r1][c_min] = max(1.0, h_weights[r1][c_min] + delta);\n    } else { // Vertical edge\n        int r_min = min(r1, r2);\n        v_weights[r_min][c1] = max(1.0, v_weights[r_min][c1] + delta);\n    }\n}\n\n// Dijkstra's algorithm to find the shortest path from start_node to end_node\n// using the current estimated edge weights.\nvoid dijkstra(pair<int, int> start_node, pair<int, int> end_node) {\n    // Initialize distances to infinity and predecessors to an invalid state.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dist[i][j] = INF;\n            pred[i][j] = {-1, -1}; // Sentinel value indicating no predecessor\n        }\n    }\n\n    // Distance to the start node is 0.\n    dist[start_node.first][start_node.second] = 0;\n\n    // Priority queue stores {negative_distance, {row, col}}.\n    // Using negative distance simulates a min-priority queue with std::priority_queue.\n    // This prioritizes nodes with smaller distances.\n    priority_queue<pair<double, pair<int, int>>> pq;\n    pq.push({0.0, start_node});\n\n    // Possible moves: Up, Down, Left, Right.\n    int dr[] = {-1, 1, 0, 0}; \n    int dc[] = {0, 0, -1, 1};\n\n    while (!pq.empty()) {\n        // Get the node with the smallest distance from the priority queue.\n        auto [d, curr_node] = pq.top();\n        pq.pop();\n        d = -d; // Convert negative distance back to positive.\n\n        int r = curr_node.first;\n        int c = curr_node.second;\n\n        // If the extracted distance is greater than the known shortest distance, skip.\n        // This can happen if a shorter path to 'curr_node' was found and pushed later.\n        if (d > dist[r][c]) {\n            continue;\n        }\n        \n        // Optimization: If we have reached the destination, we can stop.\n        // Since edge weights are positive, this path is guaranteed to be the shortest.\n        if (curr_node == end_node) {\n            break; \n        }\n\n        // Explore neighbors.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid boundaries.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = get_weight(r, c, nr, nc);\n                // If a shorter path to the neighbor is found, update distance and predecessor.\n                if (dist[r][c] + weight < dist[nr][nc]) {\n                    dist[nr][nc] = dist[r][c] + weight;\n                    pred[nr][nc] = {r, c}; // Set current node as predecessor for neighbor.\n                    pq.push({-dist[nr][nc], {nr, nc}}); // Add neighbor to priority queue.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // --- Initialization ---\n    // Initialize all edge weights to a starting guess.\n    // Edge generation values are typically in the range [1000, 9000].\n    // 5000.0 is a reasonable midpoint, central to the expected range.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) { // Horizontal edges\n            h_weights[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) { // Vertical edges\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = 5000.0;\n        }\n    }\n\n    // --- Process Queries ---\n    for (int k = 1; k <= 1000; ++k) {\n        // Read start and end nodes for the current query.\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        pair<int, int> start_node = {si, sj};\n        pair<int, int> end_node = {ti, tj};\n\n        // Find the shortest path using Dijkstra with current estimated weights.\n        dijkstra(start_node, end_node);\n\n        // --- Path Reconstruction and Output ---\n        string path_str = \"\";\n        double estimated_path_length = 0.0;\n        \n        // Store vertices temporarily to reconstruct path and then iterate to build string and sum length.\n        vector<pair<int, int>> path_trace;\n        pair<int, int> curr = end_node;\n        while (!(curr.first == -1 && curr.second == -1)) { // Stop if predecessor is invalid (-1,-1)\n            path_trace.push_back(curr);\n            if (curr == start_node) break; // Reached the start node\n            curr = pred[curr.first][curr.second];\n        }\n        // The path_trace is collected in reverse order (end to start). Reverse it.\n        reverse(path_trace.begin(), path_trace.end()); // Path from start to end.\n\n        // If start and end nodes are different, generate the path string and calculate estimated length.\n        if (path_trace.size() > 1) { \n            for (size_t i = 0; i + 1 < path_trace.size(); ++i) {\n                pair<int, int> u = path_trace[i]; // Current vertex\n                pair<int, int> v = path_trace[i+1]; // Next vertex\n\n                // Add the weight of the edge (u, v) to the estimated path length.\n                estimated_path_length += get_weight(u.first, u.second, v.first, v.second);\n\n                // Determine the move direction and append to the path string.\n                if (u.first < v.first) path_str += 'D'; // Moved Down (row index increased)\n                else if (u.first > v.first) path_str += 'U'; // Moved Up (row index decreased)\n                else if (u.second < v.second) path_str += 'R'; // Moved Right (column index increased)\n                else if (u.second > v.second) path_str += 'L'; // Moved Left (column index decreased)\n            }\n        }\n        \n        // Output the generated path string.\n        cout << path_str << endl;\n        // Flush the output buffer. This is crucial for the judge to receive the output promptly.\n        cout << flush;\n\n        // --- Feedback and Weight Update ---\n        // Read the feedback integer from the judge. This is a noisy measurement of the path's actual length.\n        long long feedback_k_ll; \n        cin >> feedback_k_ll;\n        double feedback_k = static_cast<double>(feedback_k_ll);\n\n        // Calculate the number of edges in the found path.\n        int num_edges = path_trace.size() - 1;\n        \n        // Only update weights if the path consists of at least one edge (start != end).\n        if (num_edges > 0) { \n            // Calculate the error: difference between observed feedback and estimated length.\n            double error = feedback_k - estimated_path_length;\n            \n            // Calculate the learning rate using simple linear decay (INITIAL_LR / k).\n            // This strategy has yielded the highest scores.\n            // Incrementing INITIAL_LR to 6.0 from 5.0.\n            double learning_rate = INITIAL_LR / k; \n            \n            // Use raw error without tanh for error smoothing, as it performed best.\n            double robust_error = error; \n\n            // Calculate the update amount to be applied to each edge in the path.\n            double delta_per_edge = learning_rate * robust_error / num_edges;\n            \n            // Clamp the delta_per_edge to prevent excessively large weight updates.\n            delta_per_edge = std::max(-MAX_DELTA_PER_EDGE, std::min(MAX_DELTA_PER_EDGE, delta_per_edge));\n            \n            // Update the weights of all edges that constitute the found path.\n            for (size_t i = 0; i + 1 < path_trace.size(); ++i) {\n                pair<int, int> u = path_trace[i];\n                pair<int, int> v = path_trace[i+1];\n                update_weight(u.first, u.second, v.first, v.second, delta_per_edge);\n            }\n        }\n    }\n\n    return 0; // Program finished successfully.\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <set>\n#include <tuple>\n#include <numeric> // For iota\n#include <chrono> // For time-based seed\n\nusing namespace std;\n\nint N;\nint M;\nvector<string> s;\n\n// Matrix characters\nconst char EMPTY = '.';\nconst vector<char> ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nstruct Placement {\n    int string_idx;\n    int r, c, dir; // dir: 0 for horizontal, 1 for vertical\n    vector<pair<int, int>> cells; // List of (row, col) for this placement\n    int id_in_string; // Unique ID for this placement within string_idx\n};\n\nvector<vector<Placement>> all_placements_for_string;\n// cell_users[r][c] stores a list of (string_idx, placement_id_in_string, pos_in_placement) for all placements using cell (r,c).\nvector<vector<vector<tuple<int, int, int>>>> cell_users; \n\n// State tracking variables\nvector<vector<bool>> placement_validity; // Stores validity for each placement in the current matrix A\nvector<int> valid_placement_count; // Stores total number of valid placements for each string\nvector<bool> is_matched; // Stores if a string is matched (has at least one valid placement)\nint num_matched; // Total number of matched strings\nlong long total_cells_filled; // Number of non-empty cells in the matrix\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Helper for toroidal coordinates\nint mod(int a, int b) {\n    return (a % b + b) % b;\n}\n\n// Calculate score based on current state\nlong double calculate_score_value() {\n    if (num_matched < M) {\n        // Score for not all strings matched: 10^8 * c / M\n        return 1e8 * (long double)num_matched / M;\n    } else {\n        // Score for all strings matched: 10^8 * 2 N^2 / (2 N^2 - d)\n        // d = N*N - total_cells_filled is the number of dots\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) { // Avoid division by zero or very small numbers\n            return 2e8; // Effectively max score, or a very high value\n        }\n        return 1e8 * term_numerator / term_denominator;\n    }\n}\n\n// Check if a specific placement is valid in the given matrix A\nbool is_placement_valid(const Placement& p, const vector<string>& A) {\n    for (size_t i = 0; i < p.cells.size(); ++i) {\n        int r_cell = p.cells[i].first;\n        int c_cell = p.cells[i].second;\n        // A cell is valid for this placement if it's empty or matches the required character\n        if (A[r_cell][c_cell] != EMPTY && A[r_cell][c_cell] != s[p.string_idx][i]) {\n            return false; // Conflict found\n        }\n    }\n    return true; // No conflicts\n}\n\n// Attempts to make a move by changing A[r][c] to new_char.\n// Returns true if the move is accepted and applied, false otherwise.\nbool try_move(vector<string>& A, int r, int c, char new_char) {\n    char old_char = A[r][c];\n    if (old_char == new_char) return false; // No change, skip.\n\n    // --- Store current state for comparison and potential revert ---\n    long double current_score_val = calculate_score_value();\n    // FIX: Store the current global num_matched before any changes.\n    int current_num_matched_snapshot = num_matched; \n    long long current_total_cells_filled = total_cells_filled;\n    \n    // Identify strings potentially affected by changing cell (r,c)\n    set<int> potentially_affected_string_indices;\n    for (const auto& user : cell_users[r][c]) {\n        potentially_affected_string_indices.insert(get<0>(user)); // string_idx\n    }\n\n    // Store old total valid counts for affected strings to revert if the move is rejected.\n    vector<pair<int, int>> old_valid_counts_for_affected;\n    for(int s_idx : potentially_affected_string_indices) {\n        old_valid_counts_for_affected.push_back({s_idx, valid_placement_count[s_idx]});\n    }\n\n    // --- Tentatively apply the change to A ---\n    A[r][c] = new_char;\n\n    // --- Calculate potential new state and score ---\n    // Start potential_num_matched from the snapshot of the current state.\n    int potential_num_matched = current_num_matched_snapshot; \n    long long potential_total_cells_filled = current_total_cells_filled;\n\n    // Update cell count\n    if (old_char == EMPTY && new_char != EMPTY) potential_total_cells_filled++;\n    if (old_char != EMPTY && new_char == EMPTY) potential_total_cells_filled--;\n\n    // Recalculate match status and valid_placement_count for affected strings\n    for (int s_idx : potentially_affected_string_indices) {\n        int new_total_valid_count = 0;\n        // Re-evaluate validity of ALL placements for this string in the *tentatively modified* grid A.\n        for(size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n            if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                new_total_valid_count++;\n            }\n        }\n        \n        // Check if the match status of the string changes.\n        bool was_matched = (valid_placement_count[s_idx] > 0); // Use current global count from before the move.\n        bool now_matched = (new_total_valid_count > 0);\n\n        if (was_matched && !now_matched) {\n            potential_num_matched--; // String becomes unmatched\n        } else if (!was_matched && now_matched) {\n            potential_num_matched++; // String becomes matched\n        }\n        // Tentatively update the global valid_placement_count for this s_idx for use in score calculation.\n        // This value will be restored if the move is rejected.\n        valid_placement_count[s_idx] = new_total_valid_count; \n    }\n\n    // Calculate potential score\n    long double potential_score_val;\n    if (potential_num_matched < M) {\n        potential_score_val = 1e8 * (long double)potential_num_matched / M;\n    } else {\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - potential_total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) {\n            potential_score_val = 2e8; // Max score\n        } else {\n            potential_score_val = 1e8 * term_numerator / term_denominator;\n        }\n    }\n\n    // --- Acceptance criteria ---\n    bool accept = false;\n    if (potential_score_val > current_score_val) {\n        accept = true; // Always accept if score improves\n    } else if (abs(potential_score_val - current_score_val) < 1e-9) { // Scores are approximately equal\n        // Tie-breaking: If all strings are matched (c=M), prefer fewer dots.\n        // FIX: Use the snapshot of current_num_matched here.\n        if (potential_num_matched == M && current_num_matched_snapshot == M) { \n            if (potential_total_cells_filled > current_total_cells_filled) { // Prefer filling more cells\n                accept = true;\n            }\n        }\n    }\n\n    if (accept) {\n        // Apply changes permanently\n        total_cells_filled = potential_total_cells_filled;\n        num_matched = potential_num_matched; // Update global num_matched.\n        \n        // Update `is_matched` based on the final `valid_placement_count` for affected strings.\n        for(int s_idx : potentially_affected_string_indices) {\n            is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n        }\n        return true;\n    } else {\n        // Revert changes if move is not accepted\n        A[r][c] = old_char; // Revert matrix cell\n        \n        // Revert `valid_placement_count` for affected strings.\n        for(const auto& state : old_valid_counts_for_affected) {\n            int s_idx_revert = state.first;\n            int old_count = state.second;\n            valid_placement_count[s_idx_revert] = old_count;\n        }\n        // num_matched and total_cells_filled are implicitly restored by not updating the global variables if not accepted.\n        return false;\n    }\n}\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M;\n    s.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n    }\n\n    // Precomputation: Generate all possible placements for all strings.\n    // For each string, a placement is defined by its starting row, starting column, and direction (horizontal/vertical).\n    all_placements_for_string.resize(M);\n    cell_users.resize(N, vector<vector<tuple<int, int, int>>>(N, vector<tuple<int, int, int>>()));\n    \n    for (int i = 0; i < M; ++i) {\n        int k = s[i].length();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Horizontal placement\n                Placement p_h;\n                p_h.string_idx = i;\n                p_h.r = r; p_h.c = c; p_h.dir = 0; // 0 for horizontal\n                p_h.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_h.cells[pi] = {r, mod(c + pi, N)};\n                }\n                p_h.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_h);\n\n                // Vertical placement\n                Placement p_v;\n                p_v.string_idx = i;\n                p_v.r = r; p_v.c = c; p_v.dir = 1; // 1 for vertical\n                p_v.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_v.cells[pi] = {mod(r + pi, N), c};\n                }\n                p_v.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_v);\n            }\n        }\n    }\n\n    // Populate cell_users: map each cell to which placements use it.\n    // This is crucial for efficiently finding affected strings when a cell changes.\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < all_placements_for_string[i].size(); ++j) {\n            const auto& p = all_placements_for_string[i][j];\n            for (size_t cell_idx = 0; cell_idx < p.cells.size(); ++cell_idx) {\n                int r_cell = p.cells[cell_idx].first;\n                int c_cell = p.cells[cell_idx].second;\n                cell_users[r_cell][c_cell].emplace_back(i, j, cell_idx); // Store (string_idx, placement_id_in_string, pos_in_placement)\n            }\n        }\n    }\n\n    // Initialize matrix and state tracking variables.\n    vector<string> A(N, string(N, EMPTY));\n    total_cells_filled = 0;\n\n    placement_validity.resize(M);\n    valid_placement_count.resize(M, 0);\n    is_matched.resize(M, false);\n    num_matched = 0;\n\n    // Initialize `placement_validity`, `valid_placement_count`, `is_matched` based on the initial empty matrix.\n    for (int i = 0; i < M; ++i) {\n        placement_validity[i].resize(all_placements_for_string[i].size(), false);\n        valid_placement_count[i] = 0; // Initially 0 valid placements for any string\n        is_matched[i] = false; // Initially no string is matched\n    }\n    num_matched = 0; // Initially 0 strings are matched\n\n    // --- Greedy Seeding Phase ---\n    // Iteratively fills the matrix to match as many strings as possible.\n    // Prioritizes placements that use fewer new cells (dots).\n    int max_greedy_passes = 5; // Limit passes to prevent infinite loops if greedy gets stuck.\n    for(int pass = 0; pass < max_greedy_passes; ++pass) {\n        bool new_match_made_in_pass = false;\n        \n        // Process strings in a random order to avoid consistent bias.\n        vector<int> string_order(M);\n        iota(string_order.begin(), string_order.end(), 0);\n        shuffle(string_order.begin(), string_order.end(), rng);\n\n        for (int s_idx : string_order) {\n            if (is_matched[s_idx]) continue; // Skip if already matched.\n\n            int best_p_id = -1;\n            int min_dots_used_for_best_p = N*N + 1; // Initialize with a value larger than possible\n\n            // Find the best valid placement for string `s_idx` in the current matrix `A`.\n            for (size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n                if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                    // Calculate how many currently empty cells this placement would fill.\n                    int current_dots_used = 0;\n                    for (const auto& cell : all_placements_for_string[s_idx][p_id].cells) {\n                        if (A[cell.first][cell.second] == EMPTY) {\n                            current_dots_used++;\n                        }\n                    }\n\n                    // Prioritize placements that require filling fewer empty cells.\n                    if (current_dots_used < min_dots_used_for_best_p) {\n                        min_dots_used_for_best_p = current_dots_used;\n                        best_p_id = p_id;\n                    }\n                }\n            }\n            \n            // If a valid placement was found, apply it to the matrix.\n            if (best_p_id != -1) {\n                const auto& p_to_apply = all_placements_for_string[s_idx][best_p_id];\n                for (const auto& cell : p_to_apply.cells) {\n                    if (A[cell.first][cell.second] == EMPTY) {\n                        // Find the character for this cell from the string `s[s_idx]`.\n                        int cell_pos = -1;\n                        for(size_t pi = 0; pi < p_to_apply.cells.size(); ++pi) {\n                            if (p_to_apply.cells[pi] == cell) {\n                                cell_pos = pi;\n                                break;\n                            }\n                        }\n                        A[cell.first][cell.second] = s[s_idx][cell_pos];\n                        total_cells_filled++; // Increment filled cell count.\n                    }\n                }\n                \n                // Update match status for `s_idx` and global `num_matched`.\n                bool string_s_was_matched = is_matched[s_idx];\n                // Re-evaluate validity for all placements of `s_idx` to get its new status.\n                valid_placement_count[s_idx] = 0;\n                for(size_t p_id_check = 0; p_id_check < all_placements_for_string[s_idx].size(); ++p_id_check) {\n                    placement_validity[s_idx][p_id_check] = is_placement_valid(all_placements_for_string[s_idx][p_id_check], A);\n                    if (placement_validity[s_idx][p_id_check]) {\n                        valid_placement_count[s_idx]++;\n                    }\n                }\n                is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n                \n                if (!string_s_was_matched && is_matched[s_idx]) {\n                    num_matched++; // A new string has become matched.\n                    new_match_made_in_pass = true; // Indicate that progress was made in this pass.\n                }\n                \n                // Propagate match status updates to other strings potentially affected by the newly filled cells.\n                // Collect all strings that use any of the cells that were just filled by `p_to_apply`.\n                set<int> strings_potentially_affected_by_fill;\n                for(const auto& cell : p_to_apply.cells) {\n                    // For each cell in the placement that was just filled:\n                    for (const auto& user : cell_users[cell.first][cell.second]) {\n                        strings_potentially_affected_by_fill.insert(get<0>(user)); // Add the string_idx of users.\n                    }\n                }\n                \n                // Re-evaluate match status for these potentially affected strings.\n                for(int affected_s_idx : strings_potentially_affected_by_fill) {\n                    if (affected_s_idx == s_idx) continue; // Skip the string that was just matched.\n\n                    bool was_matched_affected = is_matched[affected_s_idx];\n                    \n                    // Re-evaluate validity for all placements of `affected_s_idx`.\n                    valid_placement_count[affected_s_idx] = 0;\n                    for(size_t p_id_check = 0; p_id_check < all_placements_for_string[affected_s_idx].size(); ++p_id_check) {\n                        placement_validity[affected_s_idx][p_id_check] = is_placement_valid(all_placements_for_string[affected_s_idx][p_id_check], A);\n                        if (placement_validity[affected_s_idx][p_id_check]) {\n                            valid_placement_count[affected_s_idx]++;\n                        }\n                    }\n                    \n                    bool now_matched_affected = (valid_placement_count[affected_s_idx] > 0);\n\n                    // Update global `num_matched` and `is_matched` if the status changed.\n                    if (was_matched_affected && !now_matched_affected) {\n                        is_matched[affected_s_idx] = false;\n                        num_matched--;\n                        new_match_made_in_pass = true; // Progress made.\n                    } else if (!was_matched_affected && now_matched_affected) {\n                        is_matched[affected_s_idx] = true;\n                        num_matched++;\n                        new_match_made_in_pass = true; // Progress made.\n                    }\n                }\n            }\n        }\n        // If no new strings were matched in a full pass, the greedy phase is done.\n        if (!new_match_made_in_pass) break;\n    }\n\n    // --- Local Search Phase ---\n    // Use simulated annealing-like random walk to improve the solution.\n    // The number of iterations is adjusted based on M to balance exploration and time limit.\n    int ITER_COUNT = 100000;\n    if (M > 600) ITER_COUNT = 80000;\n    if (M > 700) ITER_COUNT = 60000;\n    if (M > 750) ITER_COUNT = 50000;\n    if (M > 780) ITER_COUNT = 40000; // Conservative for high M\n\n    uniform_int_distribution<int> dist_N(0, N - 1);\n    // Distribution for choosing character or EMPTY.\n    // FIX: Cast ALPHABET.size() to int for signed comparison.\n    int char_alphabet_size = static_cast<int>(ALPHABET.size());\n    uniform_int_distribution<int> dist_char_or_empty(0, char_alphabet_size); // Range [0, ALPHABET.size()] inclusive.\n\n    for (int iter = 0; iter < ITER_COUNT; ++iter) {\n        // Pick a random cell to modify.\n        int r = dist_N(rng);\n        int c = dist_N(rng);\n        char old_char = A[r][c];\n        \n        char new_char;\n        // Strategy for choosing the new character depends on whether all strings are matched.\n        if (num_matched == M) { \n            // If all strings are matched, the primary goal is to reduce dots (maximize filled cells).\n            // The best move is to change a character to EMPTY, if possible.\n            if (old_char != EMPTY) {\n                new_char = EMPTY;\n            } else {\n                // If the cell is already EMPTY, changing it to a character will increase dots and decrease score.\n                // So, we skip this iteration, as such a move is unlikely to be beneficial.\n                continue;\n            }\n        } else { \n            // If not all strings are matched, the priority is to match more strings.\n            // Try changing the cell to a random character from the alphabet or to EMPTY.\n            int char_choice = dist_char_or_empty(rng);\n            if (char_choice < char_alphabet_size) { // If not EMPTY index\n                new_char = ALPHABET[char_choice];\n            } else { // If chosen index corresponds to EMPTY\n                new_char = EMPTY;\n            }\n        }\n        \n        // Attempt the move. The `try_move` function handles score evaluation and state updates.\n        try_move(A, r, c, new_char);\n    }\n\n    // Output the final resulting matrix.\n    for (int i = 0; i < N; ++i) {\n        cout << A[i] << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <utility>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <tuple>\n#include <bitset>\n\nusing namespace std;\n\n// Use a large enough value for infinity for Dijkstra distances\nconst long long INF = 1e18;\n\nint N; // Grid size\nint si, sj; // Starting row and column\nvector<string> grid; // Stores the grid characters ('#', '5'-'9')\nvector<vector<int>> cost_grid; // Stores the cost to enter a road square\nvector<pair<int, int>> road_coords; // Stores {row, col} for all road squares\nmap<pair<int, int>, int> coord_to_id; // Maps {row, col} to a unique ID for road squares\n\n// Maximum possible number of road squares for N <= 69.\n// N*N <= 69*69 = 4761.\nconst int MAX_ROADS = 4761; \n\n// visible_from_bitset[r][c] is a bitset where the k-th bit is set if road with ID k is visible from (r, c).\nvector<vector<bitset<MAX_ROADS>>> visible_from_bitset; \n\n// adj_grid[r][c] stores a list of {neighbor_r, neighbor_c} for road squares adjacent to (r,c).\nvector<vector<vector<pair<int, int>>>> adj_grid; \n\n// Bitset for tracking covered roads. The k-th bit is 1 if road with ID k is covered.\nbitset<MAX_ROADS> is_road_covered_bitset; \n\npair<int, int> current_pos; // Current position of the patrol car\nlong long total_time = 0; // Total travel time of the route\nvector<pair<int, int>> route_path; // Stores the sequence of positions (coordinates) in the route\n\n// Directions for movement: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Function to check if a coordinate is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Function to reconstruct path from Dijkstra's parent pointers\nvector<pair<int, int>> reconstruct_path(const vector<vector<pair<int, int>>>& parent, pair<int, int> start_node, pair<int, int> end_node) {\n    vector<pair<int, int>> path;\n    pair<int, int> curr = end_node; \n\n    // Trace back from end_node to start_node using parent pointers\n    while (!(curr.first == start_node.first && curr.second == start_node.second)) {\n        // If curr becomes {-1, -1}, it implies end_node was unreachable from start_node\n        if (curr.first == -1) { \n            return {}; // Indicate path not found\n        }\n        path.push_back(curr); // Add the current node to the path\n        curr = parent[curr.first][curr.second]; // Move to the parent node\n    }\n    \n    // Add the start_node itself to the path.\n    if (!path.empty() || start_node == end_node) {\n        path.push_back(start_node);\n    }\n   \n    reverse(path.begin(), path.end()); // Reverse the path to get it from start to end\n    return path;\n}\n\nvoid solve() {\n    // 1. Read input and initialize data structures\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    cost_grid.resize(N, vector<int>(N));\n    adj_grid.resize(N, vector<vector<pair<int, int>>>(N)); \n    visible_from_bitset.resize(N, vector<bitset<MAX_ROADS>>(N));\n\n    int road_id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') { // If it's a road square\n                cost_grid[i][j] = grid[i][j] - '0'; // Store its travel cost\n                road_coords.push_back({i, j}); // Add its coordinates to the list\n                coord_to_id[{i, j}] = road_id_counter++; // Map its coordinates to a unique ID\n            }\n        }\n    }\n    \n    is_road_covered_bitset.reset(); // Reset for each test case\n\n    current_pos = {si, sj}; // Set current position to the start\n    route_path.push_back(current_pos); // Add start position to the route path\n\n    // 2. Precompute visibility using bitsets and adjacency lists\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] != '#') { // Process only road squares\n                \n                // Scan in four directions to find all visible road squares and set corresponding bits\n                // Left\n                for (int k = c - 1; k >= 0; --k) {\n                    if (grid[r][k] == '#') break; \n                    visible_from_bitset[r][c][coord_to_id.at({r, k})] = 1;\n                }\n                // Right\n                for (int k = c + 1; k < N; ++k) {\n                    if (grid[r][k] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({r, k})] = 1;\n                }\n                // Up\n                for (int k = r - 1; k >= 0; --k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({k, c})] = 1;\n                }\n                // Down\n                for (int k = r + 1; k < N; ++k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({k, c})] = 1;\n                }\n                // The current road square is visible from itself.\n                visible_from_bitset[r][c][coord_to_id.at({r, c})] = 1;\n\n                // Build adjacency list for road squares\n                for(int i=0; i<4; ++i) {\n                    int nr = r + dr[i];\n                    int nc = c + dc[i];\n                    if (is_valid(nr, nc) && grid[nr][nc] != '#') {\n                        adj_grid[r][c].push_back({nr, nc}); \n                    }\n                }\n            }\n        }\n    }\n\n    // Mark initially covered roads based on the starting position using bitwise OR.\n    is_road_covered_bitset |= visible_from_bitset[si][sj];\n    size_t total_roads = road_coords.size();\n\n    // --- GREEDY PHASE WITH STEP LIMIT ---\n    // Define a limit for greedy steps to ensure we don't exceed time limit.\n    // A multiplier of 7 for the number of road squares seems reasonable.\n    const int MAX_GREEDY_STEPS_MULTIPLIER = 7; \n    // Calculate max steps, ensuring it's at least a small constant to make progress on sparse maps.\n    int max_greedy_steps = max((int)road_coords.size() * MAX_GREEDY_STEPS_MULTIPLIER, 1000); \n    if (total_roads == 0) max_greedy_steps = 0; // No steps if no roads\n\n    int greedy_steps_taken = 0;\n\n    while (is_road_covered_bitset.count() < total_roads && greedy_steps_taken < max_greedy_steps) {\n        \n        // Variables to track the best move that provides new coverage\n        double best_gain_per_cost = -1.0; \n        long long min_cost_for_best_gain = INF; \n        int best_gain_r = -1, best_gain_c = -1;\n\n        // Variables for the fallback strategy (when no new coverage is achieved)\n        // Prioritize min cost, then max total visibility, then first found.\n        int fallback_r = -1, fallback_c = -1;\n        long long min_fallback_cost = INF;\n        int max_total_visibility_at_min_fallback_cost = -1; \n\n        // Iterate through adjacent road squares of the current position\n        for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; \n\n            // Calculate newly covered roads\n            bitset<MAX_ROADS> newly_covered_bits = visible_from_bitset[nr][nc] & ~is_road_covered_bitset;\n            int num_newly_covered = newly_covered_bits.count();\n\n            if (num_newly_covered > 0) {\n                // Offers new coverage: evaluate gain/cost\n                double current_gain_per_cost = (double)num_newly_covered / move_cost;\n\n                if (current_gain_per_cost > best_gain_per_cost) {\n                    best_gain_per_cost = current_gain_per_cost;\n                    min_cost_for_best_gain = move_cost;\n                    best_gain_r = nr;\n                    best_gain_c = nc;\n                } else if (abs(current_gain_per_cost - best_gain_per_cost) < 1e-9) { // Tie in score\n                    if (move_cost < min_cost_for_best_gain) { // Tie-break by cost\n                        min_cost_for_best_gain = move_cost;\n                        best_gain_r = nr;\n                        best_gain_c = nc;\n                    }\n                }\n            } else {\n                // No new coverage: consider for fallback\n                if (move_cost < min_fallback_cost) {\n                    min_fallback_cost = move_cost;\n                    fallback_r = nr;\n                    fallback_c = nc;\n                    max_total_visibility_at_min_fallback_cost = (int)visible_from_bitset[nr][nc].count();\n                } else if (move_cost == min_fallback_cost) {\n                    int current_total_visibility = (int)visible_from_bitset[nr][nc].count();\n                    if (current_total_visibility > max_total_visibility_at_min_fallback_cost) {\n                        fallback_r = nr;\n                        fallback_c = nc;\n                        max_total_visibility_at_min_fallback_cost = current_total_visibility;\n                    }\n                }\n            }\n        }\n        \n        // Decide the actual next move\n        if (best_gain_r != -1) {\n            // Found a move with new coverage. Use it.\n            current_pos = {best_gain_r, best_gain_c};\n        } else {\n            // No neighbor offers new coverage. Use the fallback move.\n            if (fallback_r != -1) { \n                current_pos = {fallback_r, fallback_c};\n            } else {\n                // This case implies current_pos has no neighbors which is only possible \n                // if total_roads == 0 or 1 (and it's covered), or if graph is disconnected (not the case here).\n                // If we're here, and still haven't covered all roads, we should break to avoid infinite loop.\n                 break; \n            }\n        }\n        \n        // Apply the chosen move\n        total_time += cost_grid[current_pos.first][current_pos.second]; // Add cost to enter the new square\n        route_path.push_back(current_pos); // Add the new position to the route path\n\n        // Update the global coverage bitset\n        is_road_covered_bitset |= visible_from_bitset[current_pos.first][current_pos.second];\n        \n        greedy_steps_taken++;\n    }\n    // --- END GREEDY PHASE ---\n\n\n    // 4. Phase 2: Return to the starting position (si, sj) using Dijkstra's algorithm\n    // This phase executes regardless of whether full coverage was achieved in the greedy phase.\n    vector<vector<long long>> dist(N, vector<long long>(N, INF)); \n    vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1})); \n    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq; \n\n    dist[current_pos.first][current_pos.second] = 0; \n    pq.push({0, current_pos}); \n\n    pair<int, int> dijkstra_target = {si, sj}; \n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top(); \n        pq.pop();\n\n        if (d > dist[pos.first][pos.second]) continue;\n        if (pos == dijkstra_target) break; \n\n        for (const auto& neighbor_pos : adj_grid[pos.first][pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; \n\n            if (dist[pos.first][pos.second] + move_cost < dist[nr][nc]) {\n                dist[nr][nc] = dist[pos.first][pos.second] + move_cost; \n                parent[nr][nc] = pos; \n                pq.push({dist[nr][nc], {nr, nc}}); \n            }\n        }\n    }\n\n    // Reconstruct the shortest path from current_pos back to dijkstra_target\n    vector<pair<int, int>> return_path_coords = reconstruct_path(parent, current_pos, dijkstra_target);\n    \n    // Append the steps from the return path to the overall route_path.\n    if (!return_path_coords.empty()) {\n        for (size_t i = 1; i < return_path_coords.size(); ++i) {\n            route_path.push_back(return_path_coords[i]); \n            total_time += cost_grid[return_path_coords[i].first][return_path_coords[i].second];\n        }\n    }\n\n    // 5. Generate the output route string\n    string result_route = \"\";\n    for (size_t i = 0; i + 1 < route_path.size(); ++i) {\n        pair<int, int> p1 = route_path[i];   \n        pair<int, int> p2 = route_path[i+1]; \n\n        int dr_move = p2.first - p1.first;\n        int dc_move = p2.second - p1.second;\n\n        if (dr_move == -1 && dc_move == 0) result_route += 'U'; // Move Up\n        else if (dr_move == 1 && dc_move == 0) result_route += 'D'; // Move Down\n        else if (dr_move == 0 && dc_move == -1) result_route += 'L'; // Move Left\n        else if (dr_move == 0 && dc_move == 1) result_route += 'R'; // Move Right\n    }\n\n    cout << result_route << endl;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); \n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n// Enum for task status\nenum TaskStatus {\n    UNSTARTED,\n    READY,\n    IN_PROGRESS,\n    COMPLETED\n};\n\n// A large value representing an unknown or very large estimated skill deficit.\n// The maximum possible w_ij could be around K * max(d_ik) ~ 20 * 160 = 3200.\n// Using 3300.0 ensures it's larger than any realistic w_ij.\nconst double INF_ESTIMATED_W = 3300.0; \n\nint N, M, K, R;\nvector<vector<int>> d; // d[task_idx][skill_idx]: required skill levels for task i\nvector<vector<int>> adj; // adj[task_idx]: list of tasks that depend on this task (successors)\nvector<int> in_degree; // in_degree[task_idx]: number of prerequisites not yet met for this task\n\nvector<TaskStatus> task_status;\nvector<bool> member_free; // True if member is available to take a new task\nvector<int> member_current_task; // Stores task_idx if member is busy, -1 otherwise\nvector<int> task_start_day; // Stores the day a task was STARTED (1-indexed day)\n\n// Data for learning and estimation\n// estimated_w[member_idx][task_idx]: estimated skill deficit w_ij for member j on task i.\n// Initialized to INF_ESTIMATED_W. Updated when member j completes task i.\nvector<vector<double>> estimated_w; \n\n// Statistics for members: used for fallback estimation when specific (member, task) w is unknown\nvector<int> member_task_count; // Number of tasks completed by this member\nvector<double> sum_observed_times_member; // Sum of durations of tasks completed by this member\n\n// Global statistics: used as a fallback when member-specific info is also unavailable\ndouble global_average_observed_duration = INF_ESTIMATED_W;\nlong long global_total_tasks_completed = 0;\ndouble global_total_observed_time = 0.0;\n\n// Structure to represent a potential assignment (member, task) with its estimated duration.\n// Used for sorting to greedily pick the best assignments.\nstruct Assignment {\n    double estimated_duration;\n    int member_idx;\n    int task_idx;\n\n    // Custom comparison for sorting: primarily by estimated_duration (ascending).\n    // Smaller duration is better. Tie-breaking is done by member_idx then task_idx for determinism.\n    bool operator<(const Assignment& other) const {\n        // Use a small epsilon for floating point comparisons to avoid issues with precision.\n        if (abs(estimated_duration - other.estimated_duration) > 1e-9) {\n            return estimated_duration < other.estimated_duration;\n        }\n        // Tie-breaking: Prefer lower indexed member, then lower indexed task.\n        if (member_idx != other.member_idx) {\n            return member_idx < other.member_idx;\n        }\n        return task_idx < other.task_idx;\n    }\n};\n\n// Updates the estimated_w for a specific (member_idx, task_idx) pair based on observed time.\n// This function is called at most once for each (member, task) pair because a task\n// is assigned to at most one member, and a member is assigned at most one task at a time.\nvoid update_estimated_w(int member_idx, int task_idx, int observed_time) {\n    double w_val;\n    if (observed_time == 1) {\n        // If task took 1 day, according to the problem statement (w_ij=0 => t_ij=1), w_ij must be 0.\n        w_val = 0.0;\n    } else {\n        // If observed_time > 1, then observed_time = w_ij + r_i, where r_i is a random integer in [-3, 3].\n        // This implies w_ij is in the range [max(0, observed_time - 3), observed_time + 3].\n        // We use the midpoint of this range as our best estimate for w_ij.\n        double w_min = max(0, observed_time - 3);\n        double w_max = observed_time + 3;\n        w_val = (w_min + w_max) / 2.0; \n    }\n    // Store the estimated skill deficit.\n    estimated_w[member_idx][task_idx] = w_val;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial problem parameters.\n    cin >> N >> M >> K >> R;\n\n    // Read task difficulty levels (d_i,k).\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Read task dependencies, build adjacency list (successors) and in-degree array.\n    adj.resize(N);\n    in_degree.resize(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; // Dependency: u must be completed before v can start.\n        cin >> u >> v;\n        --u; --v; // Convert to 0-indexed: u is prerequisite for v.\n        adj[u].push_back(v); // Add v to the adjacency list of u.\n        in_degree[v]++; // Increment in-degree of v.\n    }\n\n    // Initialize state variables for tasks and members.\n    task_status.resize(N, UNSTARTED);\n    member_free.resize(M, true);\n    member_current_task.resize(M, -1);\n    task_start_day.resize(N, -1); // -1 indicates task has not started yet.\n\n    // Initialize data structures for learning and estimation.\n    estimated_w.resize(M, vector<double>(N, INF_ESTIMATED_W));\n    member_task_count.resize(M, 0);\n    sum_observed_times_member.resize(M, 0.0);\n\n    // Identify tasks that are initially ready (have an in-degree of 0).\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) {\n            task_status[i] = READY;\n        }\n    }\n\n    int current_day = 1; // Simulation starts from day 1.\n    int completed_tasks_count = 0; // Counter for total completed tasks.\n\n    // Main simulation loop, runs day by day until all tasks are completed or time limit is reached.\n    while (completed_tasks_count < N) {\n        // 1. Process tasks completed at the END of the previous day.\n        vector<int> completed_members_indices_today; // Store indices of members who finished tasks.\n        int n_completed_input;\n        cin >> n_completed_input;\n\n        // Check for termination signal (-1) from the judge.\n        if (n_completed_input == -1) {\n            break; // Exit simulation if signal is received.\n        }\n\n        for (int i = 0; i < n_completed_input; ++i) {\n            int f_idx_1based;\n            cin >> f_idx_1based;\n            int member_idx = f_idx_1based - 1; // Convert member ID to 0-indexed.\n\n            completed_members_indices_today.push_back(member_idx);\n\n            int task_idx = member_current_task[member_idx]; // Get the task this member was working on.\n            \n            // Calculate the time taken for the task.\n            // A task started on task_start_day[task_idx] and finished at the end of current_day\n            // took current_day - task_start_day[task_idx] days.\n            int observed_time = current_day - task_start_day[task_idx];\n\n            // Update global statistics for overall average performance.\n            global_total_observed_time += observed_time;\n            global_total_tasks_completed++;\n            // Re-calculate global average duration to be more accurate.\n            global_average_observed_duration = global_total_observed_time / global_total_tasks_completed;\n\n            // Learn from the completed task: update estimated_w for this specific (member, task) pair.\n            update_estimated_w(member_idx, task_idx, observed_time);\n            \n            // Update task status to COMPLETED.\n            task_status[task_idx] = COMPLETED;\n            completed_tasks_count++;\n\n            // Mark the member as free, ready for a new assignment.\n            member_free[member_idx] = true;\n            member_current_task[member_idx] = -1;\n            \n            // Update member-specific statistics for future estimations.\n            member_task_count[member_idx]++;\n            sum_observed_times_member[member_idx] += observed_time;\n\n            // Update dependencies: decrement in-degree of successor tasks.\n            // If a successor task's in-degree becomes 0, it becomes READY.\n            for (int dependent_task_idx : adj[task_idx]) {\n                in_degree[dependent_task_idx]--;\n                if (in_degree[dependent_task_idx] == 0) {\n                    task_status[dependent_task_idx] = READY;\n                }\n            }\n        }\n        \n        // 2. Generate potential assignments for the current day.\n        vector<Assignment> candidates; // List to store all possible assignments with their estimated durations.\n        vector<int> ready_tasks_indices;\n        // Collect indices of all tasks that are currently READY.\n        for(int i=0; i<N; ++i) {\n            if (task_status[i] == READY) {\n                ready_tasks_indices.push_back(i);\n            }\n        }\n\n        // For every free member and every ready task, calculate an estimated duration.\n        for (int j = 0; j < M; ++j) { // Iterate through all members\n            if (member_free[j]) { // If member j is available\n                for (int task_idx : ready_tasks_indices) { // Consider all ready tasks\n                    double estimated_duration;\n                    \n                    // Heuristic: Estimate task duration for this (member, task) pair.\n                    // We prioritize assignments with the shortest estimated duration.\n                    // The estimation logic follows a hierarchy of information availability:\n                    // 1. Specific (member, task) estimate: If we have observed member j doing task i before.\n                    // 2. Member's average performance: If member j has completed other tasks.\n                    // 3. Global average performance: If member j is new and no other info is available.\n                    // 4. A very large value: If no historical data exists globally.\n\n                    // 1. Check if `estimated_w[j][task_idx]` has been updated from its initial large value.\n                    // The check ` < INF_ESTIMATED_W - 1.0` is a robust way to see if it's been set.\n                    if (estimated_w[j][task_idx] < INF_ESTIMATED_W - 1.0) { \n                        // `estimated_w` is the estimated skill deficit.\n                        // The estimated time to complete is max(1, estimated_w). This assumes r_i=0 for expected time.\n                        estimated_duration = max(1.0, estimated_w[j][task_idx]);\n                    } else {\n                        // 2. Fallback: Member j has some history (completed other tasks). Use their average completion time.\n                        if (member_task_count[j] > 0) {\n                            estimated_duration = sum_observed_times_member[j] / member_task_count[j];\n                        } else {\n                            // 3. Truly global fallback: Member j is new. Use global average observed time if available.\n                            if (global_total_tasks_completed > 0) {\n                                estimated_duration = global_average_observed_duration;\n                            } else {\n                                // 4. If no tasks have been completed globally yet, use a default high value.\n                                estimated_duration = INF_ESTIMATED_W;\n                            }\n                        }\n                    }\n                    \n                    // Ensure minimum duration is 1 day, as per problem statement.\n                    estimated_duration = max(1.0, estimated_duration);\n                    candidates.push_back({estimated_duration, j, task_idx}); // Add this potential assignment to candidates.\n                }\n            }\n        }\n\n        // Sort all candidate assignments by their estimated duration (ascending).\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Make assignments for the current day.\n        vector<pair<int, int>> assignments_today; // Stores {member_idx, task_idx} for output.\n        vector<bool> task_assigned_today(N, false); // Helper to ensure each task is assigned at most once per day.\n        \n        // Iterate through sorted candidates and make assignments greedily.\n        for (const auto& assignment : candidates) {\n            // Stop if we have already assigned tasks to all M members.\n            if (assignments_today.size() == M) { \n                break;\n            }\n            \n            int member_idx = assignment.member_idx;\n            int task_idx = assignment.task_idx;\n\n            // Check if the member is still free, the task is still ready, and the task hasn't been assigned today.\n            if (member_free[member_idx] && task_status[task_idx] == READY && !task_assigned_today[task_idx]) {\n                // Make the assignment.\n                member_free[member_idx] = false; // Mark member as busy.\n                member_current_task[member_idx] = task_idx; // Assign task to member.\n                task_start_day[task_idx] = current_day; // Record the start day.\n                task_status[task_idx] = IN_PROGRESS; // Update task status.\n                \n                assignments_today.push_back({member_idx, task_idx}); // Record assignment for output.\n                task_assigned_today[task_idx] = true; // Mark task as assigned for today.\n            }\n        }\n\n        // 4. Output assignments for the current day.\n        cout << assignments_today.size(); // Number of assignments.\n        for (const auto& p : assignments_today) {\n            // Output member ID and task ID (1-based).\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1; \n        }\n        cout << endl;\n        cout.flush(); // Ensure output is sent immediately.\n\n        current_day++; // Advance to the next day.\n    }\n\n    return 0; // End of simulation.\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <iomanip> // For std::fixed and std::setprecision\n\n// Use long long for coordinates and distances to be safe, although int might suffice for coordinates\nusing coord_t = int;\nusing dist_t = long long;\n\nstruct Point {\n    coord_t x, y;\n    int id; // Original order ID, or special ID for office\n\n    // Equality operator for point comparisons\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Less than operator for potential use in sets/maps\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// Calculate Manhattan distance between two points\ndist_t manhattan_distance(const Point& p1, const Point& p2) {\n    // Use static_cast to long long to prevent intermediate overflow in abs() if coordinates are large\n    return std::abs(static_cast<long long>(p1.x) - p2.x) + std::abs(static_cast<long long>(p1.y) - p2.y);\n}\n\n// Structure to hold information about a single delivery order\nstruct Order {\n    int id;\n    Point pickup;\n    Point delivery;\n    dist_t internal_dist; // Manhattan distance between pickup and delivery\n    dist_t dist_to_office_pickup; // Manhattan distance from office to pickup\n    dist_t dist_delivery_to_office; // Manhattan distance from delivery to office\n};\n\n// Structure for candidate points during route construction\n// Represents a point to visit next, along with its cost and type (pickup/delivery)\nstruct Candidate {\n    Point p;\n    dist_t cost;        // Cost to reach this point from the current location\n    int type;           // 0 for pickup, 1 for delivery\n    int order_id;       // The ID of the order this point belongs to\n    dist_t dist_to_office; // Pre-calculated distance from this point to the office (for tie-breaking)\n\n    // Custom comparison for sorting candidates by cost, then type, then distance to office\n    bool operator<(const Candidate& other) const {\n        if (cost != other.cost) {\n            return cost < other.cost;\n        }\n        // Tie-breaking:\n        // 1. Prefer pickups over deliveries.\n        if (type != other.type) {\n            return type < other.type; // 0 (pickup) < 1 (delivery)\n        }\n        // 2. If same type (both pickups or both deliveries):\n        //    Prefer the point that is closer to the office.\n        return dist_to_office < other.dist_to_office; \n    }\n};\n\n// Helper function to determine the grid cell coordinates for a given point\nstd::pair<int, int> get_cell(const Point& p) {\n    // 800x800 area, divided into 10x10 grid. Cell size is 80x80.\n    return {p.x / 80, p.y / 80}; \n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::vector<Order> all_orders(1000);\n    Point office = {400, 400, -1}; // Office location, ID -1 signifies office\n\n    // Read input for all 1000 orders\n    for (int i = 0; i < 1000; ++i) {\n        all_orders[i].id = i + 1; // Order IDs are 1-based\n        std::cin >> all_orders[i].pickup.x >> all_orders[i].pickup.y >> all_orders[i].delivery.x >> all_orders[i].delivery.y;\n        \n        // Assign original order ID to Point objects\n        all_orders[i].pickup.id = i + 1;\n        all_orders[i].delivery.id = i + 1;\n\n        // Pre-calculate distances for scoring and route construction\n        all_orders[i].internal_dist = manhattan_distance(all_orders[i].pickup, all_orders[i].delivery);\n        all_orders[i].dist_to_office_pickup = manhattan_distance(office, all_orders[i].pickup);\n        all_orders[i].dist_delivery_to_office = manhattan_distance(all_orders[i].delivery, office);\n    }\n\n    // --- Order Selection Heuristic ---\n    // Strategy: Select orders that are spatially clustered and relatively close to the office.\n    // 1. Group orders by the cell their pickup point falls into.\n    // 2. Score cells based on the average distance from the office to pickup points within them.\n    // 3. Prioritize cells closest to the office.\n    // 4. Collect candidate orders from prioritized cells, sorting them by internal travel distance.\n    // 5. Further refine candidates by a combined score and select the top 50.\n\n    // Map to group orders by their pickup cell\n    std::map<std::pair<int, int>, std::vector<Order*>> cell_to_orders_map;\n    for (auto& order : all_orders) {\n        cell_to_orders_map[get_cell(order.pickup)].push_back(&order);\n    }\n\n    // Calculate scores for each cell and store them along with cell coordinates\n    // Use double for average distance for better precision in cell scoring\n    std::vector<std::pair<double, std::pair<int, int>>> cell_scores; \n    for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n        if (order_list.empty()) continue; // Skip empty cells\n        dist_t total_dist_to_cell_pickup = 0;\n        for (Order* order_ptr : order_list) {\n            total_dist_to_cell_pickup += manhattan_distance(office, order_ptr->pickup);\n        }\n        // Average distance = total distance / number of orders in cell\n        cell_scores.push_back({static_cast<double>(total_dist_to_cell_pickup) / order_list.size(), cell_coord});\n    }\n\n    // Sort cells based on their average distance score (ascending)\n    std::sort(cell_scores.begin(), cell_scores.end());\n\n    // Pool of candidate orders to choose from. We aim for more than 50 initially to allow for better final selection.\n    std::vector<Order*> candidate_orders_pool; \n    std::set<int> added_order_ids; // Keep track of added orders to avoid duplicates\n\n    // Collect orders from the best cells first (lowest average distance to office)\n    // Increased pool size for potentially better order selection.\n    // Increased from 400 to 500.\n    const int MAX_CANDIDATES_TO_CONSIDER = 500; \n\n    for (const auto& cell_score_pair : cell_scores) {\n        std::pair<int, int> cell_coord = cell_score_pair.second;\n        if (cell_to_orders_map.count(cell_coord)) {\n            std::vector<Order*>& orders_in_cell = cell_to_orders_map[cell_coord];\n            // Sort orders within this cell by their internal travel distance (shortest first)\n            std::sort(orders_in_cell.begin(), orders_in_cell.end(), [](Order* a, Order* b) {\n                return a->internal_dist < b->internal_dist;\n            });\n            \n            // Add orders from this cell to the candidate pool if not already added\n            for (Order* order_ptr : orders_in_cell) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n        }\n        // Stop collecting if we have enough candidates\n        if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break; \n    }\n    \n    // If still not enough candidates after processing all prioritized cells,\n    // fill up from any remaining orders not yet considered.\n    if (candidate_orders_pool.size() < MAX_CANDIDATES_TO_CONSIDER) {\n        for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n            for (Order* order_ptr : order_list) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n             if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break;\n        }\n    }\n    \n    // Sort the pool of candidates by a refined score: \n    // internal_dist + min(dist_to_office_pickup, dist_delivery_to_office).\n    // This score prioritizes orders that are short and/or have at least one endpoint near the office.\n    std::sort(candidate_orders_pool.begin(), candidate_orders_pool.end(), [](Order* a, Order* b) {\n        dist_t score_a = a->internal_dist + std::min(a->dist_to_office_pickup, a->dist_delivery_to_office);\n        dist_t score_b = b->internal_dist + std::min(b->dist_to_office_pickup, b->dist_delivery_to_office);\n        return score_a < score_b;\n    });\n\n    // Select the top 50 orders from the sorted candidate pool.\n    std::vector<int> selected_order_ids;\n    std::vector<Order*> selected_orders_ptr; // Pointers to the actual Order objects for selected orders\n    for (int i = 0; i < 50; ++i) {\n        selected_order_ids.push_back(candidate_orders_pool[i]->id);\n        selected_orders_ptr.push_back(candidate_orders_pool[i]);\n    }\n\n    // --- Route Construction (Greedy) ---\n    // Uses a greedy approach to build the route, ensuring precedence constraints.\n    // It iteratively picks the cheapest valid next point (pickup or delivery).\n\n    std::vector<Point> route_points; // The sequence of points in the delivery route\n    // Map to quickly access selected order details by their ID\n    std::map<int, Order*> order_map; \n    // Track the visited status of pickups and completed deliveries for selected orders\n    std::map<int, bool> is_pickup_visited;\n    std::map<int, bool> is_delivery_done;\n    \n    // Populate data structures for selected orders\n    for (Order* order_ptr : selected_orders_ptr) {\n        order_map[order_ptr->id] = order_ptr;\n        is_pickup_visited[order_ptr->id] = false;\n        is_delivery_done[order_ptr->id] = false;\n    }\n\n    route_points.push_back(office); // Start the route at the office\n    Point current_location = office;\n    int orders_completed = 0; // Counter for the number of orders fully delivered\n\n    // Greedy construction of the route, ensuring precedence constraints\n    while (orders_completed < 50) {\n        std::vector<Candidate> candidates; // List of possible next points\n\n        // Consider all available pickup points for selected orders\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_pickup_visited[order_id]) {\n                // Add pickup point as a candidate\n                candidates.push_back({order_ptr->pickup, \n                                      manhattan_distance(current_location, order_ptr->pickup), \n                                      0, // type: pickup\n                                      order_id,\n                                      order_ptr->dist_to_office_pickup}); // distance to office for tie-breaking\n            }\n        }\n\n        // Consider all available delivery points IF their pickup has already been visited\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_delivery_done[order_id] && is_pickup_visited[order_id]) {\n                // Add delivery point if its order hasn't been completed AND its pickup has been visited\n                candidates.push_back({order_ptr->delivery, \n                                      manhattan_distance(current_location, order_ptr->delivery), \n                                      1, // type: delivery\n                                      order_id,\n                                      order_ptr->dist_delivery_to_office}); // distance to office for tie-breaking\n            }\n        }\n\n        // If no valid candidates are found, it means we are stuck.\n        // This should not happen if the problem is solvable for the selected 50 orders and the greedy logic is robust.\n        // If this occurs, `orders_completed` will be less than 50, likely leading to a WRONG_ANSWER or a suboptimal route.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates to find the best next move (using custom comparator: cost -> type -> dist_to_office)\n        std::sort(candidates.begin(), candidates.end());\n        \n        // Select the best candidate (minimum cost, then type, then distance to office)\n        Candidate best_candidate = candidates[0];\n        \n        // Add the chosen point to the route and update current location\n        route_points.push_back(best_candidate.p);\n        current_location = best_candidate.p;\n\n        // Update status based on the type of point visited\n        if (best_candidate.type == 0) { // It was a pickup\n            is_pickup_visited[best_candidate.order_id] = true;\n        } else { // It was a delivery\n            is_delivery_done[best_candidate.order_id] = true;\n            orders_completed++; // Increment count of fully delivered orders\n        }\n    }\n    \n    route_points.push_back(office); // End the route at the office\n\n    // --- Output ---\n    // Output the list of selected order IDs\n    std::cout << selected_order_ids.size() << std::endl;\n    for (int i = 0; i < selected_order_ids.size(); ++i) {\n        std::cout << selected_order_ids[i] << (i == selected_order_ids.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    // Output the sequence of points in the optimized route\n    std::cout << route_points.size() << std::endl;\n    for (int i = 0; i < route_points.size(); ++i) {\n        std::cout << route_points[i].x << \" \" << route_points[i].y << (i == route_points.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric> // For std::iota\n#include <algorithm> // For std::swap\n#include <vector> // For storing edge data\n\n// Disjoint Set Union (DSU) data structure\n// Used to keep track of connected components efficiently.\nstruct DSU {\n    std::vector<int> parent;\n    std::vector<int> sz;\n\n    // Constructor: Initializes DSU for n elements.\n    // Each element starts in its own set.\n    DSU(int n) {\n        parent.resize(n);\n        // Initialize each element to be its own parent.\n        std::iota(parent.begin(), parent.end(), 0);\n        // Initialize the size of each set to 1.\n        sz.assign(n, 1);\n    }\n\n    // Finds the representative (root) of the set containing element i.\n    // Implements path compression for optimization.\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        // Path compression: make every node on the path point directly to the root.\n        return parent[i] = find(parent[i]);\n    }\n\n    // Unites the sets containing elements i and j.\n    // Returns true if the sets were different and merged, false otherwise.\n    // Implements union by size for optimization.\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            // Union by size: attach the smaller tree to the root of the larger tree.\n            if (sz[root_i] < sz[root_j])\n                std::swap(root_i, root_j);\n            parent[root_j] = root_i;\n            sz[root_i] += sz[root_j];\n            return true; // Successfully merged two distinct sets\n        }\n        return false; // Elements were already in the same set\n    }\n};\n\n// Structure to store edge information: endpoints and calculated d_i\nstruct Edge {\n    int u, v;\n    long long d; // Rounded Euclidean distance\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Fixed values for N (number of vertices) and M (number of candidate edges)\n    // as specified in the problem statement for all test cases.\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates.\n    std::vector<std::pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> coords[i].first >> coords[i].second;\n    }\n\n    // Pre-calculate d_i for all M candidate edges.\n    std::vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u_node, v_node;\n        std::cin >> u_node >> v_node; // Read endpoints for edge i\n        edges[i].u = u_node;\n        edges[i].v = v_node;\n\n        // Calculate the Euclidean distance d_i.\n        // Using long double for intermediate calculations to maintain precision.\n        long double dx = static_cast<long double>(coords[u_node].first) - coords[v_node].first;\n        long double dy = static_cast<long double>(coords[u_node].second) - coords[v_node].second;\n        long double dist_sq = dx * dx + dy * dy;\n        long double dist = std::sqrt(dist_sq);\n        \n        // Round to the nearest integer as per problem statement.\n        edges[i].d = static_cast<long long>(std::round(dist));\n    }\n\n    DSU dsu(N); // Initialize DSU for N vertices.\n    int merges_made = 0; // Counter for successful component merges.\n\n    // Heuristic: Aim to balance connectivity guarantee with cost minimization.\n    // Adopt an edge if:\n    // 1. It connects two previously disconnected components AND\n    // 2. It is \"cheap\" (l_i <= COST_THRESHOLD * d_i) OR we are forced to take it\n    //    to guarantee connectivity (i.e., not enough remaining edges to make up needed merges).\n    //\n    // We are reducing COST_THRESHOLD from 2.7 to 2.5. This makes the \"cheap\" condition harder to satisfy.\n    // Consequently, more edges will be rejected if they are also \"not forced\",\n    // leading to a potentially lower total cost A and thus a higher score B/A.\n    // The \"forced\" condition `(edges_needed_for_connectivity > edges_available_later)` ensures\n    // we still prioritize completing the spanning tree.\n    const long double COST_THRESHOLD = 2.5; \n\n    for (int i = 0; i < M; ++i) {\n        long long l_i; // The true edge length for the i-th edge, revealed now.\n        std::cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        long long d_i = edges[i].d; // Base distance for this edge.\n\n        // Check if the edge connects two different components.\n        if (dsu.find(u) != dsu.find(v)) {\n            // This edge is potentially useful for connectivity.\n            \n            // Calculate how many more merges are strictly necessary to connect all N vertices.\n            // A spanning tree of N vertices requires N-1 edges.\n            int edges_needed_for_connectivity = (N - 1) - merges_made;\n            // Calculate how many edges are still available in the input stream from this point onwards.\n            int edges_available_later = M - 1 - i;\n\n            // Determine if the current edge's cost is within our preferred \"cheap\" range.\n            bool is_cheap = false;\n            // Handle d_i = 0 case: if base distance is 0, l_i must be 0 for it to be cheap.\n            if (d_i == 0) {\n                if (l_i == 0) is_cheap = true;\n            } else {\n                // Compare using long double for precision.\n                is_cheap = (static_cast<long double>(l_i) <= COST_THRESHOLD * static_cast<long double>(d_i));\n            }\n\n            // Decision logic: Adopt the edge if it's cheap OR if we are forced to take it.\n            // We are forced if the number of merges still needed is greater than the number of edges remaining.\n            // This ensures we don't reject an edge that might be our last chance to connect components.\n            if (is_cheap || (edges_needed_for_connectivity > edges_available_later)) {\n                // Adopt the edge.\n                std::cout << 1 << std::endl;\n                dsu.unite(u, v); // Merge the components.\n                merges_made++;   // Increment the count of successful merges.\n            } else {\n                // Reject the edge: it's too expensive AND we are not forced to take it.\n                // This is where we try to save cost by foregoing an expensive edge.\n                std::cout << 0 << std::endl;\n            }\n        } else {\n            // Reject the edge: it connects vertices already in the same component.\n            // It is redundant for connectivity and only adds cost.\n            std::cout << 0 << std::endl;\n        }\n        \n        // std::endl not only inserts a newline character but also flushes the output buffer.\n        // Flushing is critically required by the problem statement to ensure the judge receives\n        // our output for each step before providing the next input. Failure to flush can lead to TLE.\n        std::cout << std::endl;\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\n// Structures\nstruct Pos {\n    int r, c;\n    // Equality operator for comparing positions\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n    // Less than operator for sorting and using in maps/sets\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n};\n\nstruct Pet {\n    int id;\n    Pos pos;\n    int type;\n};\n\nstruct Human {\n    int id;\n    Pos pos;\n};\n\n// Directions for movement (U, D, L, R)\n// Corresponding dr and dc values\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1}; // U, D, L, R\n// Corresponding characters for movement and blocking actions\nchar move_chars[] = {'U', 'D', 'L', 'R'};\nchar block_chars[] = {'u', 'd', 'l', 'r'};\n\n// --- Helper Functions ---\n\n// Check if a position is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < GRID_SIZE && c >= 0 && c < GRID_SIZE;\n}\n\n// Calculate Manhattan distance between two positions\nint manhattan_distance(Pos p1, Pos p2) {\n    return abs(p1.r - p2.r) + abs(p1.c - p2.c);\n}\n\n// Get character for human movement action (uppercase)\nchar get_direction_char_for_move(Pos from, Pos to) {\n    if (to.r < from.r) return 'U';\n    if (to.r > from.r) return 'D';\n    if (to.c < from.c) return 'L';\n    if (to.c > from.c) return 'R';\n    return '.'; // Should not happen for movement if positions differ\n}\n\n// Get character for human blocking action (lowercase)\nchar get_direction_char_for_block(Pos from, Pos to) {\n    if (to.r < from.r) return 'u';\n    if (to.r > from.r) return 'd';\n    if (to.c < from.c) return 'l';\n    if (to.c > from.c) return 'r';\n    return '.'; // Should not happen for blocking if positions differ\n}\n\n// Get target position from current position and direction character\nPos get_pos_from_dir_char(Pos from, char dir) {\n    Pos to = from;\n    if (dir == 'U' || dir == 'u') to.r--;\n    else if (dir == 'D' || dir == 'd') to.r++;\n    else if (dir == 'L' || dir == 'l') to.c--;\n    else if (dir == 'R' || dir == 'r') to.c++;\n    return to;\n}\n\n// Get precomputed minimum Manhattan distance from a square (r, c) to any pet.\n// Uses a flattened 1D array for quick lookup.\nint get_min_dist_to_pet(int r, int c, const vector<int>& min_pet_dists_flat) {\n    return min_pet_dists_flat[r * GRID_SIZE + c];\n}\n\n// BFS to find reachable squares from a starting position.\n// This function is primarily for scoring calculation after all turns.\npair<int, vector<Pos>> get_reachable_area(Pos start_pos, const vector<vector<bool>>& is_impassable_grid) {\n    vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n    queue<Pos> q;\n    vector<Pos> reachable_squares;\n\n    // If start position is invalid or impassable, return empty area.\n    if (!is_valid(start_pos.r, start_pos.c) || is_impassable_grid[start_pos.r][start_pos.c]) {\n        return {0, {}};\n    }\n\n    q.push(start_pos);\n    visited[start_pos.r][start_pos.c] = true;\n    reachable_squares.push_back(start_pos);\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        // Explore adjacent squares\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n\n            // If adjacent square is valid, not impassable, and not visited, add to queue.\n            if (is_valid(nr, nc) && !is_impassable_grid[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                Pos next_pos = {nr, nc};\n                q.push(next_pos);\n                reachable_squares.push_back(next_pos);\n            }\n        }\n    }\n    return {reachable_squares.size(), reachable_squares};\n}\n\n// --- Global Variables ---\nint N_pets, M_humans;\nvector<Pet> pets_state;\nvector<Human> humans_state;\n// Grid state: true if impassable, false if passable.\nvector<vector<bool>> is_impassable_grid(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n\n// Main logic for the contest problem\nvoid solve() {\n    // Read initial state: pet positions, types, and human positions.\n    cin >> N_pets;\n    pets_state.resize(N_pets);\n    for (int i = 0; i < N_pets; ++i) {\n        pets_state[i].id = i;\n        cin >> pets_state[i].pos.r >> pets_state[i].pos.c >> pets_state[i].type;\n        pets_state[i].pos.r--; pets_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n    cin >> M_humans;\n    humans_state.resize(M_humans);\n    for (int i = 0; i < M_humans; ++i) {\n        humans_state[i].id = i;\n        cin >> humans_state[i].pos.r >> humans_state[i].pos.c;\n        humans_state[i].pos.r--; humans_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n\n    // Game loop for each turn\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        \n        // --- Precomputation for Human Decision Making ---\n        // Calculate minimum distance from every square to any pet.\n        // This is crucial for the human strategy of staying away from pets.\n        vector<int> min_pet_dists_flat(GRID_SIZE * GRID_SIZE);\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                min_pet_dists_flat[r * GRID_SIZE + c] = GRID_SIZE * 2; // Initialize with a large value\n                for (const auto& pet : pets_state) {\n                    min_pet_dists_flat[r * GRID_SIZE + c] = min(min_pet_dists_flat[r * GRID_SIZE + c], manhattan_distance({r, c}, pet.pos));\n                }\n            }\n        }\n\n        // Identify squares that are potentially blockable by humans.\n        // A square is blockable if it's within bounds, not impassable from previous turns,\n        // not occupied by any human or pet at the start of this turn, and not adjacent to any pet.\n        vector<Pos> blockable_squares;\n        vector<bool> is_occupied_at_start(GRID_SIZE * GRID_SIZE, false); // Mark occupied squares for quick checks\n        for (const auto& p : pets_state) is_occupied_at_start[p.pos.r * GRID_SIZE + p.pos.c] = true;\n        for (const auto& h : humans_state) is_occupied_at_start[h.pos.r * GRID_SIZE + h.pos.c] = true;\n\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                // Rule: Cannot block if adjacent to a pet. Minimum distance >= 2.\n                if (!is_impassable_grid[r][c] && !is_occupied_at_start[r * GRID_SIZE + c] && get_min_dist_to_pet(r, c, min_pet_dists_flat) >= 2) {\n                    blockable_squares.push_back({r, c});\n                }\n            }\n        }\n\n        // For each human, store their best potential blocking and moving action.\n        // Format: {score, position}. Initial score is -1.0 indicating no valid option found.\n        vector<pair<double, Pos>> best_block_options(M_humans, {-1.0, {-1, -1}}); \n        vector<pair<double, Pos>> best_move_options(M_humans, {-1.0, {-1, -1}});  \n\n        // --- Evaluate Blocking Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_block_score = -1.0;\n            Pos best_block_pos = {-1, -1};\n\n            for (const auto& sq : blockable_squares) {\n                double current_block_score = 0;\n                // Heuristic: prioritize blocking squares far from pets\n                current_block_score += (double)get_min_dist_to_pet(sq.r, sq.c, min_pet_dists_flat) * 100.0;\n                \n                // Heuristic: prefer extending existing walls (adjacent to already impassable squares)\n                bool adjacent_to_impassable = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = sq.r + dr[d];\n                    int nc = sq.c + dc[d];\n                    if(is_valid(nr, nc) && is_impassable_grid[nr][nc]) {\n                        adjacent_to_impassable = true;\n                        break;\n                    }\n                }\n                if (adjacent_to_impassable) {\n                    current_block_score += 50.0;\n                }\n                \n                // Heuristic: penalize blocking squares far from human's current position (encourages moving towards blocking target)\n                current_block_score -= manhattan_distance(humans_state[i].pos, sq);\n\n                // Update best option if current score is better\n                if (current_block_score > max_block_score) {\n                    max_block_score = current_block_score;\n                    best_block_pos = sq;\n                } else if (abs(current_block_score - max_block_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                    if (sq.r < best_block_pos.r || (sq.r == best_block_pos.r && sq.c < best_block_pos.c)) {\n                        best_block_pos = sq;\n                    }\n                }\n            }\n            // Store the best block option found for human i\n            if (best_block_pos.r != -1) {\n                best_block_options[i] = {max_block_score, best_block_pos};\n            }\n        }\n\n        // --- Evaluate Movement Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_move_score = -1.0;\n            Pos best_move_pos = {-1, -1};\n\n            // Check all 4 adjacent squares for potential movement\n            for (int d = 0; d < 4; ++d) {\n                int nr = humans_state[i].pos.r + dr[d];\n                int nc = humans_state[i].pos.c + dc[d];\n                Pos next_pos = {nr, nc};\n\n                // Can only move to a valid, passable square\n                if (is_valid(nr, nc) && !is_impassable_grid[nr][nc]) {\n                    // Cannot move to a square occupied by another human at the start of the turn\n                    if (!is_occupied_at_start[nr * GRID_SIZE + nc]) { \n                        double current_move_score = 0;\n                        // Heuristic: prefer moving to squares far from pets\n                        current_move_score += (double)get_min_dist_to_pet(nr, nc, min_pet_dists_flat) * 50.0;\n\n                        // Strong incentive to move to a square that this human plans to block\n                        if (best_block_options[i].second == next_pos) {\n                            current_move_score += 100.0;\n                        }\n                        \n                        // Update best option if current score is better\n                        if (current_move_score > max_move_score) {\n                            max_move_score = current_move_score;\n                            best_move_pos = next_pos;\n                        } else if (abs(current_move_score - max_move_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                            if (next_pos.r < best_move_pos.r || (next_pos.r == best_move_pos.r && next_pos.c < best_move_pos.c)) {\n                                best_move_pos = next_pos;\n                            }\n                        }\n                    }\n                }\n            }\n            // Store the best move option found for human i\n            if (best_move_pos.r != -1) {\n                best_move_options[i] = {max_move_score, best_move_pos};\n            }\n        }\n\n        // --- Conflict Resolution and Final Action Assignment ---\n        // This phase determines which actions are actually performed, resolving conflicts.\n        string human_actions_str(M_humans, '.'); // Stores the output action char for each human\n        vector<Pos> squares_to_move_to_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to move\n        vector<Pos> planned_blocks_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to block\n\n        // Structure to hold all potential actions (block or move) for sorting and conflict resolution\n        struct ActionChoice {\n            int human_id;\n            Pos target_pos;\n            double score;\n            bool is_block_action; // true if this choice is to block, false if to move\n\n            // Custom comparator for sorting: higher score first, then lower human_id for tie-breaking\n            bool operator<(const ActionChoice& other) const {\n                if (abs(score - other.score) > 1e-9) return score > other.score; // Sort by score descending\n                return human_id < other.human_id; // Sort by human_id ascending for ties\n            }\n        };\n        vector<ActionChoice> choices;\n\n        // Populate the list of all potential actions\n        for (int i = 0; i < M_humans; ++i) {\n            if (best_block_options[i].first > -1.0) { // If a block option was found\n                choices.push_back({i, best_block_options[i].second, best_block_options[i].first, true});\n            }\n            if (best_move_options[i].first > -1.0) { // If a move option was found\n                choices.push_back({i, best_move_options[i].second, best_move_options[i].first, false});\n            }\n        }\n        // Sort all potential actions based on score and human_id\n        sort(choices.begin(), choices.end());\n\n        vector<bool> human_assigned_action(M_humans, false); // Track if a human has been assigned an action\n\n        // Process sorted choices to assign actions and resolve conflicts\n        for (const auto& choice : choices) {\n            int hid = choice.human_id;\n            Pos target_pos = choice.target_pos;\n            bool is_block = choice.is_block_action;\n\n            if (human_assigned_action[hid]) continue; // Human already has an assigned action\n\n            if (is_block) {\n                // --- Check if this block action is still possible ---\n                bool can_block = true;\n                // 1. Cannot block if target square will be occupied by a moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (squares_to_move_to_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n                // 2. Cannot block if target square is permanently impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) { // If it was impassable before this turn\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) { // And it's currently empty\n                         can_block = false; // Cannot make an already blocked and empty square impassable.\n                     }\n                }\n                // 3. Cannot block if another human has already planned to block this same square.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n\n                // If the block action is valid, assign it.\n                if (can_block) {\n                    human_actions_str[hid] = get_direction_char_for_block(humans_state[hid].pos, target_pos);\n                    planned_blocks_this_turn[hid] = target_pos; // Record this planned block\n                    human_assigned_action[hid] = true;\n                }\n                // If block failed, this human might try their best move action later if available.\n            } else { // This choice is a movement action\n                // --- Check if this move action is still possible ---\n                bool can_move = true;\n                // 1. Cannot move to a square that is already impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) {\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) {\n                         can_move = false;\n                     }\n                }\n                // 2. Cannot move to a square already claimed by another moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (i != hid && squares_to_move_to_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n                // 3. Cannot move to a square that another human plans to block this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n\n                // If the move action is valid, assign it.\n                if (can_move) {\n                    human_actions_str[hid] = get_direction_char_for_move(humans_state[hid].pos, target_pos);\n                    squares_to_move_to_this_turn[hid] = target_pos; // Record this planned move\n                    human_assigned_action[hid] = true;\n                }\n                // If move failed, this human might have a block action as their next best choice.\n            }\n        }\n        \n        // --- Fallback: Handle humans who couldn't get their preferred action or any action ---\n        // If a human's top choice (block or move) was taken or invalid, they might try their second best,\n        // or default to blocking if possible, or default to staying put.\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                // Try to perform the best block action if it failed initially\n                if (best_block_options[i].first > -1.0) {\n                     Pos block_target = best_block_options[i].second;\n                     bool can_block_fallback = true;\n                     // Check availability similar to above\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (squares_to_move_to_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     if (is_impassable_grid[block_target.r][block_target.c]) {\n                          if (!is_occupied_at_start[block_target.r * GRID_SIZE + block_target.c]) { can_block_fallback = false; }\n                     }\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (planned_blocks_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     \n                     if (can_block_fallback) {\n                          human_actions_str[i] = get_direction_char_for_block(humans_state[i].pos, block_target);\n                          planned_blocks_this_turn[i] = block_target;\n                          human_assigned_action[i] = true;\n                     }\n                }\n                // If blocking still not possible, try to perform the best move action if it failed initially\n                if (!human_assigned_action[i] && best_move_options[i].first > -1.0) {\n                    Pos move_target = best_move_options[i].second;\n                    bool can_move_fallback = true;\n                    // Check availability similar to above\n                    if (is_impassable_grid[move_target.r][move_target.c]) {\n                         if (!is_occupied_at_start[move_target.r * GRID_SIZE + move_target.c]) { can_move_fallback = false; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (h_idx != i && squares_to_move_to_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (planned_blocks_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    \n                    if (can_move_fallback) {\n                         human_actions_str[i] = get_direction_char_for_move(humans_state[i].pos, move_target);\n                         squares_to_move_to_this_turn[i] = move_target;\n                         human_assigned_action[i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Final fallback: If a human still has no action assigned, they do nothing (stay put).\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                human_actions_str[i] = '.';\n            }\n        }\n\n        // --- Output Human Actions and Flush ---\n        cout << human_actions_str << endl;\n        cout << flush; // Essential to flush output for interactive problems\n\n        // --- Read Pet Movements and Update Game State ---\n        vector<string> current_pet_moves(N_pets);\n        for (int i = 0; i < N_pets; ++i) {\n            cin >> current_pet_moves[i];\n        }\n\n        // Update Pet Positions based on input movements\n        for (int i = 0; i < N_pets; ++i) {\n            Pos current_pet_pos = pets_state[i].pos; // Current position at start of turn\n            for (char move : current_pet_moves[i]) { // Process each move character in the string\n                if (move == '.') continue; // No move\n\n                Pos next_pet_pos = current_pet_pos;\n                if (move == 'U') next_pet_pos.r--;\n                else if (move == 'D') next_pet_pos.r++;\n                else if (move == 'L') next_pet_pos.c--;\n                else if (move == 'R') next_pet_pos.c++;\n                \n                // Determine if the target square for the pet is passable.\n                // A square is passable for a pet if it's within grid bounds, AND\n                // it's NOT newly blocked by human action THIS turn, AND\n                // it's NOT permanently blocked (from previous turns) AND currently empty.\n                \n                bool target_is_newly_impassable = false; // Blocked by humans THIS turn\n                for(const auto& block_pos : planned_blocks_this_turn) {\n                    if (block_pos == next_pet_pos) {\n                        target_is_newly_impassable = true;\n                        break;\n                    }\n                }\n                \n                bool is_permanently_blocked_and_empty = false; // Blocked from PREVIOUS turns and currently empty\n                if (is_impassable_grid[next_pet_pos.r][next_pet_pos.c]) { // If it was impassable before this turn\n                    if (!is_occupied_at_start[next_pet_pos.r * GRID_SIZE + next_pet_pos.c]) { // And it's currently empty\n                        is_permanently_blocked_and_empty = true;\n                    }\n                }\n\n                // If the target square is valid and passable for the pet, move the pet.\n                if (is_valid(next_pet_pos.r, next_pet_pos.c) && !target_is_newly_impassable && !is_permanently_blocked_and_empty) {\n                    current_pet_pos = next_pet_pos; // Pet successfully moves\n                } else {\n                    // If move is not possible, pet stays put for this move.\n                    // 'current_pet_pos' remains unchanged, and the next move in the string will be attempted from this position.\n                }\n            }\n            pets_state[i].pos = current_pet_pos; // Update pet's final position for the turn\n        }\n\n        // Update Grid State: Apply the squares that humans planned to block.\n        for (int i = 0; i < M_humans; ++i) {\n            if (planned_blocks_this_turn[i].r != -1) { // If human i planned to block a square\n                is_impassable_grid[planned_blocks_this_turn[i].r][planned_blocks_this_turn[i].c] = true;\n            }\n        }\n\n        // Update Human Positions based on their assigned move actions.\n        for (int i = 0; i < M_humans; ++i) {\n            if (human_actions_str[i] != '.' && human_actions_str[i] != 'u' && human_actions_str[i] != 'd' && human_actions_str[i] != 'l' && human_actions_str[i] != 'r') {\n                // This is a move action (uppercase char)\n                humans_state[i].pos = get_pos_from_dir_char(humans_state[i].pos, human_actions_str[i]);\n            }\n        }\n    }\n\n    // --- Scoring Calculation (for local testing/debugging, not submitted) ---\n    /*\n    double total_satisfaction = 0;\n    for (int i = 0; i < M_humans; ++i) {\n        auto [reachable_count, reachable_squares] = get_reachable_area(humans_state[i].pos, is_impassable_grid);\n        int caught_pets = 0;\n        for (const auto& pet : pets_state) {\n            for (const auto& sq : reachable_squares) {\n                if (pet.pos == sq) {\n                    caught_pets++;\n                    break;\n                }\n            }\n        }\n        double s_i = (double)reachable_count / 900.0 * pow(0.5, caught_pets);\n        total_satisfaction += s_i;\n    }\n    double final_score = round(1e8 * total_satisfaction / M_humans);\n    cerr << \"Final Score (approx): \" << fixed << setprecision(10) << final_score << endl;\n    */\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main game logic\n\n    return 0; // Program finished successfully\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Structure to store parent information for path reconstruction.\n// It records the previous grid cell (r, c), the previous step count (k),\n// and the move character that led to the current state.\nstruct ParentInfo {\n    int r, c, k; // Previous grid position and step count.\n    char move;   // The move character that was chosen to transition from (r,c,k) to the current state.\n};\n\n// Structure representing a state in the Dijkstra search.\n// It includes the expected actual time elapsed, current grid position (r, c),\n// and the number of moves (k) that have been decided/processed for the path.\nstruct State {\n    double expected_time;\n    int r, c, k; \n\n    // Custom comparator for the priority queue to implement a min-priority queue.\n    // States with lower expected_time have higher priority.\n    bool operator>(const State& other) const {\n        return expected_time > other.expected_time;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj, ti, tj; // Start and target coordinates.\n    double p;           // Probability of forgetting a move.\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // Read horizontal wall information. h_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i, j+1), 0 otherwise. Size: 20x19.\n    vector<vector<int>> h_walls(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            h_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    // Read vertical wall information. v_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i+1, j), 0 otherwise. Size: 19x20.\n    vector<vector<int>> v_walls(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            v_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    const int MAX_L = 200; // Maximum allowed length of the output string.\n    const double INF = numeric_limits<double>::max(); // Represents infinity for unreachable states.\n\n    // dist[r][c][k]: Stores the minimum expected actual time to reach grid cell (r, c)\n    // after k moves have been decided/processed for the path.\n    // k ranges from 0 to MAX_L.\n    vector<vector<vector<double>>> dist(20, vector<vector<double>>(20, vector<double>(MAX_L + 1, INF)));\n\n    // parent stores ParentInfo to reconstruct the path.\n    vector<vector<vector<ParentInfo>>> parent(20, vector<vector<ParentInfo>>(20, vector<ParentInfo>(MAX_L + 1, {-1, -1, -1, ' '})));\n\n    // Priority queue for Dijkstra's algorithm.\n    priority_queue<State, vector<State>, greater<State>> pq;\n\n    // Initial state: At home (si, sj), 0 moves processed, with an expected time of 0.0.\n    dist[si][sj][0] = 0.0;\n    pq.push({0.0, si, sj, 0});\n\n    // Define movement directions and corresponding characters for 'U', 'D', 'L', 'R'.\n    int dr[] = {-1, 1, 0, 0}; // Delta row for U, D, L, R\n    int dc[] = {0, 0, -1, 1}; // Delta column for U, D, L, R\n    char moves[] = {'U', 'D', 'L', 'R'};\n\n    // Variables to track the best path found to the office.\n    // min_expected_arrival_time stores the minimum expected time to reach the office.\n    // best_k stores the number of moves processed when the office was reached with min_expected_arrival_time.\n    double min_expected_arrival_time = INF;\n    int best_k = -1; \n\n    // Dijkstra's algorithm main loop.\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        double t = current.expected_time; // Expected time to reach this state.\n        int r = current.r;                 // Current row.\n        int c = current.c;                 // Current column.\n        int k = current.k;                 // Number of moves processed so far.\n\n        // If we found a better path to this state already, skip processing.\n        if (t > dist[r][c][k]) {\n            continue;\n        }\n\n        // Check if the current cell is the office.\n        if (r == ti && c == tj) {\n            // If we reached the office and this path is better than the best found so far, update.\n            if (t < min_expected_arrival_time) {\n                min_expected_arrival_time = t;\n                best_k = k; // Record the number of moves processed for this best path.\n            }\n            // Note: We don't 'continue' here because even if we reached the office,\n            // this state might be part of an even better path to the office IF it's reached earlier in terms of actual moves.\n            // However, since the goal is minimizing expected time, and the arrival time `t` is recorded,\n            // any further exploration from `(r,c,k)` for THIS specific path's time `t` is not useful for finding a *shorter* path to the office *via this specific branch*.\n            // But other states in PQ might offer a path with a lower expected time.\n            // The check `if (k == MAX_L)` below handles the path length limit.\n        }\n        \n        // If we have already processed MAX_L moves, we cannot extend this path further.\n        if (k == MAX_L) {\n            continue;\n        }\n\n        // Explore transitions for the next move (the (k+1)-th move in the sequence).\n        // For each of the 4 possible directions ('U', 'D', 'L', 'R'):\n        for (int i = 0; i < 4; ++i) {\n            char move_char = moves[i];\n            int nr_attempt = r, nc_attempt = c; // Initialize potential next position to current.\n\n            // Determine the target cell if the move is successful, considering grid boundaries and walls.\n            bool wall_collision = false; // True if move is blocked by boundary or wall.\n\n            if (move_char == 'U') {\n                // Check for boundary (r=0) or vertical wall v_walls[r-1][c] (between (r-1,c) and (r,c)).\n                if (r > 0 && !v_walls[r - 1][c]) { nr_attempt = r - 1; } else { wall_collision = true; }\n            } else if (move_char == 'D') {\n                // Check for boundary (r=19) or vertical wall v_walls[r][c] (between (r,c) and (r+1,c)).\n                if (r < 19 && !v_walls[r][c]) { nr_attempt = r + 1; } else { wall_collision = true; }\n            } else if (move_char == 'L') {\n                // Check for boundary (c=0) or horizontal wall h_walls[r][c-1] (between (r,c-1) and (r,c)).\n                if (c > 0 && !h_walls[r][c - 1]) { nc_attempt = c - 1; } else { wall_collision = true; }\n            } else if (move_char == 'R') {\n                // Check for boundary (c=19) or horizontal wall h_walls[r][c] (between (r,c) and (r,c+1)).\n                if (c < 19 && !h_walls[r][c]) { nc_attempt = c + 1; } else { wall_collision = true; }\n            }\n\n            // The actual time advances by 1 turn for this step, regardless of success or failure.\n            double next_expected_time = t + 1.0;\n            int next_k = k + 1; // One more move is now processed.\n\n            // Case 1: Move is forgotten (probability p).\n            // Takahashi stays at the current cell (r, c). The next state is (r, c) after k+1 moves.\n            // If the path to this state (r, c, next_k) via this route is better than previously found paths:\n            if (dist[r][c][next_k] > next_expected_time) {\n                dist[r][c][next_k] = next_expected_time;\n                // Record the parent information: we came from (r, c) at step k, and chose 'move_char'\n                // to generate this state at step k+1.\n                parent[r][c][next_k] = {r, c, k, move_char}; \n                pq.push({next_expected_time, r, c, next_k});\n            }\n\n            // Case 2: Move is executed (probability 1-p).\n            // Takahashi moves to (nr_attempt, nc_attempt). The next state is (nr_attempt, nc_attempt) after k+1 moves.\n            // If the path to this state (nr_attempt, nc_attempt, next_k) via this route is better:\n            if (dist[nr_attempt][nc_attempt][next_k] > next_expected_time) {\n                dist[nr_attempt][nc_attempt][next_k] = next_expected_time;\n                // Record parent information: came from (r, c) at step k, chose 'move_char'.\n                parent[nr_attempt][nc_attempt][next_k] = {r, c, k, move_char};\n                pq.push({next_expected_time, nr_attempt, nc_attempt, next_k});\n            }\n        }\n    }\n\n    // Path reconstruction.\n    string path = \"\";\n    if (best_k != -1) { // If the office was reached at least once within MAX_L moves.\n        int curr_r = ti;\n        int curr_c = tj;\n        int curr_k = best_k;\n\n        // Trace back from the office-reaching state to the start state (0 moves processed).\n        // The loop terminates when curr_k becomes 0.\n        while (curr_k > 0) {\n            ParentInfo p_info = parent[curr_r][curr_c][curr_k];\n            // Append the move character to the path string. This character is the (curr_k)-th move in the sequence.\n            path += p_info.move;\n            // Move to the parent state.\n            curr_r = p_info.r;\n            curr_c = p_info.c;\n            curr_k = p_info.k;\n        }\n        // The path string is built in reverse order, so reverse it.\n        reverse(path.begin(), path.end());\n    }\n    // If best_k remains -1, it means the office was not reached within MAX_L moves with a finite expected time.\n    // According to problem statement, failure leads to score 0. An empty path might be output, or a default path.\n    // However, given problem guarantees and structure, best_k should be set if office is reachable.\n    // For contest robustness, if path is empty, a simple BFS path could be a fallback, but Dijkstra should yield the optimal strategy.\n    \n    cout << path << endl; // Output the constructed commuting route.\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <random>\n#include <chrono> // For seeding the random number generator\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_DIRECTIONS = 4;\n\n// Directions: 0:Left, 1:Up, 2:Right, 3:Down\n// di[d] is the row change for direction d\n// dj[d] is the column change for direction d\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Base connections for the 8 tile types\n// base_connections[tile_type][entry_direction] = exit_direction\n// -1 means no connection\n// This table is derived from the problem statement's 'to' array.\nint base_connections[8][NUM_DIRECTIONS] = {\n    {1, 0, -1, -1}, // Type 0: L-U / U-L (Curve)\n    {3, -1, -1, 0}, // Type 1: L-D / D-L (Curve)\n    {-1, -1, 3, 2}, // Type 2: R-D / D-R (Curve)\n    {-1, 2, 1, -1}, // Type 3: R-U / U-R (Curve)\n    {1, 2, 3, 0},   // Type 4: Square path L->U->R->D->L\n    {3, 2, 1, 0},   // Type 5: S-curve like L->D, U->R, R->U, D->L (as per problem's to table)\n    {2, -1, 0, -1}, // Type 6: Horizontal L<->R (Straight)\n    {-1, 3, -1, 1}  // Type 7: Vertical U<->D (Straight)\n};\n\n// Function to map initial tile type and rotation count to effective tile type\n// The problem states how rotation changes the tile type for different groups.\nint map_type(int initial_type, int rotation) {\n    if (initial_type >= 0 && initial_type <= 3) { // Group 1: {0,1,2,3} rotate cyclically\n        return (initial_type + rotation) % 4;\n    } else if (initial_type == 4) { // Group 2a: {4,5} for initial type 4\n        // Rotation 0,2 -> type 4; Rotation 1,3 -> type 5\n        return 4 + (rotation % 2);\n    } else if (initial_type == 5) { // Group 2b: {4,5} for initial type 5\n        // Rotation 0,2 -> type 5; Rotation 1,3 -> type 4\n        return 4 + ((rotation + 1) % 2);\n    } else if (initial_type == 6) { // Group 3a: {6,7} for initial type 6\n        // Rotation 0,2 -> type 6; Rotation 1,3 -> type 7\n        return 6 + (rotation % 2);\n    } else if (initial_type == 7) { // Group 3b: {6,7} for initial type 7\n        // Rotation 0,2 -> type 7; Rotation 1,3 -> type 6\n        return 6 + ((rotation + 1) % 2);\n    }\n    return -1; // Should not happen\n}\n\n// Global variables to store the current configuration and support loop detection\nvector<vector<int>> base_type_input_grid; // Stores the initial tile type for each cell\nvector<vector<int>> current_rotations_grid; // Stores rotation count (0-3) for each cell\nvector<vector<vector<int>>> effective_to_grid; // Stores the connections for the current configuration of all cells\nvector<vector<vector<bool>>> visited_edge; // To mark edges (cell, entry_direction) that have been part of a found loop or dead end path\nvector<int> loop_lengths; // Stores lengths of all detected loop lines\n\n// Function to calculate the connections for a cell (r, c) based on its base type and current rotation\nvector<int> get_cell_connections(int r, int c) {\n    int initial_type = base_type_input_grid[r][c];\n    int rotation = current_rotations_grid[r][c];\n    int effective_type = map_type(initial_type, rotation);\n    // Return a copy of the connection rules for the effective tile type\n    return vector<int>(base_connections[effective_type], base_connections[effective_type] + NUM_DIRECTIONS);\n}\n\n// Function to find all loop lines and calculate the score (L1 * L2)\n// This function is called repeatedly by the local search heuristic.\nlong long evaluate_all_loops() {\n    // 1. Populate the effective_to_grid based on current rotations\n    effective_to_grid.assign(GRID_SIZE, vector<vector<int>>(GRID_SIZE, vector<int>(NUM_DIRECTIONS)));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            effective_to_grid[i][j] = get_cell_connections(i, j);\n        }\n    }\n\n    // 2. Find all loops using Depth First Search\n    loop_lengths.clear();\n    // visited_edge[i][j][d_in] marks if the edge entering cell (i,j) from direction d_in has been visited globally.\n    // This ensures each directed edge is explored at most once across all DFS traversals, making loop detection efficient.\n    visited_edge.assign(GRID_SIZE, vector<vector<bool>>(GRID_SIZE, vector<bool>(NUM_DIRECTIONS, false)));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            for (int d_in = 0; d_in < NUM_DIRECTIONS; ++d_in) {\n                // If this edge has not been visited yet, start a new DFS traversal\n                if (!visited_edge[i][j][d_in]) {\n                    vector<tuple<int, int, int>> current_path; // Stores the sequence of (row, col, entry_direction) visited in this DFS\n                    map<tuple<int, int, int>, int> visited_in_current_dfs; // Maps state to the step index in current_path for cycle detection\n                    \n                    int cur_i = i, cur_j = j, cur_d_in = d_in;\n                    int step = 0;\n\n                    while (true) {\n                        // Check for out of bounds\n                        if (cur_i < 0 || cur_i >= GRID_SIZE || cur_j < 0 || cur_j >= GRID_SIZE) {\n                            break; // Path broken (out of bounds)\n                        }\n\n                        auto state = make_tuple(cur_i, cur_j, cur_d_in);\n                        \n                        // Check for cycle\n                        if (visited_in_current_dfs.count(state)) {\n                            int cycle_start_step = visited_in_current_dfs[state];\n                            int loop_len = step - cycle_start_step;\n                            \n                            // Mark all edges in the found cycle as visited globally\n                            for (int k = cycle_start_step; k < current_path.size(); ++k) {\n                                auto [pi, pj, pd_in] = current_path[k];\n                                visited_edge[pi][pj][pd_in] = true;\n                            }\n                            loop_lengths.push_back(loop_len);\n                            break; // Found a loop, stop this DFS traversal\n                        }\n\n                        // Mark current state as visited in this DFS and add to path\n                        visited_in_current_dfs[state] = step;\n                        current_path.push_back(state);\n\n                        // Determine next tile and direction\n                        int d_out = effective_to_grid[cur_i][cur_j][cur_d_in];\n                        if (d_out == -1) {\n                            break; // Path broken (tile has no exit in this direction)\n                        }\n\n                        cur_i += di[d_out];\n                        cur_j += dj[d_out];\n                        cur_d_in = (d_out + 2) % 4; // The entry direction to the next tile is opposite of the exit direction from current tile\n                        step++;\n                    }\n                    \n                    // Mark all edges in the path explored by this DFS as globally visited.\n                    // This prevents re-exploring dead-end paths or segments that didn't form a cycle.\n                    for(const auto& path_state : current_path) {\n                        auto [pi, pj, pd_in] = path_state;\n                        visited_edge[pi][pj][pd_in] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 3. Calculate the score: L1 * L2\n    sort(loop_lengths.rbegin(), loop_lengths.rend()); // Sort lengths in descending order\n\n    if (loop_lengths.size() < 2) {\n        return 0; // Score is 0 if less than two loop lines are found\n    }\n    // Use long long for score to prevent overflow\n    return (long long)loop_lengths[0] * loop_lengths[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input and store base tile types\n    base_type_input_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            base_type_input_grid[i][j] = row[j] - '0';\n        }\n    }\n\n    // Initialize rotations: start with all tiles at 0 rotation.\n    // This is a common starting point for heuristic search.\n    current_rotations_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0)); \n\n    long long best_score = 0;\n    vector<vector<int>> best_rotations = current_rotations_grid;\n\n    // Calculate initial score for the all-zero rotation configuration\n    best_score = evaluate_all_loops();\n\n    // --- Randomized Iterative Improvement (Hill Climbing Variant) ---\n    // Use a Mersenne Twister engine for good random number generation.\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> cell_dist(0, GRID_SIZE - 1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n\n    // Number of iterations for the local search. This value is a heuristic tuning parameter.\n    // More iterations generally yield better results but increase computation time.\n    int num_iterations = 100000; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        // Pick a random cell (r, c) to potentially change its rotation\n        int r = cell_dist(rng);\n        int c = cell_dist(rng);\n        int original_rotation = current_rotations_grid[r][c];\n\n        // Explore all 4 possible rotations for the chosen cell (r, c).\n        // For each, evaluate the total score. Keep track of the rotation that yields the maximum score locally.\n        long long max_local_score = -1; // Initialize with a value lower than any possible score\n        int best_local_r = original_rotation; // Default to keeping the original rotation if no improvement found\n\n        for (int test_r = 0; test_r < 4; ++test_r) {\n            current_rotations_grid[r][c] = test_r; // Temporarily set this rotation\n            long long score = evaluate_all_loops(); // Evaluate the score for this configuration\n            \n            if (score > max_local_score) {\n                max_local_score = score;\n                best_local_r = test_r;\n            }\n        }\n        \n        // After trying all 4 rotations, commit the best one found for this cell (r, c).\n        // This is a greedy step: always move to a state that improves the local score.\n        current_rotations_grid[r][c] = best_local_r;\n\n        // Update the global best score and configuration if the current configuration is better\n        if (max_local_score > best_score) {\n            best_score = max_local_score;\n            best_rotations = current_rotations_grid; // Save the rotations that achieved this best score\n        }\n    }\n\n    // Output the resulting rotations as a single string of 900 digits.\n    string result_string = \"\";\n    result_string.reserve(GRID_SIZE * GRID_SIZE); // Reserve space for efficiency\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            result_string += to_string(best_rotations[i][j]);\n        }\n    }\n    cout << result_string << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <algorithm>\n#include <cmath>\n#include <array>\n#include <functional> // for std::greater\n\nusing namespace std;\n\nint N;\nint T_limit;\nvector<vector<int>> initial_board_grid;\npair<int, int> initial_empty_pos;\n\n// Target configuration: canonical grid graph with empty at (N-1, N-1)\nvector<vector<int>> canonical_board_grid;\n\n// For state representation and visited set\nusing Board = vector<vector<int>>;\nusing StateKey = vector<int>; // Flattened board\n\n// Stores minimum cost (number of moves) and the path to reach a board state.\n// Key: flattened board configuration.\nmap<StateKey, pair<int, string>> visited;\n\n// Movement directions: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\nchar move_chars[] = {'U', 'D', 'L', 'R'};\n\n// --- Heuristic function ---\n// Calculates the Manhattan distance of the empty square from the target position (N-1, N-1).\n// This is an admissible heuristic for sliding tile puzzles.\nint calculate_heuristic(int r, int c) {\n    return abs(r - (N - 1)) + abs(c - (N - 1));\n}\n\n// --- Board to StateKey conversion ---\n// Converts the 2D board representation to a 1D vector for use as a map key.\nStateKey board_to_key(const Board& board) {\n    StateKey key;\n    key.reserve(N * N);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            key.push_back(board[r][c]);\n        }\n    }\n    return key;\n}\n\n// --- Custom State struct for Priority Queue ---\n// Represents a state in the search: current board, empty square position, cost (moves), and path.\nstruct SearchState {\n    Board board;\n    int empty_r, empty_c;\n    int cost; // g_cost: number of moves from initial state\n    string path;\n\n    // Operator overload for priority_queue to prioritize states with lower f_cost (g_cost + h_cost).\n    // If f_costs are equal, prioritize states with lower actual cost (g_cost).\n    bool operator>(const SearchState& other) const {\n        int h_self = calculate_heuristic(empty_r, empty_c);\n        int h_other = calculate_heuristic(other.empty_r, other.empty_c);\n        \n        // Primary sort by f_cost (g + h)\n        if ((cost + h_self) != (other.cost + h_other)) {\n            return (cost + h_self) > (other.cost + h_other);\n        }\n        // Secondary sort by actual cost (g) to favor shorter paths when heuristics are equal\n        return cost > other.cost; \n    }\n};\n\nvoid solve() {\n    // 1. Construct the canonical target board configuration.\n    // This configuration aims to form a grid graph spanning tree with the empty square at (N-1, N-1).\n    // Each tile (r, c) (not the empty square) is assigned bits representing lines needed\n    // to connect to its neighbors in the grid, excluding any connection to the empty square.\n    canonical_board_grid.assign(N, vector<int>(N));\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (r == N - 1 && c == N - 1) {\n                canonical_board_grid[r][c] = 0; // The empty square\n            } else {\n                int val = 0;\n                // Tile at (r, c) needs a RIGHT line (bit 4) if neighbor (r, c+1) exists and is not empty.\n                if (c < N - 1) val |= 4; \n                // Tile at (r, c) needs a LEFT line (bit 1) if neighbor (r, c-1) exists.\n                if (c > 0) val |= 1;     \n                // Tile at (r, c) needs a DOWN line (bit 8) if neighbor (r+1, c) exists and is not empty.\n                if (r < N - 1) val |= 8; \n                // Tile at (r, c) needs an UP line (bit 2) if neighbor (r-1, c) exists.\n                if (r > 0) val |= 2;     \n                canonical_board_grid[r][c] = val;\n            }\n        }\n    }\n\n    // 2. Initialize A* search.\n    priority_queue<SearchState, vector<SearchState>, greater<SearchState>> pq;\n    visited.clear();\n\n    StateKey initial_key = board_to_key(initial_board_grid);\n    SearchState initial_state = {initial_board_grid, initial_empty_pos.first, initial_empty_pos.second, 0, \"\"};\n    \n    // Check if the initial state is already the target state.\n    bool is_initial_target = true;\n    if (initial_state.empty_r != N - 1 || initial_state.empty_c != N - 1) {\n        is_initial_target = false;\n    } else {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (r == N - 1 && c == N - 1) continue; // Skip the empty square itself\n                if (initial_state.board[r][c] != canonical_board_grid[r][c]) {\n                    is_initial_target = false;\n                    break;\n                }\n            }\n            if (!is_initial_target) break;\n        }\n    }\n\n    if (is_initial_target) {\n        cout << \"\" << endl; // Zero moves needed if already in target state.\n        return;\n    }\n\n    visited[initial_key] = {0, \"\"};\n    pq.push(initial_state);\n\n    // Limit the number of states explored to prevent Time Limit Exceeded.\n    // This limit is heuristic and may need tuning. It's adjusted based on N.\n    int max_states_to_explore = 2500000; // Default value\n    if (N >= 8) max_states_to_explore = 1800000; \n    if (N == 10) max_states_to_explore = 1200000; \n\n    int states_explored = 0;\n\n    // A* search loop.\n    while (!pq.empty() && states_explored < max_states_to_explore) {\n        SearchState current = pq.top();\n        pq.pop();\n\n        states_explored++;\n\n        StateKey current_key = board_to_key(current.board);\n        \n        // If we've found a shorter path to this state already, skip.\n        if (visited.count(current_key) && visited[current_key].first < current.cost) {\n            continue;\n        }\n\n        // Check if the current state is the target state.\n        bool is_target = true;\n        if (current.empty_r != N - 1 || current.empty_c != N - 1) {\n            is_target = false;\n        } else {\n            for (int r = 0; r < N; ++r) {\n                for (int c = 0; c < N; ++c) {\n                    if (r == N - 1 && c == N - 1) continue; // Skip the empty square\n                    if (current.board[r][c] != canonical_board_grid[r][c]) {\n                        is_target = false;\n                        break;\n                    }\n                }\n                if (!is_target) break;\n            }\n        }\n\n        // If target is reached, print the path and terminate.\n        if (is_target) {\n            cout << current.path << endl;\n            return; \n        }\n        \n        // Explore neighboring states by moving the empty square.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current.empty_r + dr[i];\n            int nc = current.empty_c + dc[i];\n\n            // Check if the potential new position for the empty square is within board bounds.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                Board next_board = current.board; // Create a copy of the current board.\n                // Perform the move: swap the empty square with the adjacent tile.\n                swap(next_board[current.empty_r][current.empty_c], next_board[nr][nc]);\n\n                StateKey next_key = board_to_key(next_board);\n                int next_cost = current.cost + 1;\n\n                // If this state hasn't been visited, or if we found a shorter path to it:\n                if (!visited.count(next_key) || next_cost < visited[next_key].first) {\n                    // Record the new state with its cost and path.\n                    visited[next_key] = {next_cost, current.path + move_chars[i]};\n                    // Add the new state to the priority queue for exploration.\n                    pq.push({next_board, nr, nc, next_cost, current.path + move_chars[i]});\n                }\n            }\n        }\n    }\n    \n    // According to the problem statement, a solution that forms a tree of size N^2-1\n    // is guaranteed to exist within T operations. If the search loop finishes\n    // without finding the target state, it implies that the search limits (e.g.,\n    // max_states_to_explore) were too strict, the heuristic was insufficient,\n    // or the state space exploration was too slow for the given time limit.\n    // In a competitive programming context, if this part is reached, it typically\n    // indicates a need for optimization, a better heuristic, or a different algorithm.\n    // For this problem, we assume the target state is reachable and will be found.\n    // If not found, the program would exit without outputting a path, which would be WA/TLE.\n}\n\n// Helper function to convert hexadecimal character to integer tile value.\nint char_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input: N (board size) and T (move limit).\n    cin >> N >> T_limit;\n\n    // Read the initial board configuration.\n    initial_board_grid.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            initial_board_grid[i][j] = char_to_int(row[j]);\n            // Store the position of the empty square (tile value 0).\n            if (initial_board_grid[i][j] == 0) {\n                initial_empty_pos = {i, j};\n            }\n        }\n    }\n\n    // Solve the puzzle using A* search.\n    solve();\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <iomanip>\n\nusing namespace std;\n\n// Use the maximum allowed coordinate value for defining line endpoints.\n// The problem statement allows coordinates up to 10^9.\nconst long long INF_COORD = 1e9; \n\nstruct Strawberry {\n    long long x, y;\n    int id;\n};\n\nstruct Line {\n    long long px, py, qx, qy;\n};\n\n// Helper function to select 'count' unique integer coordinates for lines.\n// This version aims for a robust candidate pool generation and then selects 'count'\n// coordinates from this pool that are themselves well-spaced.\nvector<long long> select_line_coords(int count, const set<long long>& occupied_coords) {\n    vector<long long> candidate_coords_pool;\n\n    // Define broad search ranges. Strawberry coords |x|,|y| < 10000.\n    long long internal_min = -16000, internal_max = 16000;\n    long long external_min = -20000, external_max = 20000;\n    \n    // Strategy 1: Add points from fixed, broad ranges.\n    // This ensures a baseline of available coordinates.\n    for (long long val = internal_min; val <= internal_max; ++val) {\n        if (occupied_coords.find(val) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val);\n        }\n    }\n    // Add points further out if needed to ensure enough candidates.\n    for (long long offset = 1; offset <= 4; ++offset) { // Limited offsets\n        long long val_neg = internal_min - offset * 2000;\n        if (val_neg >= external_min && occupied_coords.find(val_neg) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val_neg);\n        }\n        long long val_pos = internal_max + offset * 2000;\n        if (val_pos <= external_max && occupied_coords.find(val_pos) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val_pos);\n        }\n    }\n\n    // Strategy 2: Generate candidates from midpoints between existing strawberry coordinates.\n    // This is crucial for adapting to strawberry clusters.\n    if (!occupied_coords.empty()) {\n        vector<long long> sorted_occupied(occupied_coords.begin(), occupied_coords.end());\n        \n        // Add sentinel points to define intervals covering the whole range.\n        if (sorted_occupied.front() > external_min) sorted_occupied.insert(sorted_occupied.begin(), external_min);\n        if (sorted_occupied.back() < external_max) sorted_occupied.push_back(external_max);\n        \n        sort(sorted_occupied.begin(), sorted_occupied.end());\n        sorted_occupied.erase(unique(sorted_occupied.begin(), sorted_occupied.end()), sorted_occupied.end());\n\n        // Iterate through adjacent pairs of occupied coordinates.\n        for (size_t i = 0; i < sorted_occupied.size() - 1; ++i) {\n            long long c1 = sorted_occupied[i];\n            long long c2 = sorted_occupied[i+1];\n            \n            // Calculate the midpoint.\n            double mid = (static_cast<double>(c1) + c2) / 2.0;\n            \n            // Search outwards from the rounded midpoint for the nearest available integer coordinate.\n            // Reduce the offset limit to focus on candidates closer to the midpoint.\n            // A smaller offset might prevent generating too many candidates in dense regions,\n            // potentially leading to better selection spacing.\n            for (long long offset = 0; offset < 1000; ++offset) { // Reduced offset limit from 5000 to 1000\n                long long cand_pos = round(mid) + offset;\n                // Check if candidate is strictly within interval [c1, c2] and not occupied.\n                if (cand_pos > c1 && cand_pos < c2 && occupied_coords.find(cand_pos) == occupied_coords.end()) {\n                    candidate_coords_pool.push_back(cand_pos);\n                }\n                // Stop if we cross the next boundary.\n                if (cand_pos > c2) break;\n\n                if (offset > 0) { // Avoid checking negative offset if it's same as positive offset (offset=0)\n                    long long cand_neg = round(mid) - offset;\n                    if (cand_neg > c1 && cand_neg < c2 && occupied_coords.find(cand_neg) == occupied_coords.end()) {\n                        candidate_coords_pool.push_back(cand_neg);\n                    }\n                    // Stop if we cross the previous boundary.\n                    if (cand_neg < c1) break;\n                }\n            }\n        }\n    }\n\n    // Sort the entire pool of candidates and remove duplicates.\n    sort(candidate_coords_pool.begin(), candidate_coords_pool.end());\n    candidate_coords_pool.erase(unique(candidate_coords_pool.begin(), candidate_coords_pool.end()), candidate_coords_pool.end());\n    \n    vector<long long> selected_coords;\n    \n    // Select 'count' coordinates from the pool such that the selected coordinates are themselves well-spaced.\n    if (!candidate_coords_pool.empty() && count > 0) {\n        // If the pool is larger than 'count', pick evenly spaced indices from the pool.\n        if (candidate_coords_pool.size() > static_cast<size_t>(count)) {\n            // Calculate an approximate spacing factor for indices in the pool.\n            double spacing_factor = static_cast<double>(candidate_coords_pool.size()) / count;\n            for (int i = 0; i < count; ++i) {\n                // Calculate the index in the candidate pool.\n                size_t pool_idx = static_cast<size_t>(round(i * spacing_factor));\n                // Clamp index to ensure it's within bounds.\n                pool_idx = min(pool_idx, candidate_coords_pool.size() - 1);\n                selected_coords.push_back(candidate_coords_pool[pool_idx]);\n            }\n        } else {\n            // If pool is smaller than 'count', take all unique candidates from the pool.\n            selected_coords = candidate_coords_pool;\n        }\n    }\n\n    // Final fallback: Ensure we have exactly 'count' coordinates.\n    // If the above selection yielded fewer than 'count' coordinates, fill the remainder.\n    // Use broad fixed ranges for fallback, ensuring to avoid occupied and already selected values.\n    long long current_fallback_val = external_min;\n    while (selected_coords.size() < count) {\n        // Check if the current fallback value is not occupied and not already selected.\n        if (occupied_coords.find(current_fallback_val) == occupied_coords.end()) {\n            bool already_selected = false;\n            for(long long sel_val : selected_coords) {\n                if(sel_val == current_fallback_val) {\n                    already_selected = true;\n                    break;\n                }\n            }\n            if(!already_selected) {\n                selected_coords.push_back(current_fallback_val);\n            }\n        }\n        current_fallback_val++;\n        // Wrap around to avoid infinite loop if the range is exhaustively checked and still short.\n        if (current_fallback_val > external_max) {\n            current_fallback_val = external_min;\n        }\n    }\n\n    // Sort the final selection to ensure deterministic output and correct interval definition.\n    sort(selected_coords.begin(), selected_coords.end());\n    // Remove any duplicates that might have been introduced by fallback logic or overlapping candidates.\n    selected_coords.erase(unique(selected_coords.begin(), selected_coords.end()), selected_coords.end());\n\n    // Truncate if by some rare chance we ended up with more than 'count'.\n    if (selected_coords.size() > static_cast<size_t>(count)) {\n        selected_coords.resize(count);\n    }\n\n    return selected_coords;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    int k; // Maximum number of cuts\n    cin >> n >> k;\n\n    vector<int> a(11); // a[d] is the number of attendees for d years\n    for (int d = 1; d <= 10; ++d) {\n        cin >> a[d];\n    }\n\n    vector<Strawberry> strawberries(n);\n    set<long long> sx_set, sy_set; // Sets to store unique strawberry x and y coordinates for efficient lookup.\n    for (int i = 0; i < n; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        sx_set.insert(strawberries[i].x);\n        sy_set.insert(strawberries[i].y);\n    }\n\n    // Strategy: Divide the K cuts into vertical and horizontal lines.\n    // A balanced split (k/2 vertical, k-k/2 horizontal) creates a grid of regions.\n    int num_v_lines = k / 2;\n    int num_h_lines = k - num_v_lines;\n\n    // Select coordinates for the vertical and horizontal lines using the improved strategy.\n    vector<long long> v_line_values = select_line_coords(num_v_lines, sx_set);\n    vector<long long> h_line_values = select_line_coords(num_h_lines, sy_set);\n\n    // Sort line coordinates to define intervals correctly.\n    sort(v_line_values.begin(), v_line_values.end());\n    sort(h_line_values.begin(), h_line_values.end());\n\n    // Define interval boundaries for regions.\n    // These boundaries are the selected line coordinates plus sentinels far outside the strawberry range.\n    vector<long long> x_intervals = {-20000LL}; // Lower sentinel\n    x_intervals.insert(x_intervals.end(), v_line_values.begin(), v_line_values.end());\n    x_intervals.push_back(20000LL); // Upper sentinel\n    sort(x_intervals.begin(), x_intervals.end());\n    x_intervals.erase(unique(x_intervals.begin(), x_intervals.end()), x_intervals.end());\n\n    vector<long long> y_intervals = {-20000LL}; // Lower sentinel\n    y_intervals.insert(y_intervals.end(), h_line_values.begin(), h_line_values.end());\n    y_intervals.push_back(20000LL); // Upper sentinel\n    sort(y_intervals.begin(), y_intervals.end());\n    y_intervals.erase(unique(y_intervals.begin(), y_intervals.end()), y_intervals.end());\n\n    // Group regions by the number of strawberries they contain.\n    map<int, vector<int>> regions_by_count;\n    \n    int region_flat_idx_counter = 0; // Unique ID for each distinct rectangular region.\n\n    // Iterate through all created rectangular regions defined by the intervals.\n    for (size_t j = 0; j < x_intervals.size() - 1; ++j) {\n        for (size_t l = 0; l < y_intervals.size() - 1; ++l) {\n            long long min_x = x_intervals[j];\n            long long max_x = x_intervals[j+1];\n            long long min_y = y_intervals[l];\n            long long max_y = y_intervals[l+1];\n\n            // Count strawberries strictly within this open rectangular region.\n            int count = 0;\n            for (const auto& straw : strawberries) {\n                if (straw.x > min_x && straw.x < max_x &&\n                    straw.y > min_y && straw.y < max_y) {\n                    count++;\n                }\n            }\n            \n            // If a region contains strawberries, record it.\n            if (count > 0) {\n                regions_by_count[count].push_back(region_flat_idx_counter);\n                region_flat_idx_counter++;\n            }\n        }\n    }\n    \n    // Assignment phase: Greedily assign available regions to satisfy attendee demands.\n    set<int> used_region_flat_indices; // Track used regions.\n\n    // Iterate through each strawberry count demand (d from 1 to 10).\n    for (int d = 1; d <= 10; ++d) {\n        if (a[d] > 0) { // If there's a demand for 'd' strawberries.\n            // Check if we have any regions that contain exactly 'd' strawberries.\n            if (regions_by_count.count(d)) {\n                const vector<int>& available_regions_for_d = regions_by_count.at(d); \n                \n                int assigned_for_this_d = 0; // Counter for pieces of size 'd' assigned for current demand 'a[d]'.\n                \n                // Iterate through all regions known to contain exactly 'd' strawberries.\n                for (int region_flat_idx : available_regions_for_d) {\n                    // Check if this specific region has already been assigned.\n                    if (used_region_flat_indices.find(region_flat_idx) == used_region_flat_indices.end()) {\n                        // This region is available. Assign it.\n                        used_region_flat_indices.insert(region_flat_idx); // Mark as used.\n                        assigned_for_this_d++;\n                        \n                        // If we have satisfied all $a_d$ demands for this count 'd', stop looking for this 'd'.\n                        if (assigned_for_this_d == a[d]) {\n                            break; \n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Prepare the output cuts.\n    vector<Line> cuts;\n    // For each selected vertical line coordinate `val`, create a line segment.\n    for (long long val : v_line_values) {\n        cuts.push_back({val, -INF_COORD, val, INF_COORD});\n    }\n    // For each selected horizontal line coordinate `val`, create a line segment.\n    for (long long val : h_line_values) {\n        cuts.push_back({-INF_COORD, val, INF_COORD, val});\n    }\n\n    // Output the total number of cuts and the coordinates defining each cut line.\n    cout << cuts.size() << endl;\n    for (const auto& line : cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <set>\n#include <algorithm>\n#include <map>\n#include <tuple>\n\nusing namespace std;\n\n// Maximum number of operations to perform.\n// A limit is needed to prevent infinite loops and control execution time.\nconst int MAX_OPS = 5000; \n\n// Structure to represent a grid point.\nstruct Point {\n    int x, y;\n\n    // For use in std::set and std::map.\n    // Lexicographical comparison.\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n\n    // For equality checks.\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Global variables for grid dimensions, center, and total weight.\nlong long N_val; // Grid size (N x N). Renamed from N to avoid conflict.\nPoint center; // Center of the grid for weight calculation.\nlong long total_weight_sum_val; // Sum of weights of all points with dots. Renamed to avoid conflict.\n\n// Data structures for storing drawn segments to check for overlaps.\n// For axis-aligned segments:\n// h_segments_by_y[y] stores a set of pairs {min_x, max_x} for horizontal segments on line y.\n// v_segments_by_x[x] stores a set of pairs {min_y, max_y} for vertical segments on line x.\nmap<int, set<pair<int, int>>> h_segments_by_y;\nmap<int, set<pair<int, int>>> v_segments_by_x;\n\n// For 45-degree segments, we use transformed coordinates:\n// u = x + y\n// v = x - y\n// A segment with dx=dy becomes horizontal in (u,v) space (v is constant).\n//   Stored in uv_v_segments_by_v: key is the constant v, value is the range of u {min_u, max_u}.\n// A segment with dx=-dy becomes vertical in (u,v) space (u is constant).\n//   Stored in uv_h_segments_by_u: key is the constant u, value is the range of v {min_v, max_v}.\nmap<int, set<pair<int, int>>> uv_h_segments_by_u; // Stores vertical segments in (u,v) plane\nmap<int, set<pair<int, int>>> uv_v_segments_by_v; // Stores horizontal segments in (u,v) plane\n\n// Calculates the weight of a grid point based on its distance from the center.\nlong long weight(Point p) {\n    long long dx = p.x - center.x;\n    long long dy = p.y - center.y;\n    return dx * dx + dy * dy + 1;\n}\n\n// Adds a new segment (defined by two points) to the appropriate segment tracking maps.\nvoid add_segment(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        v_segments_by_x[p1.x].insert({min_y, max_y});\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        h_segments_by_y[p1.y].insert({min_x, max_x});\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // For 45-degree segments, |dx| must equal |dy|.\n        // This check is defensive; it should not be necessary if rectangle shape is correctly validated.\n        if (abs(dx) != abs(dy)) {\n             return; \n        }\n\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n\n        if (dx == dy) { // Segment is horizontal in (u,v) space (v is constant).\n            int v_const = v1; // v1 == v2 for dx=dy.\n            // Store in uv_v_segments_by_v, keyed by the constant v. Range is of u.\n            uv_v_segments_by_v[v_const].insert({min(u1, u2), max(u1, u2)});\n        } else { // dx == -dy. Segment is vertical in (u,v) space (u is constant).\n            int u_const = u1; // u1 == u2 for dx=-dy.\n            // Store in uv_h_segments_by_u, keyed by the constant u. Range is of v.\n            uv_h_segments_by_u[u_const].insert({min(v1, v2), max(v1, v2)});\n        }\n    }\n}\n\n// Checks if a new segment defined by p1 and p2 overlaps with any previously drawn segment.\nbool check_segment_overlap(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        \n        auto it_map = v_segments_by_x.find(p1.x); // Look for segments on the same vertical line.\n        if (it_map != v_segments_by_x.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_y, max_y}.\n            \n            // Efficiently find potentially overlapping segments.\n            // Find the first segment whose max_y is greater than or equal to our min_y.\n            // A segment [seg_min_y, seg_max_y] overlaps with [min_y, max_y] if seg_max_y >= min_y AND seg_min_y <= max_y.\n            // We search for segments whose 'first' element (seg_min_y) is <= max_y.\n            // `upper_bound({max_y, -1})` finds the first element strictly greater than {max_y, -1}.\n            // Decrementing it gives the first element that might overlap (its start is <= max_y).\n            auto it = segments.upper_bound({max_y, -1}); \n            if (it != segments.begin()) {\n                --it; // Move to the first segment that could overlap.\n                do {\n                    // Check for overlap: existing segment [it->first, it->second] vs new segment [min_y, max_y].\n                    if (it->second >= min_y && it->first <= max_y) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break; // Stop if we reached the beginning.\n                    --it; // Move to the next potential overlapping segment.\n                } while (it->first >= min_y); // Optimization: If an existing segment starts before our new segment, further preceding segments cannot overlap.\n            }\n        }\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        \n        auto it_map = h_segments_by_y.find(p1.y); // Look for segments on the same horizontal line.\n        if (it_map != h_segments_by_y.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_x, max_x}.\n            \n            auto it = segments.upper_bound({max_x, -1});\n            if (it != segments.begin()) {\n                --it;\n                do {\n                    // Existing segment [it->first, it->second] vs new segment [min_x, max_x].\n                    if (it->second >= min_x && it->first <= max_x) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_x);\n            }\n        }\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // This branch is for 45-degree segments, where |dx| == |dy|.\n        if (abs(dx) != abs(dy)) return false; // Should not happen if shape is valid.\n\n        // Calculate transformed coordinates for the new segment.\n        int u1_new = p1.x + p1.y;\n        int v1_new = p1.x - p1.y;\n        int u2_new = p2.x + p2.y;\n        int v2_new = p2.x - p2.y;\n\n        if (dx == dy) { // New segment is horizontal in (u,v) space (v is constant).\n            int v_const_new = v1_new; // v1_new == v2_new.\n            int min_u_new = min(u1_new, u2_new);\n            int max_u_new = max(u1_new, u2_new);\n\n            auto it_map = uv_v_segments_by_v.find(v_const_new); // Map stores horizontal segments in (u,v).\n            if (it_map != uv_v_segments_by_v.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_u, max_u}.\n                \n                auto it = segments.upper_bound({max_u_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_u_new, max_u_new].\n                        if (it->second >= min_u_new && it->first <= max_u_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_u_new);\n                }\n            }\n        } else { // dx == -dy. New segment is vertical in (u,v) space (u is constant).\n            int u_const_new = u1_new; // u1_new == u2_new.\n            int min_v_new = min(v1_new, v2_new);\n            int max_v_new = max(v1_new, v2_new);\n\n            auto it_map = uv_h_segments_by_u.find(u_const_new); // Map stores vertical segments in (u,v).\n            if (it_map != uv_h_segments_by_u.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_v, max_v}.\n                \n                auto it = segments.upper_bound({max_v_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_v_new, max_v_new].\n                        if (it->second >= min_v_new && it->first <= max_v_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_v_new);\n                }\n            }\n        }\n    }\n    return false; // No overlap found.\n}\n\n\n// Checks if a point 'test_p' lies strictly on the line segment defined by 'seg_p1' and 'seg_p2',\n// excluding the endpoints.\nbool is_point_on_segment_exclusive(Point test_p, Point seg_p1, Point seg_p2) {\n    if (seg_p1 == seg_p2) return false; // Degenerate segment.\n\n    // Check collinearity using the cross product.\n    // (test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) == (test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y)\n    long long cross_product = (long long)(test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) - (long long)(test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y);\n    if (cross_product != 0) return false; // Not collinear.\n\n    // Check if the point lies within the bounding box of the segment.\n    bool on_x = (test_p.x >= min(seg_p1.x, seg_p2.x) && test_p.x <= max(seg_p1.x, seg_p2.x));\n    bool on_y = (test_p.y >= min(seg_p1.y, seg_p2.y) && test_p.y <= max(seg_p1.y, seg_p2.y));\n\n    if (!on_x || !on_y) return false; // Collinear but outside the segment's bounds.\n\n    // Point is collinear and within the bounding box. Now check if it's strictly between the endpoints.\n    // It's strictly between if it's not equal to either endpoint.\n    bool is_endpoint1 = (test_p.x == seg_p1.x && test_p.y == seg_p1.y);\n    bool is_endpoint2 = (test_p.x == seg_p2.x && test_p.y == seg_p2.y);\n    \n    return !(is_endpoint1 || is_endpoint2);\n}\n\n// Checks Condition 2: No dots (other than the rectangle's corners) lie on the perimeter of the proposed rectangle.\n// p1_new is the point where the new dot will be placed.\n// p2_old, p3_old, p4_old are the three existing points that form the rectangle with p1_new.\nbool check_perimeter_dots(Point p1_new, Point p2_old, Point p3_old, Point p4_old, const set<Point>& current_dots) {\n    // Define the four segments of the rectangle.\n    Point segments[4][2] = {{p1_new, p2_old}, {p2_old, p3_old}, {p3_old, p4_old}, {p4_old, p1_new}};\n    \n    // The dots that are allowed to be on the perimeter are the existing corners of the rectangle.\n    set<Point> allowed_on_perimeter = {p2_old, p3_old, p4_old};\n\n    for (auto& seg : segments) {\n        Point seg_p1 = seg[0];\n        Point seg_p2 = seg[1];\n\n        if (seg_p1 == seg_p2) continue; // Skip degenerate segments.\n\n        // Iterate through all currently placed dots.\n        for (const auto& dot : current_dots) {\n            // If the dot is one of the allowed corners, it's fine.\n            if (allowed_on_perimeter.count(dot)) continue;\n            \n            // Check if this dot lies strictly on the current segment.\n            if (is_point_on_segment_exclusive(dot, seg_p1, seg_p2)) {\n                return false; // Found a forbidden dot on the perimeter.\n            }\n        }\n    }\n    return true; // No forbidden dots found on any segment.\n}\n\n// Checks if four points (p1, p2, p3, p4) in order form a valid rectangle.\n// p1 is the potential new dot, and p2, p3, p4 are existing dots.\nbool check_rectangle_shape_and_order(Point p1, Point p2, Point p3, Point p4) {\n    // Calculate vectors for each side.\n    long long dx1 = p2.x - p1.x; // Vector p1->p2\n    long long dy1 = p2.y - p1.y;\n    long long dx2 = p3.x - p2.x; // Vector p2->p3\n    long long dy2 = p3.y - p2.y;\n    long long dx3 = p4.x - p3.x; // Vector p3->p4\n    long long dy3 = p4.y - p3.y;\n    long long dx4 = p1.x - p4.x; // Vector p4->p1\n    long long dy4 = p1.y - p4.y;\n\n    // A rectangle is a parallelogram with perpendicular adjacent sides.\n    // Check if opposite sides are parallel and equal in length:\n    // Vector p1->p2 should be the negation of p3->p4 (or p4->p3).\n    bool side1_matches_side3 = (dx1 == -dx3) && (dy1 == -dy3);\n    // Vector p2->p3 should be the negation of p4->p1 (or p1->p4).\n    bool side2_matches_side4 = (dx2 == -dx4) && (dy2 == -dy4);\n\n    if (!side1_matches_side3 || !side2_matches_side4) {\n        return false; // Not a parallelogram.\n    }\n    \n    // Check if adjacent sides are perpendicular using the dot product.\n    // Dot product of vector p1->p2 and vector p2->p3 must be zero.\n    long long dot_product_12_23 = dx1 * dx2 + dy1 * dy2;\n    \n    if (dot_product_12_23 != 0) {\n        return false; // Adjacent sides are not perpendicular.\n    }\n\n    // All conditions met: it's a rectangle.\n    return true;\n}\n\n// Structure to represent a candidate move (placing a new dot).\nstruct CandidateMove {\n    Point p1_new; // The new dot's coordinates.\n    Point p2_old, p3_old, p4_old; // The three existing dots used to form the rectangle.\n    long long weight_val; // The weight of the new dot (p1_new).\n\n    // For sorting candidates: we want the move that adds the point with the highest weight.\n    bool operator<(const CandidateMove& other) const {\n        return weight_val < other.weight_val; // Ascending for std::sort, so we sort reversed later.\n    }\n};\n\n// Finds all possible valid moves (rectangles that can be drawn).\nvector<CandidateMove> find_candidate_moves(const set<Point>& current_dots) {\n    vector<CandidateMove> candidates;\n    // Convert the set of dots to a vector for easier iteration.\n    vector<Point> dots_vec(current_dots.begin(), current_dots.end());\n\n    // Strategy: Iterate through pairs of existing dots (pa, pb) and check if they can be part of a rectangle.\n\n    // --- Generate Axis-Aligned Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point pa = dots_vec[i];\n            Point pb = dots_vec[j];\n\n            // Case 1: pa and pb share the same y-coordinate (form a horizontal segment).\n            if (pa.y == pb.y) {\n                int y_base = pa.y;\n                int x1 = min(pa.x, pb.x);\n                int x2 = max(pa.x, pb.x);\n                \n                // Search for points on parallel lines y_new = y_base + dy and y_new = y_base - dy.\n                // We search symmetrically outwards from the base segment.\n                for (int dy = 1; ; ++dy) {\n                    // If both upward and downward searches go out of bounds, stop.\n                    if (y_base + dy >= N_val && y_base - dy < 0) break; \n\n                    bool found_upper = false;\n                    Point pc_upper = {-1, -1}, pd_upper = {-1, -1}; // Placeholder for potential points.\n                    // Check for points on the line y_base + dy.\n                    if (y_base + dy < N_val) {\n                        pc_upper = {x1, y_base + dy};\n                        pd_upper = {x2, y_base + dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_upper) && current_dots.count(pd_upper)) {\n                            found_upper = true;\n                        }\n                    }\n\n                    bool found_lower = false;\n                    Point pc_lower = {-1, -1}, pd_lower = {-1, -1};\n                    // Check for points on the line y_base - dy.\n                    if (y_base - dy >= 0) {\n                        pc_lower = {x1, y_base - dy};\n                        pd_lower = {x2, y_base - dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_lower) && current_dots.count(pd_lower)) {\n                            found_lower = true;\n                        }\n                    }\n\n                    // If no points were found in either direction at this distance 'dy',\n                    // and 'dy' has exceeded a reasonable limit (e.g., grid size), stop searching in this direction.\n                    if (!found_upper && !found_lower) {\n                        if (dy > N_val) break; // Heuristic limit to prevent excessive search.\n                        continue; // Continue to the next 'dy' if not out of bounds.\n                    }\n                    \n                    // If we found two points on the upper line (pc_upper, pd_upper):\n                    if (found_upper) {\n                        // Potential rectangle vertices are: (x1, y_base), (x2, y_base), pc_upper, pd_upper.\n                        // We need to find a NEW dot (p_new) and three OLD dots (p2_old, p3_old, p4_old).\n                        // If pc_upper is empty, it can be p_new. The existing dots are pd_upper, pa, pb.\n                        Point p_new = pc_upper;\n                        if (!current_dots.count(p_new)) {\n                            // Try forming the rectangle with p_new and the three existing dots.\n                            // The existing dots for this case are pd_upper, pa, pb.\n                            // Vertices are (x1, y_base), (x2, y_base), (x2, y_base+dy), (x1, y_base+dy).\n                            // Possible pairings for (p2_old, p3_old, p4_old) to form a rectangle with p_new=(x1, y_base+dy):\n                            // 1. (p_new, (x1, y_base), (x2, y_base), (x2, y_base+dy))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_upper)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_upper, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // 2. (p_new, pd_upper, pb, pa) - this order tries to form a rectangle (x1,y_up), (x2,y_up), (x2,y_base), (x1,y_base)\n                            if (current_dots.count(pd_upper) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_upper, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_upper, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_upper, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_upper is empty, it can be p_new. Existing dots: pc_upper, pa, pb.\n                        p_new = pd_upper;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_upper, pa, pb) -> ((x2, y_base+dy), (x1, y_base+dy), (x1, y_base), (x2, y_base))\n                            if (current_dots.count(pc_upper) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_upper, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_upper, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_upper, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pb, pa, pc_upper) -> ((x2, y_base+dy), (x2, y_base), (x1, y_base), (x1, y_base+dy))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_upper)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_upper, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    // If both upper and lower lines had pairs of points, we don't need to search further for this pa, pb pair in 'dy' direction.\n                    if (found_upper && found_lower) break; \n                    // If neither direction yielded points, further 'dy' won't find them either.\n                    if (!found_upper && !found_lower) break;\n                }\n            }\n\n            // Case 2: pa and pb share the same x-coordinate (form a vertical segment).\n            if (pa.x == pb.x) {\n                int x_base = pa.x;\n                int y1 = min(pa.y, pb.y);\n                int y2 = max(pa.y, pb.y);\n\n                // Search for points on parallel lines x_new = x_base + dx and x_new = x_base - dx.\n                for (int dx = 1; ; ++dx) {\n                    if (x_base + dx >= N_val && x_base - dx < 0) break;\n\n                    bool found_right = false;\n                    Point pc_right = {-1, -1}, pd_right = {-1, -1};\n                    // Check for points on the line x_base + dx.\n                    if (x_base + dx < N_val) {\n                        pc_right = {x_base + dx, y1};\n                        pd_right = {x_base + dx, y2};\n                        if (current_dots.count(pc_right) && current_dots.count(pd_right)) {\n                            found_right = true;\n                        }\n                    }\n\n                    bool found_left = false;\n                    Point pc_left = {-1, -1}, pd_left = {-1, -1};\n                    // Check for points on the line x_base - dx.\n                    if (x_base - dx >= 0) {\n                        pc_left = {x_base - dx, y1};\n                        pd_left = {x_base - dx, y2};\n                        if (current_dots.count(pc_left) && current_dots.count(pd_left)) {\n                            found_left = true;\n                        }\n                    }\n\n                    if (!found_right && !found_left) {\n                        if (dx > N_val) break;\n                        continue;\n                    }\n\n                    // If we found two points on the right line (pc_right, pd_right):\n                    if (found_right) {\n                        // Potential rectangle vertices: (x_base, y1), (x_base, y2), pc_right, pd_right.\n                        // Try placing new dot at pc_right. Existing dots are pd_right, pa, pb.\n                        Point p_new = pc_right;\n                        if (!current_dots.count(p_new)) {\n                            // Try (p_new, pa, pb, pd_right) -> ((x_base+dx, y1), (x_base, y1), (x_base, y2), (x_base+dx, y2))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_right)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_right) &&\n                                        !check_segment_overlap(pd_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_right, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pd_right, pb, pa) -> ((x_base+dx, y1), (x_base+dx, y2), (x_base, y2), (x_base, y1))\n                             if (current_dots.count(pd_right) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_right, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_right) &&\n                                        !check_segment_overlap(pd_right, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_right, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_right, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_right is empty, it can be p_new. Existing dots: pc_right, pa, pb.\n                        p_new = pd_right;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_right, pa, pb) -> ((x_base+dx, y2), (x_base+dx, y1), (x_base, y1), (x_base, y2))\n                            if (current_dots.count(pc_right) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_right, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_right) &&\n                                        !check_segment_overlap(pc_right, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_right, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_right, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                             // Try (p_new, pb, pa, pc_right) -> ((x_base+dx, y2), (x_base, y2), (x_base, y1), (x_base+dx, y1))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_right)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_right) &&\n                                        !check_segment_overlap(pc_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_right, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_right && found_left) break;\n                    if (!found_right && !found_left) break;\n                }\n            }\n        }\n    }\n\n    // --- Generate 45-degree Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point p_a = dots_vec[i];\n            Point p_b = dots_vec[j];\n\n            long long dx_ab = p_b.x - p_a.x;\n            long long dy_ab = p_b.y - p_a.y;\n\n            // Check if p_a and p_b could be adjacent vertices of a 45-degree rectangle.\n            // This implies their difference vector (dx_ab, dy_ab) must have |dx_ab| == |dy_ab| and not be zero.\n            if (abs(dx_ab) == abs(dy_ab) && dx_ab != 0) {\n                // The vector for the next side must be perpendicular and have the same length.\n                // Two possibilities for the next vector: (-dy_ab, dx_ab) and (dy_ab, -dx_ab).\n                int possible_v[2][2] = {{- (int)dy_ab, (int)dx_ab}, {(int)dy_ab, - (int)dx_ab}};\n\n                for (int k = 0; k < 2; ++k) {\n                    long long next_dx = possible_v[k][0];\n                    long long next_dy = possible_v[k][1];\n\n                    // Calculate the coordinates of the other two potential vertices of the rectangle.\n                    Point p_c = {p_b.x + (int)next_dx, p_b.y + (int)next_dy}; // p_c = p_b + next_vector\n                    Point p_d = {p_a.x + (int)next_dx, p_a.y + (int)next_dy}; // p_d = p_a + next_vector\n\n                    // Check if these potential points are within grid bounds.\n                    if (p_c.x >= 0 && p_c.x < N_val && p_c.y >= 0 && p_c.y < N_val &&\n                        p_d.x >= 0 && p_d.x < N_val && p_d.y >= 0 && p_d.y < N_val) {\n                        \n                        // If both p_c and p_d already exist as dots:\n                        if (current_dots.count(p_c) && current_dots.count(p_d)) {\n                            // We've found a rectangle formed by p_a, p_b, p_c, p_d.\n                            // A new dot can be placed at any of these vertices if it's currently empty.\n                            // We need to find an empty point (p_new) and three existing points (p2, p3, p4).\n\n                            // Case 1: p_a is the new dot (p_new). p_b, p_c, p_d must be existing dots.\n                            Point p_new = p_a;\n                            if (!current_dots.count(p_new)) { // Check if p_a is empty.\n                                // Order: (p_new, p_b, p_c, p_d) where p_b is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_b, p_c, p_d)) {\n                                    // Check for segment overlaps and perimeter dots.\n                                    if (!check_segment_overlap(p_new, p_b) &&\n                                        !check_segment_overlap(p_b, p_c) &&\n                                        !check_segment_overlap(p_c, p_d) &&\n                                        !check_segment_overlap(p_d, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_b, p_c, p_d, current_dots)) {\n                                            candidates.push_back({p_new, p_b, p_c, p_d, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 2: p_b is the new dot (p_new). p_a, p_c, p_d must be existing dots.\n                            p_new = p_b;\n                            if (!current_dots.count(p_new)) { // Check if p_b is empty.\n                                // Order: (p_new, p_a, p_d, p_c) where p_a is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_a, p_d, p_c)) {\n                                    if (!check_segment_overlap(p_new, p_a) &&\n                                        !check_segment_overlap(p_a, p_d) &&\n                                        !check_segment_overlap(p_d, p_c) &&\n                                        !check_segment_overlap(p_c, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_a, p_d, p_c, current_dots)) {\n                                            candidates.push_back({p_new, p_a, p_d, p_c, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 3: p_c is the new dot (p_new). p_a, p_b, p_d must be existing dots.\n                            p_new = p_c;\n                            if (!current_dots.count(p_new)) { // Check if p_c is empty.\n                                // Order: (p_new, p_d, p_a, p_b) where p_d is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_d, p_a, p_b)) {\n                                    if (!check_segment_overlap(p_new, p_d) &&\n                                        !check_segment_overlap(p_d, p_a) &&\n                                        !check_segment_overlap(p_a, p_b) &&\n                                        !check_segment_overlap(p_b, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_d, p_a, p_b, current_dots)) {\n                                            candidates.push_back({p_new, p_d, p_a, p_b, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 4: p_d is the new dot (p_new). p_a, p_b, p_c must be existing dots.\n                            p_new = p_d;\n                            if (!current_dots.count(p_new)) { // Check if p_d is empty.\n                                // Order: (p_new, p_c, p_b, p_a) where p_c is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_c, p_b, p_a)) {\n                                    if (!check_segment_overlap(p_new, p_c) &&\n                                        !check_segment_overlap(p_c, p_b) &&\n                                        !check_segment_overlap(p_b, p_a) &&\n                                        !check_segment_overlap(p_a, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_c, p_b, p_a, current_dots)) {\n                                            candidates.push_back({p_new, p_c, p_b, p_a, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M; // Number of initially placed dots.\n    cin >> N_val >> M;\n\n    // Calculate grid center coordinates. N is always odd.\n    center = {(int)(N_val - 1) / 2, (int)(N_val - 1) / 2};\n    total_weight_sum_val = 0; // Initialize total weight sum.\n\n    // Store the initial dots.\n    set<Point> current_dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        current_dots.insert({x, y});\n        total_weight_sum_val += weight({x, y}); // Add weight of initial dots.\n    }\n\n    // Store the operations performed.\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    int ops_count = 0;\n    // Game loop: continue as long as possible and within the operation limit.\n    while (ops_count < MAX_OPS) {\n        // Find all possible moves.\n        vector<CandidateMove> candidates = find_candidate_moves(current_dots);\n\n        // If no more moves can be made, break the loop.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates in descending order of weight (using reverse iterators on ascending sort).\n        sort(candidates.rbegin(), candidates.rend());\n\n        // Select the best move: the one with the highest weight for the new dot.\n        const auto& best_move = candidates[0];\n\n        // Apply the best move: add the new dot and update total weight.\n        current_dots.insert(best_move.p1_new);\n        total_weight_sum_val += best_move.weight_val;\n        ops_count++;\n\n        // Record the operation details.\n        operations.emplace_back(best_move.p1_new.x, best_move.p1_new.y,\n                                best_move.p2_old.x, best_move.p2_old.y,\n                                best_move.p3_old.x, best_move.p3_old.y,\n                                best_move.p4_old.x, best_move.p4_old.y);\n\n        // Add the segments of the newly drawn rectangle to the tracking maps.\n        add_segment(best_move.p1_new, best_move.p2_old);\n        add_segment(best_move.p2_old, best_move.p3_old);\n        add_segment(best_move.p3_old, best_move.p4_old);\n        add_segment(best_move.p4_old, best_move.p1_new);\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output the details of each operation.\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) << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <tuple>       // For std::tuple and std::tie\n#include <array>       // For std::array\n#include <queue>       // Not used, but common for grid problems\n\nusing namespace std;\n\nconst int SIZE = 10;\n// Maximum possible Manhattan distance in a 10x10 grid (e.g., from (0,0) to (9,9)).\nconst int MAX_DIST = (SIZE - 1) + (SIZE - 1); \n\n// Global board state. Using std::array for better C++ integration and compatibility with std::tuple.\n// 0 means empty, 1, 2, 3 represent the flavors.\nstd::array<std::array<int, SIZE>, SIZE> board;\n\n// Stores the predefined sequence of candy flavors (f_1, f_2, ..., f_100)\nint f_sequence[101];\n\n// Helper function to find the p_t-th empty cell.\n// Cells are numbered 1 to (101-t) based on row-major order.\n// Returns a pair {row, col} of the cell's coordinates.\npair<int, int> get_pt_empty_cell(int p_t) {\n    int empty_count = 0; // Counter for empty cells found so far\n    // Iterate through the grid row by row, then column by column\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            // If the current cell is empty\n            if (board[r][c] == 0) {\n                empty_count++; // Increment the count of empty cells\n                // If this is the p_t-th empty cell, return its coordinates\n                if (empty_count == p_t) {\n                    return {r, c};\n                }\n            }\n        }\n    }\n    // This part should ideally not be reached in a valid game state\n    // as p_t is guaranteed to be within the range of available empty cells.\n    return {-1, -1};\n}\n\n// Applies a tilt operation to the global 'board'.\n// This function modifies the actual game state.\nvoid apply_actual_tilt(char dir) {\n    // Create a temporary copy of the current board state.\n    // This is necessary because the tilt operation affects all candies simultaneously,\n    // and we need to know the state *before* any candy has moved to correctly update others.\n    std::array<std::array<int, SIZE>, SIZE> temp_board_state = board;\n\n    // Handle each tilt direction\n    if (dir == 'F') { // Tilt Forward (candies move towards larger row indices, i.e., down)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col; // Stores flavors in this column in their original order\n            // Collect all flavors in the current column from top to bottom from the *copied* state\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the column in the global board (preparing to repopulate)\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            // Repopulate the column from the bottom, packing candies\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[SIZE - 1 - (k - 1 - i)][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'B') { // Tilt Backward (candies move towards smaller row indices, i.e., up)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col;\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the column in the global board\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            // Repopulate the column from the top, packing candies\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[i][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'R') { // Tilt Right (candies move towards larger column indices, i.e., right)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the row in the global board\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            // Repopulate the row from the right, packing candies\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][SIZE - 1 - (k - 1 - i)] = flavors_in_row[i];\n            }\n        }\n    } else { // dir == 'L', Tilt Left (candies move towards smaller column indices, i.e., left)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the row in the global board\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            // Repopulate the row from the left, packing candies\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][i] = flavors_in_row[i];\n            }\n        }\n    }\n}\n\n// Simulates a tilt on a copy of the current board state.\n// Returns:\n// 1. The final row of the *newly placed* candy.\n// 2. The final column of the *newly placed* candy.\n// 3. The resulting board state after the tilt.\n// Uses std::array for the board state to enable proper tuple inclusion.\n// The original position (original_r, original_c) of the new candy is required to track its movement.\nstd::tuple<int, int, std::array<std::array<int, SIZE>, SIZE>> simulate_tilt_and_get_new_candy_pos(char dir, int original_r, int original_c) {\n    // This array will hold the board state after the simulated tilt.\n    std::array<std::array<int, SIZE>, SIZE> sim_board_state = board; // Copy current global board\n\n    int sim_r_final = -1, sim_c_final = -1; // Will store the final position of the *newly placed* candy\n\n    // Apply tilt logic to sim_board_state\n    if (dir == 'F') { // Move down\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor} in the column\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) { // Read from the copied state\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end()); // Sort by original row to determine packing order\n\n        int k = occupied_in_col.size();\n        // Clear the column in the simulated board before repopulating\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from bottom\n        for (int i = 0; i < k; ++i) {\n            int original_row_in_col = occupied_in_col[i].first; // Row index *before* clearing column\n            int new_row = SIZE - 1 - (k - 1 - i); // Packed to the bottom\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            // Check if this is the candy we are tracking by comparing its original row index\n            if (original_row_in_col == original_r) { \n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'B') { // Move up\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor}\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) {\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end());\n\n        int k = occupied_in_col.size();\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from top\n        for (int i = 0; i < k; ++i) {\n            int original_row_in_col = occupied_in_col[i].first;\n            int new_row = i; // Packed to the top\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            if (original_row_in_col == original_r) {\n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'R') { // Move right\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from right\n        for (int i = 0; i < k; ++i) {\n            int original_col_in_row = occupied_in_row[i].first;\n            int new_col = SIZE - 1 - (k - 1 - i); // Packed to the right\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col_in_row == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    } else { // dir == 'L', Move left\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from left\n        for (int i = 0; i < k; ++i) {\n            int original_col_in_row = occupied_in_row[i].first;\n            int new_col = i; // Packed to the left\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col_in_row == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    }\n    // Return the final position of the new candy and the simulated board state\n    return {sim_r_final, sim_c_final, sim_board_state};\n}\n\n// Calculates metrics for a given simulated board state and new candy position.\n// Returns:\n// 1. Number of neighbors within Manhattan distance D=2.\n// 2. Minimum Manhattan distance to any neighbor of the same flavor.\n//    If no neighbors exist, this is MAX_DIST.\npair<int, int> get_neighbor_metrics(int r, int c, int flavor, const std::array<std::array<int, SIZE>, SIZE>& sim_board) {\n    int num_neighbors_close = 0;\n    int min_dist_to_any_neighbor = MAX_DIST; // Initialize with a value indicating no neighbor found yet\n    const int CLOSE_DIST_THRESHOLD = 2; // Manhattan distance threshold for \"close\" neighbors\n\n    for (int r_other = 0; r_other < SIZE; ++r_other) {\n        for (int c_other = 0; c_other < SIZE; ++c_other) {\n            // Check if it's a candy of the same flavor AND it's NOT the new candy itself.\n            if (sim_board[r_other][c_other] == flavor && !(r_other == r && c_other == c)) {\n                int dist = abs(r - r_other) + abs(c - c_other);\n                \n                // Update minimum distance to any neighbor\n                min_dist_to_any_neighbor = min(min_dist_to_any_neighbor, dist);\n                \n                // Count neighbors within the close distance threshold\n                if (dist <= CLOSE_DIST_THRESHOLD) {\n                    num_neighbors_close++;\n                }\n            }\n        }\n    }\n    return {num_neighbors_close, min_dist_to_any_neighbor};\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the predefined sequence of candy flavors from input\n    for (int i = 1; i <= 100; ++i) {\n        cin >> f_sequence[i];\n    }\n\n    // Initialize the global board to be empty (all cells set to 0)\n    for (int i = 0; i < SIZE; ++i) {\n        for (int j = 0; j < SIZE; ++j) {\n            board[i][j] = 0;\n        }\n    }\n\n    // Main loop: Process each candy placement and make a tilt decision\n    // t is the current candy number being placed (1 to 100)\n    for (int t = 1; t <= 100; ++t) {\n        int p_t; // The index of the empty cell where the t-th candy will be placed.\n        cin >> p_t;\n\n        // Find the coordinates where the new candy is placed.\n        pair<int, int> cell = get_pt_empty_cell(p_t);\n        int current_r = cell.first;  // Original row of the new candy\n        int current_c = cell.second; // Original column of the new candy\n        int flavor_t = f_sequence[t]; // Flavor of the new candy\n        \n        // Place the candy in the actual board FIRST.\n        // The simulation functions will then read from this updated 'board'.\n        board[current_r][current_c] = flavor_t;\n\n        // For the 100th candy, no tilt is performed or output is required.\n        if (t == 100) {\n            continue; // Skip the rest of the loop for t=100\n        }\n\n        // Heuristic variables to track the best tilt choice.\n        // We want to:\n        // 1. Maximize number of close neighbors (dist <= 2).\n        // 2. Then, minimize distance to nearest neighbor.\n        // 3. Tie-break using lexicographical order of directions ('F' < 'B' < 'L' < 'R').\n        \n        int best_num_close_neighbors = -1; // Maximize this. Initialized to a value less than any possible count (which is >= 0).\n        int best_min_dist_to_any = MAX_DIST + 1; // Minimize this. Initialized to a value greater than any possible distance.\n        char best_tilt = 'F'; // Default best tilt for tie-breaking and initial assignment.\n\n        char possible_tilts[] = {'F', 'B', 'L', 'R'};\n\n        // Evaluate each possible tilt direction\n        for (char tilt_dir : possible_tilts) {\n            int sim_r_final, sim_c_final; // Final position of the new candy after simulated tilt\n            std::array<std::array<int, SIZE>, SIZE> temp_board_state; // Board state after simulated tilt\n\n            // Simulate the tilt and get the resulting state and the new candy's final position.\n            tie(sim_r_final, sim_c_final, temp_board_state) = simulate_tilt_and_get_new_candy_pos(tilt_dir, current_r, current_c);\n\n            // Get the neighbor metrics (number of close neighbors and minimum distance to any neighbor).\n            pair<int, int> metrics = get_neighbor_metrics(sim_r_final, sim_c_final, flavor_t, temp_board_state);\n            int current_num_close = metrics.first;\n            int current_min_dist = metrics.second;\n\n            // Check if the current tilt resulted in finding any neighbors.\n            bool current_has_neighbors = (current_min_dist != MAX_DIST);\n            // Check if the best tilt found so far also resulted in neighbors.\n            bool best_has_neighbors = (best_min_dist_to_any != MAX_DIST + 1);\n\n            bool update_best = false; // Flag to indicate if the current tilt is better than the best found so far.\n\n            // Decision logic based on the heuristic priorities:\n            if (current_has_neighbors && !best_has_neighbors) {\n                // Case 1: Current tilt found neighbors, but previous best didn't. Current is strictly better.\n                update_best = true;\n            } else if (current_has_neighbors && best_has_neighbors) {\n                // Case 2: Both current and best tilt have neighbors. Compare based on priority.\n                if (current_num_close > best_num_close_neighbors) {\n                    // Priority 1: More close neighbors is better.\n                    update_best = true;\n                } else if (current_num_close == best_num_close_neighbors) {\n                    // Priority 2: If close neighbor counts are tied, minimize nearest neighbor distance.\n                    if (current_min_dist < best_min_dist_to_any) {\n                        update_best = true;\n                    }\n                    // If still tied (current_min_dist == best_min_dist_to_any), the loop order handles Priority 3 (lexicographical).\n                    // 'best_tilt' will not be updated, preserving the earlier (lexicographically smaller) direction.\n                }\n            } else if (!current_has_neighbors && !best_has_neighbors) {\n                // Case 3: Neither current nor best tilt found neighbors. It's a tie.\n                // The 'best_tilt' variable already holds the lexicographically smallest direction encountered so far among those with no neighbors.\n                // No update needed, as the loop order ensures 'F' would be picked first if all are equally bad.\n            } else { // !current_has_neighbors && best_has_neighbors\n                // Case 4: Current tilt has no neighbors, but the best tilt found so far had neighbors.\n                // The best tilt is still better. Do nothing.\n            }\n\n            // If the current tilt is determined to be better, update the best tracking variables.\n            if (update_best) {\n                best_num_close_neighbors = current_num_close;\n                best_min_dist_to_any = current_min_dist;\n                best_tilt = tilt_dir;\n            }\n        }\n\n        // After evaluating all possible tilts, apply the chosen 'best_tilt' to the actual game board.\n        apply_actual_tilt(best_tilt);\n\n        // Output the chosen tilt direction, followed by a newline.\n        cout << best_tilt << endl;\n        // Flush the output buffer to ensure the judge receives the output immediately.\n        cout << flush;\n    }\n\n    // Program finishes after processing all 100 candies and their corresponding tilts.\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath> // For std::abs\n#include <random> // For std::mt19937 and std::shuffle\n\n// Function to compute the degree sequence of a graph from its bitstring representation.\n// The input string 's' represents edges (u,v) for 0 <= u < v <= N-1 in lexicographical order.\nstd::vector<int> get_degrees_from_string(int N, const std::string& s) {\n    std::vector<int> degrees(N, 0); // Initialize degrees for all vertices to 0\n    int k = 0; // Index for iterating through the bitstring\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (s[k] == '1') { // If an edge exists between vertex i and vertex j\n                degrees[i]++; // Increment degree of vertex i\n                degrees[j]++; // Increment degree of vertex j\n            }\n            k++; // Move to the next character in the bitstring\n        }\n    }\n    return degrees;\n}\n\nint main() {\n    // Fast I/O operations\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    std::cin >> M >> epsilon;\n\n    // --- Refined Strategy ---\n    // Analysis of previous results:\n    // - Fixed N=30 strategy yielded the highest score (~30.6M).\n    // - The identical scores in the last two submissions suggest the N=30 strategy is robust\n    //   but might be hitting a plateau.\n    // - The core issue for low scores is likely a high error rate (E) due to insufficient\n    //   distinguishability of base graphs under noise.\n    //\n    // Strategy for this iteration:\n    // Slightly increase N to potentially improve graph discriminability and reduce E,\n    // accepting a marginal decrease in the 1/N score multiplier.\n    //\n    // 1. Fixed N: Use N=32. This increases the number of possible edges to 32*31/2 = 496.\n    //    This provides more capacity for graph diversity compared to N=30 (435 edges).\n    //    The average initial edge gap for M=100 is ~496/99 ~ 5.01.\n    //    The effective gap at epsilon=0.4 is ~5.01 * (1 - 2*0.4) = ~1.002, crossing the\n    //    threshold of an \"effective gap of 1\", which might reduce E.\n    //    The 1/N multiplier will be 1/32.\n    const int N = 32; \n    \n    // Maximum possible edges in an N-vertex graph. For N=32, this is 32*31/2 = 496.\n    int max_possible_edges = N * (N - 1) / 2;\n\n    // Store precomputed degree sequences for G_0, ..., G_{M-1}.\n    std::vector<std::vector<int>> precomputed_degrees(M, std::vector<int>(N));\n    // Store the string representations of G_0, ..., G_{M-1} for output.\n    std::vector<std::string> graph_strings(M);\n\n    // Seed the random number generator for graph generation.\n    // Using a fixed seed (0) ensures reproducible graph generation.\n    std::mt19937 rng(0); \n\n    // Pre-calculate all possible edge indices in the string representation (u < v).\n    // The string index for edge (u,v) is computed by summing the number of edges in\n    // rows 0 to u-1, plus the position of v within row u.\n    std::vector<int> all_string_indices(max_possible_edges);\n    int current_edge_idx_in_list = 0;\n    for (int u = 0; u < N; ++u) {\n        // Offset for edges starting with vertex u: sum of edges in rows 0 to u-1.\n        // Formula: u * (2*N - u - 1) / 2\n        long long offset_u = static_cast<long long>(u) * (2 * N - u - 1) / 2;\n        for (int v = u + 1; v < N; ++v) {\n            // Index of edge (u,v) in the string (u < v)\n            // = offset_u + (v - (u+1))\n            all_string_indices[current_edge_idx_in_list++] = static_cast<int>(offset_u + (v - (u + 1)));\n        }\n    }\n\n    // Generate M distinct graphs.\n    // Use random graph generation, distributing edge counts linearly from 0 to max_possible_edges.\n    for (int i = 0; i < M; ++i) {\n        // Calculate the target number of edges for graph G_i using linear interpolation.\n        // This spreads the edge counts across the full range [0, max_possible_edges].\n        int target_edges = static_cast<int>(static_cast<long long>(i) * max_possible_edges / (M - 1));\n        \n        // Ensure target_edges is within valid bounds [0, max_possible_edges].\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n\n        // Construct the graph string by randomly selecting 'target_edges'.\n        std::string current_graph_str(max_possible_edges, '0');\n        // Shuffle the list of all possible edge indices and pick the first 'target_edges'.\n        std::shuffle(all_string_indices.begin(), all_string_indices.end(), rng);\n        for (int edge_pos = 0; edge_pos < target_edges; ++edge_pos) {\n            current_graph_str[all_string_indices[edge_pos]] = '1';\n        }\n        graph_strings[i] = current_graph_str;\n        \n        // Compute and store the degree sequence for this graph G_i.\n        precomputed_degrees[i] = get_degrees_from_string(N, graph_strings[i]);\n    }\n\n    // Output N, followed by the string representations of the M generated graphs.\n    std::cout << N << std::endl;\n    for (int i = 0; i < M; ++i) {\n        std::cout << graph_strings[i] << std::endl;\n    }\n    // Flush the output buffer to ensure all generated graph data is sent to the judge.\n    std::cout << std::flush; \n\n    // Process the 100 queries.\n    for (int k = 0; k < 100; ++k) {\n        std::string H_str; // The graph string received for the current query H_k.\n        std::cin >> H_str;\n\n        // Compute the degree sequence of the received graph H_k.\n        std::vector<int> degrees_H = get_degrees_from_string(N, H_str);\n\n        int best_match_idx = -1; // Stores the index of the best matching G_i found so far.\n        // Initialize min_dist to a value larger than any possible L1 distance.\n        // The maximum L1 distance between two degree sequences is N * (N-1).\n        // For N=32, this is 32*31 = 992.\n        // Using -1 as a sentinel for the first assignment.\n        long long min_dist = -1; \n\n        // Find which precomputed graph G_i has a degree sequence 'closest' to H_k's degree sequence.\n        // Closeness is measured by the L1 distance (sum of absolute differences in degrees).\n        for (int i = 0; i < M; ++i) {\n            long long current_dist = 0; // L1 distance for G_i.\n            for (int j = 0; j < N; ++j) {\n                current_dist += std::abs(degrees_H[j] - precomputed_degrees[i][j]);\n            }\n\n            // If this is the first graph considered (best_match_idx == -1), or\n            // if the current graph G_i is closer to H_k than the current best match,\n            // update the best match.\n            if (best_match_idx == -1 || current_dist < min_dist) {\n                min_dist = current_dist;\n                best_match_idx = i;\n            }\n        }\n        \n        // Output the predicted index t_k.\n        std::cout << best_match_idx << std::endl;\n        // Flush the output buffer to ensure the prediction is sent immediately.\n        std::cout << std::flush; \n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Use a large value for infinity, greater than any possible shortest path sum.\n// Max path length can be approximately N * max_w = 1000 * 10^6 = 10^9.\n// The problem uses 10^9 for unreachable distances. Our internal INF must be larger\n// to correctly identify unreachable nodes in Dijkstra's algorithm.\nconst long long INF = 4e15; \n\n// Structure to represent an edge in the graph.\nstruct Edge {\n    int u, v, w, id;       // Endpoints, weight, and original index of the edge.\n    long long dist_uv;     // Shortest path distance between u and v in the original graph.\n    long long endpoint_path_sum; // Sum of shortest paths from all nodes to u and v.\n    int assignment;        // The day this edge is scheduled for repair.\n};\n\n// Structure for Dijkstra's priority queue: stores distance and vertex.\nstruct State {\n    long long dist;\n    int vertex;\n\n    // For priority_queue: sort by distance (min-heap).\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\n// Dijkstra's algorithm to find shortest paths from a single source vertex.\n// It returns a vector containing the shortest distance from start_node to every other node.\n// Time complexity: O(M log N) or O(M + N log N) depending on priority queue implementation.\nvector<long long> dijkstra(int start_node, int n, const vector<vector<pair<int, int>>>& adj) {\n    vector<long long> dist(n + 1, INF); // Initialize distances to infinity.\n    dist[start_node] = 0;               // Distance from source to itself is 0.\n    priority_queue<State, vector<State>, greater<State>> pq;\n    pq.push({0, start_node});\n\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        long long d = current.dist;\n        int v = current.vertex;\n\n        // If we found a shorter path to 'v' already, skip this one.\n        if (d > dist[v]) {\n            continue;\n        }\n\n        // Explore neighbors of vertex 'v'.\n        for (auto& edge_info : adj[v]) {\n            int neighbor = edge_info.first;\n            int weight = edge_info.second;\n            \n            // Relaxation step: If a shorter path to 'neighbor' is found through 'v'.\n            // Check for overflow before addition. If dist[v] is INF, dist[v] + weight will be larger than any finite path or INF, so this condition handles INF correctly.\n            if (dist[v] != INF && dist[v] + weight < dist[neighbor]) {\n                dist[neighbor] = dist[v] + weight;\n                pq.push({dist[neighbor], neighbor});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, d_days, k_limit;\n    cin >> n >> m >> d_days >> k_limit;\n\n    // Adjacency list for graph: vector of vectors of pairs {neighbor, weight}.\n    // Vertices are 1-indexed in input, so we use size n+1 for 1-based indexing.\n    vector<vector<pair<int, int>>> adj(n + 1);\n    vector<Edge> edges;\n    edges.reserve(m); // Pre-allocate memory for edges.\n\n    // Read edges and build the adjacency list.\n    for (int i = 0; i < m; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w}); // Graph is undirected.\n        // Store edge details including its original index 'i' (0 to m-1).\n        edges.push_back({u, v, w, i, 0, 0, 0}); // Initialize endpoint_path_sum to 0\n    }\n\n    // Step 1: Compute all-pairs shortest paths (APSP).\n    // This is done by running Dijkstra from each vertex.\n    // For N=1000, M=3000, complexity O(N*(M+N log N)) is feasible.\n    vector<vector<long long>> dist_matrix(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        dist_matrix[i] = dijkstra(i, n, adj);\n    }\n\n    // Step 2: Precompute sum of shortest path distances from all nodes to each node.\n    // sum_dist_to[j] will store sum(dist_matrix[i][j] for i = 1 to N).\n    vector<long long> sum_dist_to(n + 1, 0);\n    for (int i = 1; i <= n; ++i) { // Source node\n        for (int j = 1; j <= n; ++j) { // Destination node\n            // Only add finite distances. The graph is guaranteed to be connected.\n            if (dist_matrix[i][j] != INF) {\n                sum_dist_to[j] += dist_matrix[i][j];\n            }\n        }\n    }\n\n    // Step 3: For each edge, populate dist_uv and endpoint_path_sum.\n    for (auto& edge : edges) {\n        edge.dist_uv = dist_matrix[edge.u][edge.v];\n        \n        // Calculate sum of shortest paths involving endpoints for this edge.\n        // This heuristic tries to capture how \"central\" the edge's endpoints are.\n        // Use long long to avoid overflow for sums.\n        edge.endpoint_path_sum = sum_dist_to[edge.u] + sum_dist_to[edge.v];\n    }\n\n    // Step 4: Sort edges based on a refined heuristic.\n    // Heuristic:\n    // 1. Prioritize edges that are direct shortest paths (i.e., edge.w == edge.dist_uv).\n    // 2. Among those, prioritize edges connecting vertices with high 'centrality' (large endpoint_path_sum).\n    // 3. If ties persist, prioritize edges connecting vertices that are far apart (large edge.dist_uv).\n    // 4. If ties persist, prioritize heavier edges (large edge.w).\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        bool is_direct_shortest_a = (a.dist_uv == a.w);\n        bool is_direct_shortest_b = (b.dist_uv == b.w);\n\n        if (is_direct_shortest_a != is_direct_shortest_b) {\n            // Prioritize edges that are direct shortest paths. 'true' (1) > 'false' (0).\n            return is_direct_shortest_a > is_direct_shortest_b; \n        }\n        \n        // If both are direct shortest paths OR both are not:\n        if (a.endpoint_path_sum != b.endpoint_path_sum) {\n            // Prioritize edges whose endpoints are more central (higher sum of path lengths).\n            return a.endpoint_path_sum > b.endpoint_path_sum;\n        }\n\n        if (a.dist_uv != b.dist_uv) {\n            // Prioritize edges connecting vertices that are farther apart.\n            return a.dist_uv > b.dist_uv; \n        }\n        \n        // If all previous criteria are equal:\n        // Prioritize heavier edges.\n        return a.w > b.w; \n    });\n\n    // Step 5: Assign edges to days using a round-robin approach for better balance.\n    // This ensures that the top-ranked (most critical) edges are spread out over all D days.\n    // The constraint K > ceil(M/D) guarantees that each day will receive at most ceil(M/D) edges, which is <= K.\n    vector<int> assignments(m); // To store the day assignment for each edge, indexed by its original ID.\n    \n    for (int i = 0; i < m; ++i) {\n        // Assign the i-th edge in the sorted list to day (i % d_days) + 1.\n        int assigned_day = (i % d_days) + 1;\n        edges[i].assignment = assigned_day;\n        assignments[edges[i].id] = assigned_day;\n    }\n\n    // Step 6: Output the assignments for each edge in the order they appeared in the input.\n    for (int i = 0; i < m; ++i) {\n        cout << assignments[i] << (i == m - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\n// Grid index helpers\n#define GRID_IDX(x, y, z, D) ((x) * (D) * (D) + (y) * (D) + (z))\n\n// Grid access macros\n#define GRID_GET(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n#define GRID_WRITE(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n\n// Polycube representation\nstruct Polycube {\n    vector<tuple<int, int, int>> cells; // Stores cells in grid coordinates (x, y, z)\n\n    // Custom comparison for Polycube, used for std::map keys.\n    // Sorts cells lexicographically.\n    bool operator<(const Polycube& other) const {\n        return cells < other.cells;\n    }\n    bool operator==(const Polycube& other) const {\n        return cells == other.cells;\n    }\n    int volume() const { return cells.size(); }\n};\n\n// Global parameters\nint D;\nvector<string> f1_str, r1_str, f2_str, r2_str;\nvector<bool> G1_grid, G2_grid; // G1_grid[idx] is true if cell can be occupied for obj1\n\n// --- ID and Shape Management ---\n// Counter for unique block IDs to be used in the output grid.\n// Each DISTINCT CONNECTED COMPONENT placed gets a unique ID.\nint next_component_output_id_counter; \n\n// Map: canonical_shape -> score_id.\n// A score_id is assigned to each distinct SHAPE. This is used for scoring.\nmap<Polycube, int> shape_to_score_id;\n// Counter for assigning new score_ids to new shapes.\nint next_score_id_counter; \n\n// Store assignments for each object.\nstruct BlockAssignment {\n    int output_id;       // Unique ID for this specific connected component in the output grid.\n    int score_id;        // ID representing its canonical shape for scoring purposes.\n    Polycube shape_grid_coords; // The actual polycube in grid coordinates.\n};\nvector<BlockAssignment> assignments1, assignments2;\n\n// Library of basic polycubes (shapes to generate orientations from)\nvector<Polycube> base_library_shapes;\n\n// Pre-generated orientations for library shapes.\n// Stores {volume, list_of_normalized_orientations}\nvector<pair<int, vector<Polycube>>> precomputed_library_orientations;\n\n// Helper to create a 3D grid vector\ntemplate<typename T>\nvector<T> create_grid_vec(size_t size, T default_val) {\n    return vector<T>(size, default_val);\n}\n\n// Convert string silhouettes to boolean grids representing valid cell locations\nvoid setup_grids() {\n    G1_grid.assign(D * D * D, false);\n    G2_grid.assign(D * D * D, false);\n\n    // For object 1, a cell (x,y,z) can be occupied if f1(z,x)=1 and r1(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int x = 0; x < D; ++x) {\n            if (f1_str[z][x] == '1') {\n                for (int y = 0; y < D; ++y) {\n                    if (r1_str[z][y] == '1') {\n                        GRID_GET(G1_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // For object 2, a cell (x,y,z) can be occupied if f2(z,x)=1 and r2(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int y = 0; y < D; ++y) {\n            if (r2_str[z][y] == '1') {\n                for (int x = 0; x < D; ++x) {\n                    if (f2_str[z][x] == '1') {\n                        GRID_GET(G2_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalize a polycube: translate its cells so the minimum coordinate is (0,0,0)\n// and sort the cells lexicographically. This gives a canonical representation for translation.\nPolycube normalize(const Polycube& poly) {\n    if (poly.cells.empty()) return poly;\n    \n    int min_x = get<0>(poly.cells[0]);\n    int min_y = get<1>(poly.cells[0]);\n    int min_z = get<2>(poly.cells[0]);\n    for (const auto& cell : poly.cells) {\n        min_x = min(min_x, get<0>(cell));\n        min_y = min(min_y, get<1>(cell));\n        min_z = min(min_z, get<2>(cell));\n    }\n    \n    Polycube normalized_poly;\n    normalized_poly.cells.reserve(poly.cells.size());\n    for (const auto& cell : poly.cells) {\n        normalized_poly.cells.emplace_back(get<0>(cell) - min_x, get<1>(cell) - min_y, get<2>(cell) - min_z);\n    }\n    sort(normalized_poly.cells.begin(), normalized_poly.cells.end());\n    return normalized_poly;\n}\n\n// Generate all unique orientations (rotations) of a polycube.\n// Returns a vector of normalized Polycubes.\nvector<Polycube> get_orientations(const Polycube& poly) {\n    set<Polycube> unique_orientations;\n    vector<tuple<int,int,int>> current_cells = poly.cells;\n\n    // Apply rotations around X, Y, Z axes\n    for (int rotx = 0; rotx < 4; ++rotx) { // Rotations around X-axis\n        vector<tuple<int,int,int>> current_cells_y = current_cells;\n        for (int roty = 0; roty < 4; ++roty) { // Rotations around Y-axis\n            vector<tuple<int,int,int>> current_cells_z = current_cells_y;\n            for (int rotz = 0; rotz < 4; ++rotz) { // Rotations around Z-axis\n                Polycube oriented_poly;\n                oriented_poly.cells = current_cells_z;\n                unique_orientations.insert(normalize(oriented_poly));\n                \n                // Rotate around Z: (x, y, z) -> (-y, x, z)\n                vector<tuple<int,int,int>> next_z;\n                next_z.reserve(current_cells_z.size());\n                for(const auto& cell : current_cells_z) next_z.emplace_back(-get<1>(cell), get<0>(cell), get<2>(cell));\n                current_cells_z = next_z;\n            }\n            // Rotate around Y: (x, y, z) -> (z, y, -x)\n            vector<tuple<int,int,int>> next_y;\n            next_y.reserve(current_cells_y.size());\n            for(const auto& cell : current_cells_y) next_y.emplace_back(get<2>(cell), get<1>(cell), -get<0>(cell));\n            current_cells_y = next_y;\n        }\n        // Rotate around X: (x, y, z) -> (x, -z, y)\n        vector<tuple<int,int,int>> next_x;\n        next_x.reserve(current_cells.size());\n        for(const auto& cell : current_cells) next_x.emplace_back(get<0>(cell), -get<2>(cell), get<1>(cell));\n        current_cells = next_x;\n    }\n\n    vector<Polycube> orientations;\n    orientations.reserve(unique_orientations.size());\n    for (const auto& p : unique_orientations) orientations.push_back(p);\n    return orientations;\n}\n\n// Initialize the library of polycubes with all their orientations\nvoid initialize_library() {\n    // Define a set of 'base' polycubes to generate orientations from.\n    base_library_shapes.push_back({{{0,0,0}}}); // Monomino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}}}); // Domino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}}}); // L-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}}}); // I-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}}}); // Square tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {3,0,0}}}); // I-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}}}); // I-tetromino (vertical)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {1,1,0}}}); // T-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {1,1,0}, {2,1,0}}}); // Skew tetromino (S)\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {1,1,0}, {1,2,0}}}); // Skew tetromino (Z)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {2,1,0}}}); // L-tetromino\n    // Add more shapes if needed for better scores.\n\n    // Use a map to group orientations by their canonical form.\n    map<Polycube, vector<Polycube>> unique_canonical_shapes;\n\n    for(const auto& base_shape : base_library_shapes) {\n        vector<Polycube> orientations = get_orientations(base_shape); // These are already normalized\n        \n        // The first orientation in the list represents the canonical form.\n        Polycube canonical_form = orientations[0]; \n        \n        // If this canonical form is already in our map, skip.\n        if (unique_canonical_shapes.find(canonical_form) == unique_canonical_shapes.end()) {\n            unique_canonical_shapes[canonical_form] = orientations;\n        }\n    }\n    \n    // Populate precomputed_library_orientations from the map.\n    for(auto const& [canonical_shape, orientations_list] : unique_canonical_shapes) {\n        precomputed_library_orientations.push_back({(int)orientations_list[0].cells.size(), orientations_list});\n    }\n\n    // Sort library by volume descending to prioritize larger blocks.\n    sort(precomputed_library_orientations.rbegin(), precomputed_library_orientations.rend());\n}\n\n// Utility to check if a cell coordinate is within the DxD D grid bounds\nbool is_valid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n    \n// Attempt to place a given normalized block_shape (from the library) such that it covers the target cell.\n// Returns true if a valid placement is found, false otherwise.\n// If true, 'placed_block_out_grid_coords' will contain the actual polycube in grid coordinates.\nbool try_place(const Polycube& normalized_library_shape, // A normalized orientation from the library\n               int target_x, int target_y, int target_z, // The cell we MUST cover\n               const vector<bool>& G, // Grid indicating valid cell locations for the object\n               const vector<bool>& covered, // Grid indicating already occupied cells\n               Polycube& placed_block_out_grid_coords) { // Output: the placed polycube in grid coordinates\n\n    // Iterate through each cell of the normalized_library_shape to try aligning it with the target cell.\n    for (const auto& cell_in_shape : normalized_library_shape.cells) {\n        int shape_cell_x, shape_cell_y, shape_cell_z;\n        tie(shape_cell_x, shape_cell_y, shape_cell_z) = cell_in_shape;\n\n        // Calculate the potential origin (top-left-front corner) of the block in grid coordinates.\n        int origin_x = target_x - shape_cell_x;\n        int origin_y = target_y - shape_cell_y;\n        int origin_z = target_z - shape_cell_z;\n\n        Polycube current_placement_grid_coords; // To store cells of the potential placement\n        bool possible = true;\n\n        // Check if all cells of the block, when placed at this origin, are valid.\n        for (const auto& cell_in_shape_ : normalized_library_shape.cells) {\n            int cx, cy, cz;\n            tie(cx, cy, cz) = cell_in_shape_;\n            \n            // Calculate actual grid coordinates for this cell of the block.\n            int px = origin_x + cx;\n            int py = origin_y + cy;\n            int pz = origin_z + cz;\n\n            // Check boundaries, if cell is allowed by G, and if it's not already covered.\n            if (!is_valid(px, py, pz) || !GRID_GET(G, px, py, pz, D) || GRID_GET(covered, px, py, pz, D)) {\n                possible = false;\n                break;\n            }\n            current_placement_grid_coords.cells.emplace_back(px, py, pz);\n        }\n\n        if (possible) {\n            // Found a valid placement that covers (target_x, target_y, target_z) and respects constraints.\n            placed_block_out_grid_coords = current_placement_grid_coords;\n            return true;\n        }\n    }\n    return false; // No valid placement found for this library block shape to cover the target cell.\n}\n\n// Greedy fill function\nvoid fill_object(const vector<bool>& G,\n                 vector<bool>& covered,\n                 vector<BlockAssignment>& assignments,\n                 bool is_object1) {\n\n    // Iterate through all cells of the grid.\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 this cell must be filled (according to G) and is not yet covered by any block:\n                if (GRID_GET(G, x, y, z, D) && !GRID_GET(covered, x, y, z, D)) {\n                    // This cell (x,y,z) must be part of a NEW, CONNECTED block instance.\n                    \n                    bool block_placed_in_this_step = false;\n                    Polycube best_placed_block_grid_coords; // Stores the best found block instance in grid coordinates.\n                    int best_block_score_id = -1;             // The score_id associated with this shape.\n                    int max_volume_found = -1;                // To prioritize larger blocks.\n\n                    // --- Attempt to fit the largest possible library block first ---\n                    for (const auto& lib_item : precomputed_library_orientations) {\n                        int current_vol = lib_item.first;\n                        const vector<Polycube>& orientations = lib_item.second; // list of normalized orientations\n\n                        // Optimization: If we already found a block and the current library block is not larger, skip.\n                        if (block_placed_in_this_step && current_vol <= max_volume_found) continue;\n\n                        // Try each orientation of the current library shape.\n                        for (const auto& oriented_shape_normalized : orientations) { \n                            Polycube current_placed_block_grid_coords; // To store the resulting polycube in grid coords\n                            \n                            // try_place will find an alignment that covers (x,y,z) and forms a valid, connected polycube.\n                            if (try_place(oriented_shape_normalized, x, y, z, G, covered, current_placed_block_grid_coords)) {\n                                // Success! 'current_placed_block_grid_coords' is a single, connected polycube.\n                                \n                                // Get its canonical form to determine its score_id.\n                                Polycube canonical_form = normalize(current_placed_block_grid_coords);\n                                \n                                int current_score_id;\n                                // Find or assign a score_id for this canonical shape.\n                                if (shape_to_score_id.count(canonical_form)) {\n                                    // This shape has been seen before, reuse its score_id.\n                                    current_score_id = shape_to_score_id[canonical_form];\n                                } else {\n                                    // New shape, assign a new score_id.\n                                    current_score_id = next_score_id_counter++;\n                                    shape_to_score_id[canonical_form] = current_score_id;\n                                }\n                                \n                                // We found a candidate block. If it's larger than the previous best for this cell, update.\n                                if (!block_placed_in_this_step || current_vol > max_volume_found) {\n                                    best_placed_block_grid_coords = current_placed_block_grid_coords; // Store the actual placed polycube\n                                    best_block_score_id = current_score_id;\n                                    max_volume_found = current_vol;\n                                    block_placed_in_this_step = true;\n                                }\n                            }\n                        }\n                    }\n                    \n                    // --- Assignment ---\n                    if (block_placed_in_this_step) {\n                        // Assign a NEW, UNIQUE output ID to this specific connected component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        // Add the assignment, linking the output ID, score ID, and the placed block.\n                        assignments.push_back({current_component_output_id, best_block_score_id, best_placed_block_grid_coords});\n                        \n                        // Mark all cells of this specific block instance as covered.\n                        for (const auto& cell : best_placed_block_grid_coords.cells) {\n                            GRID_GET(covered, get<0>(cell), get<1>(cell), get<2>(cell), D) = true;\n                        }\n                    } else {\n                        // Fallback: No library block could be placed starting from (x,y,z).\n                        // Place a 1x1x1 unit block at (x,y,z).\n                        Polycube unit_block_cell_grid_coords = {{{x, y, z}}}; // The single cell at its grid position\n                        Polycube canonical_unit = normalize(unit_block_cell_grid_coords); // Canonical is {{{0,0,0}}}\n\n                        int current_score_id;\n                        // Get or assign score_id for the unit block shape.\n                        if (shape_to_score_id.count(canonical_unit)) {\n                            current_score_id = shape_to_score_id[canonical_unit];\n                        } else {\n                            current_score_id = next_score_id_counter++;\n                            shape_to_score_id[canonical_unit] = current_score_id;\n                        }\n                        \n                        // Assign a NEW, UNIQUE output ID to this unit block component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        assignments.push_back({current_component_output_id, current_score_id, unit_block_cell_grid_coords});\n                        GRID_GET(covered, x, y, z, D) = true; // Mark this cell as covered.\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input D (dimension of the grid)\n    cin >> D;\n    \n    // Resize input strings for silhouettes\n    f1_str.resize(D); r1_str.resize(D);\n    f2_str.resize(D); r2_str.resize(D);\n\n    // Read the four silhouette images\n    for (int i = 0; i < D; ++i) cin >> f1_str[i];\n    for (int i = 0; i < D; ++i) cin >> r1_str[i];\n    for (int i = 0; i < D; ++i) cin >> f2_str[i];\n    for (int i = 0; i < D; ++i) cin >> r2_str[i];\n\n    // Initialize the grids that define where cells can be occupied\n    setup_grids();\n    // Initialize the library of shapes and their orientations\n    initialize_library();\n\n    // Initialize counters.\n    // next_component_output_id_counter ensures each placed component gets a unique ID for the output grid.\n    next_component_output_id_counter = 1; \n    // next_score_id_counter ensures each distinct shape gets a unique score_id for scoring.\n    next_score_id_counter = 1;          \n    shape_to_score_id.clear();          // Clear for object 1.\n    assignments1.clear();               \n    vector<bool> covered1(D * D * D, false);\n    fill_object(G1_grid, covered1, assignments1, true); // Fill object 1\n\n    // Process object 2.\n    // IMPORTANT: Counters are NOT reset for shapes. This allows sharing score_ids for identical shapes.\n    // HOWEVER, next_component_output_id_counter must NOT be reset if we want output IDs to be global and unique across both objects.\n    // Based on problem statement and example, total 'n' blocks means total unique components.\n    assignments2.clear();               \n    vector<bool> covered2(D * D * D, false);\n    fill_object(G2_grid, covered2, assignments2, false); // Fill object 2\n\n    // --- Output ---\n    // The total number of blocks 'n' is the maximum output ID used.\n    cout << next_component_output_id_counter - 1 << endl;\n\n    // Output for object 1: Use the unique output_id for each component.\n    vector<int> b1_output(D * D * D, 0);\n    for (const auto& assign : assignments1) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b1_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b1_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    // Output for object 2: Use the unique output_id for each component.\n    vector<int> b2_output(D * D * D, 0);\n    for (const auto& assign : assignments2) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b2_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b2_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <map>\n\n// Use long double for precision in distance calculations\nusing ftype = long double;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nstruct Resident {\n    int id;\n    Point pos;\n};\n\nint N_stations_global, M_edges_global, K_residents_global;\nstd::vector<Point> station_pos_global;\nstd::vector<Edge> edges_global; // Store edges with original IDs and weights\nstd::vector<Resident> residents_global;\n\n// Precomputed distances: dists_global[i][k] is distance from station i to resident k\nstd::vector<std::vector<ftype>> dists_global;\n\n// Function to calculate Euclidean distance\nftype dist(Point p1, Point p2) {\n    ftype dx = static_cast<ftype>(p1.x) - p2.x;\n    ftype dy = static_cast<ftype>(p1.y) - p2.y;\n    return std::sqrt(dx * dx + dy * dy);\n}\n\n// Calculate total cost\nlong long calculate_total_cost(const std::vector<int>& P, const std::vector<int>& B) {\n    long long edge_cost = 0;\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (B[j]) {\n            edge_cost += edges_global[j].w;\n        }\n    }\n    long long station_cost = 0;\n    for (int i = 0; i < N_stations_global; ++i) {\n        station_cost += static_cast<long long>(P[i]) * P[i];\n    }\n    return station_cost + edge_cost;\n}\n\n// Helper to compute reachable vertices from station 0\nstd::vector<int> get_reachable_stations(int N, const std::vector<int>& B_current, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> reachable_indices;\n    std::vector<std::vector<int>> adj(N);\n    \n    // Rebuild adjacency list from active edges (B_current)\n    for(const auto& edge : all_edges_indexed) {\n        if (B_current[edge.id]) { // Use edge.id to check B_current\n            adj[edge.u].push_back(edge.v);\n            adj[edge.v].push_back(edge.u);\n        }\n    }\n\n    std::queue<int> q;\n    if (N > 0) { // Station 0 is always source\n        q.push(0);\n        reachable_indices.push_back(0);\n    }\n    \n    std::vector<bool> visited(N, false);\n    if (N > 0) visited[0] = true;\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for(int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                reachable_indices.push_back(v);\n            }\n        }\n    }\n    return reachable_indices;\n}\n\n\n// --- Optimized P Assignment using Priority Queue ---\n\n// Struct to hold state for PQ in solve_P_greedy_marginal_cost\nstruct StationUpgradeState {\n    long long marginal_cost; // Cost to cover the *next* uncovered resident for this station\n    int station_idx;\n\n    bool operator>(const StationUpgradeState& other) const {\n        // Primary sort by cost, secondary by station index for deterministic behavior\n        if (marginal_cost != other.marginal_cost) {\n            return marginal_cost > other.marginal_cost; // Min-heap\n        }\n        return station_idx > other.station_idx;\n    }\n};\n\n// Global structures for the PQ-based solver\nstd::vector<std::vector<std::pair<ftype, int>>> residents_by_dist_global; // For each station, residents sorted by distance {distance, resident_id}\nstd::vector<int> next_uncovered_resident_idx_global; // For each station, index into residents_by_dist_global\nstd::vector<bool> global_resident_covered_global;\nint current_uncovered_count_global;\n\n// Function to update coverage status and push next upgrade to PQ\nvoid update_coverage_and_pq(int station_idx, std::vector<int>& P, \n                            std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>>& pq) {\n    \n    if (station_idx >= N_stations_global || residents_by_dist_global[station_idx].empty()) return;\n\n    // Find the first resident for this station that is not yet covered and reachable by current P[station_idx]\n    int current_k_idx_in_list = next_uncovered_resident_idx_global[station_idx];\n    \n    while(current_k_idx_in_list < residents_by_dist_global[station_idx].size()) {\n        auto& resident_entry = residents_by_dist_global[station_idx][current_k_idx_in_list];\n        int k_id = resident_entry.second;\n        ftype dist_to_k = resident_entry.first;\n\n        // If resident is too far even with max P, skip it.\n        if (dist_to_k > 5000.0 + 1e-9) { \n            current_k_idx_in_list++;\n            continue;\n        }\n        // If resident is already covered OR cannot be covered by current P[station_idx]\n        if (global_resident_covered_global[k_id] || dist_to_k > P[station_idx] + 1e-9) {\n            current_k_idx_in_list++;\n            continue;\n        }\n        // Found an uncovered resident that is reachable by current P[station_idx]. Break to process it.\n        break;\n    }\n    next_uncovered_resident_idx_global[station_idx] = current_k_idx_in_list;\n\n    // If we've advanced past all residents for this station that can be covered by current P, return.\n    if (next_uncovered_resident_idx_global[station_idx] >= residents_by_dist_global[station_idx].size()) {\n        return;\n    }\n\n    // Now, process the found resident `k_id` which requires an increase in P.\n    auto& resident_entry = residents_by_dist_global[station_idx][next_uncovered_resident_idx_global[station_idx]];\n    int k_id = resident_entry.second;\n    ftype dist_to_k = resident_entry.first;\n\n    // Calculate the required P to cover this specific resident.\n    int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n    // The new P value must be at least the current P and at least the required P.\n    int new_p_val = std::max(P[station_idx], required_p_int);\n    \n    // Calculate the actual marginal cost for this specific upgrade step.\n    long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[station_idx]) * P[station_idx];\n    \n    // Push this potential upgrade to the PQ.\n    pq.push({actual_marginal_cost, station_idx});\n}\n\n\nstd::vector<int> solve_P_greedy_marginal_cost_pq(const std::vector<int>& V_prime_indices, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> P(N_stations_global, 0);\n    \n    if (K_residents_global == 0) return P; // No residents, no cost.\n\n    // If V_prime is empty and K > 0, coverage is impossible. Return zeros.\n    if (V_prime_indices.empty()) {\n        return P; \n    }\n\n    // Initialize global structures for PQ solver\n    residents_by_dist_global.assign(N_stations_global, std::vector<std::pair<ftype, int>>());\n    next_uncovered_resident_idx_global.assign(N_stations_global, 0);\n    global_resident_covered_global.assign(K_residents_global, false);\n    current_uncovered_count_global = K_residents_global;\n    \n    // Populate residents_by_dist_global and sort for stations in V_prime\n    for (int station_idx : V_prime_indices) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            // Only consider residents potentially coverable within max P (5000)\n            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { \n                residents_by_dist_global[station_idx].push_back({dists_global[station_idx][k], k});\n            }\n        }\n        // Sort residents by distance for this station\n        std::sort(residents_by_dist_global[station_idx].begin(), residents_by_dist_global[station_idx].end());\n        // Initialize next_uncovered_resident_idx_global for this station\n        next_uncovered_resident_idx_global[station_idx] = 0; \n    }\n\n    // Priority queue for upgrades\n    std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>> pq;\n\n    // Initial population of PQ: For each station, find the first resident it needs to cover\n    for (int station_idx : V_prime_indices) {\n        update_coverage_and_pq(station_idx, P, pq); \n    }\n\n    // Greedy loop: While there are uncovered residents and potential upgrades\n    while (current_uncovered_count_global > 0 && !pq.empty()) {\n        StationUpgradeState current_upgrade = pq.top();\n        pq.pop();\n\n        int s = current_upgrade.station_idx;\n        \n        // Re-evaluate: The PQ entry might be stale if P[s] has already increased\n        // or if the target resident is now covered by another station.\n        // Update the station's state to find the *actual* next resident to cover.\n        update_coverage_and_pq(s, P, pq); // This will update next_uncovered_resident_idx_global[s] and push new PQ entry if needed.\n\n        // If update_coverage_and_pq found a new resident or P[s] increased, it pushed to PQ.\n        // We need to ensure that *this* popped element from PQ is still valid for the current state.\n        // The 'current_upgrade.marginal_cost' might be outdated.\n        // The crucial part is that `update_coverage_and_pq` re-calculates based on current P[s].\n        // If the station `s` still needs to cover a resident and `update_coverage_and_pq` successfully pushed a valid state,\n        // then that new state will be processed later.\n        // For the CURRENT popped element, we need to know if it corresponds to the actual next step.\n\n        // The logic in `update_coverage_and_pq` is designed to find the *next* resident.\n        // If it returned, it implies the station `s` might need an upgrade to cover that resident.\n        // The cost pushed is `actual_marginal_cost` for that specific upgrade.\n        // We should apply the upgrade if `current_uncovered_count_global` is still positive.\n\n        // The PQ entry `current_upgrade` represents the cost to cover the resident that was\n        // `residents_by_dist_global[s][next_uncovered_resident_idx_global[s]]` AT THE TIME of pushing.\n        // After `update_coverage_and_pq` called above, `next_uncovered_resident_idx_global[s]` might have advanced.\n        // If the element we popped was for a resident already covered or too far, we simply ignore it.\n\n        // Re-check if the resident the popped entry was intended for is *still* the target and is uncovered.\n        if (next_uncovered_resident_idx_global[s] < residents_by_dist_global[s].size()) {\n            auto& resident_entry = residents_by_dist_global[s][next_uncovered_resident_idx_global[s]];\n            int k_id = resident_entry.second;\n            ftype dist_to_k = resident_entry.first;\n            \n            // If the resident is covered or too far with current P[s], this popped element is stale.\n            if (global_resident_covered_global[k_id] || dist_to_k > P[s] + 1e-9) {\n                // This PQ entry is stale because the resident is already covered or P[s] is already sufficient.\n                // `update_coverage_and_pq` might have already pushed a *new* entry for this station `s`\n                // if P[s] changed, or if `next_uncovered_resident_idx_global[s]` advanced.\n                continue; // Skip processing this stale entry.\n            }\n\n            // If we reach here, the popped entry is relevant, and `next_uncovered_resident_idx_global[s]` points to the uncovered resident.\n            // Calculate the required P and marginal cost based on the current P[s]\n            int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n            int new_p_val = std::max(P[s], required_p_int);\n            long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[s]) * P[s];\n\n            // Apply the upgrade\n            P[s] = new_p_val;\n\n            // Update coverage for all residents potentially covered by the new P[s] starting from this resident.\n            int initial_next_idx = next_uncovered_resident_idx_global[s]; // Start from current target\n            for (int i = initial_next_idx; i < residents_by_dist_global[s].size(); ++i) {\n                auto& current_resident_entry = residents_by_dist_global[s][i];\n                int resident_k_id = current_resident_entry.second;\n                ftype dist_to_resident_k = current_resident_entry.first;\n\n                if (dist_to_resident_k > P[s] + 1e-9) { // Stop if distance exceeds new P[s]\n                    break; \n                }\n\n                if (!global_resident_covered_global[resident_k_id]) {\n                    global_resident_covered_global[resident_k_id] = true;\n                    current_uncovered_count_global--;\n                }\n                // Update the index to the next potential resident for this station\n                next_uncovered_resident_idx_global[s] = i + 1;\n            }\n            \n            // After covering, re-populate PQ for station `s` in case it needs further upgrades.\n            update_coverage_and_pq(s, P, pq);\n        }\n    }\n\n    // Fallback for any remaining uncovered residents if PQ becomes empty but count > 0.\n    // This typically means coverage is impossible or requires very high P.\n    // Set P to 5000 for the closest station in V_prime that can cover it.\n    if (current_uncovered_count_global > 0) {\n        for(int k=0; k<K_residents_global; ++k) {\n            if (!global_resident_covered_global[k]) {\n                ftype min_d = 5001.0;\n                int best_station_idx = -1;\n                for (int station_idx : V_prime_indices) { // Use original V_prime_indices for this fallback\n                    ftype d = dists_global[station_idx][k];\n                    if (d <= 5000.0 + 1e-9) { // Can cover within max radius\n                        if (d < min_d) {\n                            min_d = d;\n                            best_station_idx = station_idx;\n                        }\n                    }\n                }\n                if (best_station_idx != -1) {\n                    // Force coverage by setting P to 5000.\n                    if (P[best_station_idx] < 5000) {\n                        P[best_station_idx] = 5000;\n                    }\n                }\n            }\n        }\n    }\n\n    return P;\n}\n\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> N_stations_global >> M_edges_global >> K_residents_global;\n\n    station_pos_global.resize(N_stations_global);\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cin >> station_pos_global[i].x >> station_pos_global[i].y;\n    }\n\n    edges_global.resize(M_edges_global);\n    for (int i = 0; i < M_edges_global; ++i) {\n        edges_global[i].id = i;\n        std::cin >> edges_global[i].u >> edges_global[i].v >> edges_global[i].w;\n        edges_global[i].u--; // 0-indexed\n        edges_global[i].v--; // 0-indexed\n    }\n\n    residents_global.resize(K_residents_global);\n    for (int i = 0; i < K_residents_global; ++i) {\n        residents_global[i].id = i;\n        std::cin >> residents_global[i].pos.x >> residents_global[i].pos.y;\n    }\n\n    // 1. Precompute all distances\n    dists_global.resize(N_stations_global, std::vector<ftype>(K_residents_global));\n    for (int i = 0; i < N_stations_global; ++i) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            dists_global[i][k] = dist(station_pos_global[i], residents_global[k].pos);\n        }\n    }\n\n    // Sort edges by weight for MST and pruning\n    std::vector<Edge> sorted_edges = edges_global;\n    std::sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    // 2. Initial Connectivity using MST\n    std::vector<int> parent(N_stations_global);\n    std::iota(parent.begin(), parent.end(), 0);\n    auto find_set = [&](auto self, int v) -> int {\n        if (v == parent[v]) return v;\n        return parent[v] = self(self, parent[v]);\n    };\n    auto unite_sets = [&](int a, int b) -> bool {\n        a = find_set(find_set, a);\n        b = find_set(find_set, b);\n        if (a != b) {\n            parent[b] = a;\n            return true;\n        }\n        return false;\n    };\n\n    std::vector<int> B(M_edges_global, 0); // B[j] = 1 if edge j is ON, 0 otherwise\n    int edges_count = 0;\n    if (N_stations_global > 1) { // MST only needed if more than 1 station\n        for (const auto& edge : sorted_edges) {\n            if (unite_sets(edge.u, edge.v)) {\n                B[edge.id] = 1;\n                edges_count++;\n                if (edges_count == N_stations_global - 1) break;\n            }\n        }\n    } \n\n    // 3. Edge Pruning (Iterative Improvement)\n    // This pruning strategy checks if coverage is *feasible* after edge removal.\n    // It does not enforce full connectivity between all N stations.\n    for (const auto& edge_to_consider : sorted_edges) {\n        int edge_id = edge_to_consider.id;\n        if (B[edge_id] == 0) continue; // Edge is already OFF\n\n        // Temporarily remove the edge\n        B[edge_id] = 0;\n\n        // Determine the set of stations reachable from station 0 with the current B\n        std::vector<int> temp_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Check if coverage is feasible with the new V_prime.\n        // Coverage is feasible if every resident can be reached by at least one station\n        // in temp_V_prime_indices within the maximum radius of 5000.\n        bool coverage_feasible_after_prune = true;\n        if (K_residents_global > 0) {\n            if (temp_V_prime_indices.empty()) {\n                coverage_feasible_after_prune = false; // Cannot cover if no stations are reachable\n            } else {\n                for (int k = 0; k < K_residents_global; ++k) {\n                    bool resident_k_can_be_covered = false;\n                    for (int station_idx : temp_V_prime_indices) {\n                        if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { // Max possible coverage radius\n                            resident_k_can_be_covered = true;\n                            break;\n                        }\n                    }\n                    if (!resident_k_can_be_covered) {\n                        coverage_feasible_after_prune = false;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // If coverage is not feasible, restore the edge.\n        if (!coverage_feasible_after_prune) {\n            B[edge_id] = 1; // Restore the edge\n        }\n        // If coverage is feasible, we tentatively keep the edge removed.\n    }\n\n    // 4. Determine the final V_prime set after pruning and assign P values\n    std::vector<int> final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n\n    // Ensure V_prime is not empty if K > 0 by adding the cheapest edge if necessary.\n    if (K_residents_global > 0 && final_V_prime_indices.empty() && N_stations_global > 0) {\n        for (const auto& edge_to_add : sorted_edges) {\n            if (B[edge_to_add.id] == 0) { // If edge is OFF\n                B[edge_to_add.id] = 1; // Turn it ON\n                final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n                break; // Added one edge, sufficient for now.\n            }\n        }\n    }\n    \n    // Assign P values using the optimized PQ solver\n    std::vector<int> P = solve_P_greedy_marginal_cost_pq(final_V_prime_indices, edges_global);\n\n    // 5. Local Search / Iterative Refinement\n    // Reduced iterations for performance.\n    const int LOCAL_SEARCH_ITER = 300; \n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    for(int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        bool improved = false;\n\n        // --- Edge Removal ---\n        // Iterate through edges by increasing weight.\n        std::vector<Edge> edges_to_try_removing = sorted_edges; \n\n        for (const auto& edge_to_consider : edges_to_try_removing) {\n            int edge_id = edge_to_consider.id;\n            if (B[edge_id] == 0) continue; // Already OFF\n\n            // Temporarily remove edge\n            B[edge_id] = 0;\n\n            // Determine new V_prime\n            std::vector<int> next_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n            \n            // Check if coverage is still feasible with the new V_prime.\n            bool coverage_feasible = true;\n            if (K_residents_global > 0) {\n                if (next_V_prime_indices.empty()) {\n                    coverage_feasible = false;\n                } else {\n                    for (int k = 0; k < K_residents_global; ++k) {\n                        bool resident_k_can_be_covered = false;\n                        for (int station_idx : next_V_prime_indices) {\n                            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) {\n                                resident_k_can_be_covered = true;\n                                break;\n                            }\n                        }\n                        if (!resident_k_can_be_covered) {\n                            coverage_feasible = false;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (!coverage_feasible) {\n                B[edge_id] = 1; // Revert edge removal\n                continue;\n            }\n\n            // Re-solve P values for the new V_prime\n            std::vector<int> next_P = solve_P_greedy_marginal_cost_pq(next_V_prime_indices, edges_global);\n            \n            // Verify actual coverage with next_P and next_V_prime_indices (should be guaranteed if feasibility check is perfect and solver is correct)\n            bool actual_coverage_ok = true;\n            if (K_residents_global > 0) {\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    bool k_covered = false;\n                    for(int st_idx_check : next_V_prime_indices) {\n                        if (next_P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= next_P[st_idx_check]) {\n                            k_covered = true;\n                            break;\n                        }\n                    }\n                    if(k_covered) covered_count++;\n                }\n                if (covered_count < K_residents_global) actual_coverage_ok = false;\n            }\n\n            if (actual_coverage_ok) {\n                // Calculate costs: Compare cost *before* removal vs *after* removal.\n                // Cost BEFORE removal: Current P, B with edge_id restored to 1.\n                std::vector<int> B_before_removal = B; // B has edge_id=0\n                B_before_removal[edge_id] = 1; // Temporarily restore edge for cost calc\n                long long cost_before_removal = calculate_total_cost(P, B_before_removal);\n                \n                // Cost AFTER removal: next_P, B with edge_id=0\n                long long cost_after_removal = calculate_total_cost(next_P, B); \n                \n                if (cost_after_removal < cost_before_removal) {\n                    P = next_P; // Update P values\n                    // B is already updated (edge_id is 0)\n                    improved = true;\n                } else {\n                    // Revert the change\n                    B[edge_id] = 1;\n                }\n            } else {\n                // Revert the change if actual coverage is lost\n                B[edge_id] = 1;\n            }\n        }\n        \n        // --- P Value Adjustment ---\n        // Re-calculate current V_prime based on current B state\n        std::vector<int> current_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Only attempt P adjustment if V_prime is not empty OR if there are no residents to cover.\n        if (!current_V_prime_indices.empty() || K_residents_global == 0) {\n            \n            // Try decreasing P of a random station in V_prime that has P > 0\n            int station_to_adjust = -1;\n            if (!current_V_prime_indices.empty()) {\n                std::vector<int> stations_with_p_greater_than_zero;\n                for (int s_idx : current_V_prime_indices) {\n                    if (P[s_idx] > 0) {\n                        stations_with_p_greater_than_zero.push_back(s_idx);\n                    }\n                }\n\n                if (!stations_with_p_greater_than_zero.empty()) {\n                    // Pick one randomly from those with P > 0\n                    station_to_adjust = stations_with_p_greater_than_zero[std::uniform_int_distribution<int>(0, stations_with_p_greater_than_zero.size() - 1)(rng)];\n                }\n            }\n\n            if (station_to_adjust != -1) {\n                int original_P = P[station_to_adjust];\n                P[station_to_adjust]--; // Try decreasing P by 1\n                \n                // Check coverage with the decreased P\n                bool coverage_ok = true;\n                if (K_residents_global > 0) {\n                    int covered_count = 0;\n                    for(int k=0; k<K_residents_global; ++k) {\n                        bool k_covered = false;\n                        for(int st_idx_check : current_V_prime_indices) { // Use the current V_prime\n                            if (P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= P[st_idx_check]) {\n                                k_covered = true;\n                                break;\n                            }\n                        }\n                        if(k_covered) covered_count++;\n                    }\n                    if (covered_count < K_residents_global) coverage_ok = false;\n                }\n                \n                if (coverage_ok) {\n                    // Cost decreased (since P decreased)\n                    improved = true;\n                } else {\n                    // Revert if coverage lost\n                    P[station_to_adjust] = original_P;\n                }\n            }\n        }\n\n        if (!improved) {\n             // If no improvement in an entire iteration, break.\n             break; \n        }\n    }\n\n    // Output final P values and B values\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cout << P[i] << (i == N_stations_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n    for (int j = 0; j < M_edges_global; ++j) {\n        std::cout << B[j] << (j == M_edges_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <map>\n#include <tuple> // For tie-breaking if needed, though struct comparison is sufficient\n\n// Maximum number of tiers\nconst int N = 30;\n// Total number of balls\nconst int M = N * (N + 1) / 2; // M = 465\n\n// Structure to represent coordinates (tier x, position y)\nstruct Coord {\n    int x, y;\n\n    // Operator overloading for map keys and comparisons.\n    // Required for std::map and for determining lexicographical order.\n    bool operator<(const Coord& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Coord& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Useful for tie-breaking in lexicographical order.\n    bool operator>(const Coord& other) const {\n        if (x != other.x) return x > other.x;\n        return y > other.y;\n    }\n};\n\n// Convert pyramid coordinates (x, y) to a linear index.\n// This index serves as the \"target position\" for a ball with a value equal to this index.\n// For example, ball with value 0 should be at (0,0), value 1 at (1,0), value 2 at (1,1), etc.\ninline int get_idx_from_coord(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Define relative coordinates for the 6 possible adjacent moves.\n// These correspond to the adjacency rules given in the problem statement.\n// Order:\n// (dx[0], dy[0]) = (1, 0) : (x+1, y)   (Down-Left)\n// (dx[1], dy[1]) = (1, 1) : (x+1, y+1) (Down-Right)\n// (dx[2], dy[2]) = (0, 1) : (x, y+1)   (Right)\n// (dx[3], dy[3]) = (0,-1) : (x, y-1)   (Left)\n// (dx[4], dy[4]) = (-1,0) : (x-1, y)   (Up-Left)\n// (dx[5], dy[5]) = (-1,1) : (x-1, y+1) (Up-Right)\nint dx[] = {1, 1, 0, 0, -1, -1}; // change in x\nint dy[] = {0, 1, 1, -1, 0, 1}; // change in y\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Map to store the current value of the ball at a given coordinate.\n    // Key: Coord, Value: ball_value\n    std::map<Coord, int> current_values_map;\n    \n    // Vector to store all valid coordinates in the pyramid.\n    // Populated in order: (0,0), (1,0), (1,1), (2,0), (2,1), (2,2), ...\n    // This order ensures deterministic iteration through all cells and facilitates tie-breaking.\n    std::vector<Coord> all_coords;\n    all_coords.reserve(M);\n\n    // Read input and populate the initial state of the pyramid.\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            Coord c = {x, y};\n            all_coords.push_back(c);\n            int value;\n            std::cin >> value;\n            current_values_map[c] = value;\n        }\n    }\n\n    // Store the sequence of performed swaps.\n    // Each swap is a pair of adjacent coordinates.\n    std::vector<std::pair<Coord, Coord>> swaps;\n    const int MAX_SWAPS = 10000; // Maximum allowed operations.\n\n    // Heuristic strategy:\n    // This problem is NP-hard, so we employ a greedy heuristic.\n    // The target configuration is one where each ball with value `v` is located at\n    // coordinate `c` such that `get_idx_from_coord(c.x, c.y) == v`.\n    // This configuration guarantees the condition V(x,y) < V(x+1,y) and V(x,y) < V(x+1,y+1).\n    //\n    // In each step (up to MAX_SWAPS operations), we find the single best adjacent swap.\n    // The \"best\" swap is defined as one that maximizes the reduction in the total absolute error.\n    // The total absolute error is the sum of |target_index - current_value| for all balls.\n    // A swap is only considered if it moves a ball with a larger value to a position\n    // that should ideally hold a larger index (i.e., resolves an inversion where idx1 < idx2 but val1 > val2).\n    // If multiple swaps yield the same maximum benefit, we choose the one that is\n    // lexicographically smallest in terms of the coordinate pair (c1, c2), where c1 is\n    // the \"left/up\" ball and c2 is the \"right/down\" ball (idx(c1) < idx(c2)).\n\n    for (int k = 0; k < MAX_SWAPS; ++k) {\n        // Variables to track the best swap found in this iteration.\n        // Initialize max_benefit to a very small number. We are interested in non-negative benefits.\n        long long max_benefit = -2e18; \n        Coord best_c1 = {-1, -1}, best_c2 = {-1, -1}; // Initialize to invalid coordinates.\n\n        // Iterate through all balls (c1) and their potential neighbors (c2).\n        // `all_coords` is iterated in lexicographical order.\n        for (const auto& c1 : all_coords) { \n            int val1 = current_values_map.at(c1);\n            int idx1 = get_idx_from_coord(c1.x, c1.y);\n\n            // Check each of the 6 possible adjacent neighbors of c1.\n            for (int i = 0; i < 6; ++i) {\n                Coord c2 = {c1.x + dx[i], c1.y + dy[i]};\n\n                // Validate if the neighbor coordinate c2 is within the pyramid boundaries.\n                if (c2.x < 0 || c2.x >= N || c2.y < 0 || c2.y > c2.x) {\n                    continue; // c2 is outside the pyramid.\n                }\n\n                int val2 = current_values_map.at(c2);\n                int idx2 = get_idx_from_coord(c2.x, c2.y);\n\n                // We are only interested in swaps that fix an \"inversion\" according to the target index.\n                // An inversion exists if c1 should have a smaller index than c2 (idx1 < idx2),\n                // but c1 currently holds a larger value than c2 (val1 > val2).\n                // Swapping these would move a smaller value towards a smaller index, and a larger value\n                // towards a larger index, thus reducing the total absolute error.\n                if (idx1 < idx2 && val1 > val2) {\n                    // Calculate the benefit of swapping c1 and c2.\n                    // Benefit is defined as the reduction in the sum of absolute errors:\n                    // Total Error = Sum over all balls v of | target_idx(pos[v]) - v |\n                    // current_error_sum = |idx1 - val1| + |idx2 - val2|\n                    // new_error_sum     = |idx1 - val2| + |idx2 - val1|  (after swapping val1 and val2)\n                    // benefit           = current_error_sum - new_error_sum\n                    long long current_error_sum = std::abs((long long)idx1 - val1) + std::abs((long long)idx2 - val2);\n                    long long new_error_sum = std::abs((long long)idx1 - val2) + std::abs((long long)idx2 - val1);\n                    long long benefit = current_error_sum - new_error_sum;\n\n                    // Update `best_c1`, `best_c2`, and `max_benefit` if this swap is better.\n                    // Selection criteria:\n                    // 1. Maximize the benefit. We require `benefit >= 0`. A benefit of 0 means\n                    //    the total error sum doesn't decrease, but the swap might still resolve\n                    //    an inversion and potentially reduce direct violations (E), or help reach MAX_SWAPS.\n                    // 2. If benefits are equal, choose the lexicographically smaller coordinate pair (c1, c2).\n                    //    The iteration order ensures that the first encountered pair for a given\n                    //    benefit is the lexicographically smallest. Thus, we update only if the current\n                    //    pair (c1, c2) is strictly smaller than the current `(best_c1, best_c2)`.\n                    \n                    if (benefit > max_benefit) {\n                        max_benefit = benefit;\n                        best_c1 = c1;\n                        best_c2 = c2;\n                    } else if (benefit == max_benefit) {\n                        // Tie-breaking: select the lexicographically smaller coordinate pair (c1, c2).\n                        if (c1 < best_c1 || (c1 == best_c1 && c2 < best_c2)) {\n                             best_c1 = c1;\n                             best_c2 = c2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // If a beneficial swap was found (best_c1 is valid and max_benefit >= 0),\n        // and we haven't reached the maximum allowed number of swaps:\n        if (best_c1.x != -1 && max_benefit >= 0) {\n            // Apply the selected best swap.\n            std::swap(current_values_map.at(best_c1), current_values_map.at(best_c2));\n            // Record the swap operation.\n            swaps.push_back({best_c1, best_c2});\n        } else {\n            // No swap found with non-negative benefit, or we have already performed MAX_SWAPS (implicit in k loop condition).\n            // In this case, we cannot improve further with this greedy strategy, so we stop.\n            break;\n        }\n    }\n\n    // Output the total number of operations performed.\n    std::cout << swaps.size() << std::endl;\n    // Output each swap operation in the specified format.\n    for (const auto& sw : swaps) {\n        std::cout << sw.first.x << \" \" << sw.first.y << \" \" << sw.second.x << \" \" << sw.second.y << std::endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions and properties\nconst int MAX_D = 9; // D is fixed at 9 for all test cases\nint D;\nbool is_obstacle[MAX_D][MAX_D];\nint dist[MAX_D][MAX_D];\npair<int, int> entrance;\n\n// Directions for BFS: North, East, South, West\n// These correspond to changes in (row, column) coordinates.\nint dr[] = {-1, 0, 1, 0};\nint dc[] = {0, 1, 0, -1};\n\n// Structure to hold cell information: row, column, and its shortest distance from the entrance.\n// This is used for sorting storage locations.\nstruct CellInfo {\n    int r, c, d;\n\n    // Custom comparison operator for sorting:\n    // 1. Primarily by distance (ascending).\n    // 2. Secondarily by row index (ascending).\n    // 3. Tertiarily by column index (ascending).\n    bool operator<(const CellInfo& other) const {\n        if (d != other.d) {\n            return d < other.d;\n        }\n        if (r != other.r) {\n            return r < other.r;\n        }\n        return c < other.c;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming performance.\n    // `ios_base::sync_with_stdio(false)` unties C++ streams from C stdio.\n    // `cin.tie(NULL)` unties cin from cout, meaning cin operations do not force cout to flush.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N; // Number of obstacles\n    cin >> D >> N;\n\n    // Set entrance coordinates (0-indexed). D is always 9, so (D-1)/2 is 4.\n    entrance = {0, (D - 1) / 2};\n\n    // Initialize grid properties: mark all cells as not an obstacle and unreachable initially.\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            is_obstacle[i][j] = false;\n            dist[i][j] = -1; // -1 indicates unreachable or unvisited\n        }\n    }\n\n    // Read and mark obstacle locations.\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    // --- BFS to calculate shortest distances ---\n    // We perform a Breadth-First Search starting from the entrance to find the shortest\n    // path distance to all reachable non-obstacle cells.\n    queue<pair<int, int>> q;\n\n    // The entrance is guaranteed not to be an obstacle.\n    dist[entrance.first][entrance.second] = 0;\n    q.push(entrance);\n\n    // This vector will store information about all reachable cells (including the entrance)\n    // along with their distances.\n    vector<CellInfo> all_reachable_cells;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n\n        // Add the current cell to our list of reachable cells.\n        all_reachable_cells.push_back({r, c, dist[r][c]});\n\n        // Explore neighbors in all four directions.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid bounds, is not an obstacle, and has not been visited yet.\n            if (nr >= 0 && nr < D && nc >= 0 && nc < D && !is_obstacle[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1; // Distance is one more than the current cell's distance.\n                q.push({nr, nc}); // Add the neighbor to the queue for exploration.\n            }\n        }\n    }\n\n    // --- Sorting Storage Locations ---\n    // The problem states that containers are stored in squares other than the entrance and obstacles.\n    // The total number of containers is M = D*D - 1 - N. These will occupy M storage locations.\n    // We need to sort these storage locations based on their proximity to the entrance to establish an order.\n    vector<CellInfo> sorted_storage_locs;\n    for (const auto& cell : all_reachable_cells) {\n        // The entrance cell itself is not a storage location, so we skip it.\n        if (cell.r == entrance.first && cell.c == entrance.second) {\n            continue;\n        }\n        sorted_storage_locs.push_back(cell);\n    }\n\n    // Sort the storage locations using the custom comparison operator defined in CellInfo.\n    // This ensures they are ordered by distance, then row, then column.\n    sort(sorted_storage_locs.begin(), sorted_storage_locs.end());\n\n    // Calculate the total number of containers to be stored.\n    int num_containers = D * D - 1 - N;\n\n    // --- Container Placement Phase ---\n    // This phase handles the arrival of containers one by one.\n    // For each arriving container, we decide where to store it.\n    // Our strategy: The d-th container to arrive (with ID t_d) is placed in the d-th location\n    // from our sorted list of storage locations (`sorted_storage_locs`). This greedy approach aims\n    // to keep containers with smaller target retrieval IDs in \"closer\" or more accessible locations.\n    \n    // We need to record the arrival order for each container ID.\n    // `container_arrival_idx[container_id]` will store the index `d` (0 to num_containers-1)\n    // representing the order in which `container_id` arrived and was placed.\n    vector<int> container_arrival_idx(num_containers); \n\n    for (int d = 0; d < num_containers; ++d) {\n        int container_id; // The ID of the container arriving at step d.\n        cin >> container_id;\n\n        // The d-th arriving container is placed at the d-th location in our sorted list.\n        CellInfo current_storage_loc = sorted_storage_locs[d];\n        pair<int, int> pos = {current_storage_loc.r, current_storage_loc.c};\n        \n        // Output the chosen storage location (row and column) for this container.\n        cout << pos.first << \" \" << pos.second << endl;\n        // `endl` typically flushes the output buffer in C++ streams, which is required.\n        \n        // Record that `container_id` arrived at step `d` and was assigned to `sorted_storage_locs[d]`.\n        // This means container_id is stored at the d-th closest available slot.\n        container_arrival_idx[container_id] = d; \n    }\n\n    // --- Container Retrieval Phase ---\n    // After all containers are stored, we need to determine the order in which they are transported out.\n    // The goal is to minimize the number of inversions in the retrieval sequence `b_0, b_1, ..., b_{M-1}`.\n    // This is achieved by aiming for the sorted sequence `0, 1, ..., M-1`.\n    // Our placement strategy (d-th arrival at d-th closest slot) allows for this.\n    // Container `k` is placed at `sorted_storage_locs[container_arrival_idx[k]]`.\n    // By retrieving containers in increasing order of their IDs (0, 1, 2, ...), we can achieve minimal inversions.\n    // Container `k` can be retrieved at step `k` because its location is guaranteed to be reachable.\n    // All containers `0, ..., k-1` are retrieved before container `k`, making their locations empty.\n    // The entire storage area is connected to the entrance, ensuring reachability.\n    \n    for (int k = 0; k < num_containers; ++k) {\n        // We want to retrieve container with ID `k` at step `k` of the retrieval sequence.\n        // Find out which storage slot `d` this container `k` was assigned to based on its arrival order.\n        int d = container_arrival_idx[k]; \n        \n        // The location of container `k` is the d-th sorted storage location.\n        CellInfo retrieved_cell = sorted_storage_locs[d];\n        pair<int, int> pos = {retrieved_cell.r, retrieved_cell.c};\n        \n        // Output the coordinates of the container to be transported out at this step.\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> initial_grid;\nvector<vector<int>> output_grid; // -1: unassigned, 0..m: assigned color\nvector<vector<bool>> adj;\nvector<pair<int, int>> dx = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n// Checks if assigning color 'color_to_assign' to a cell is valid\n// given the colors of its already assigned neighbors.\n// 'neighbor_colors' is a set of colors of already assigned neighbors of the cell.\nbool is_valid(int color_to_assign, const set<int>& neighbor_colors) {\n    for (int neighbor_color : neighbor_colors) {\n        if (color_to_assign != neighbor_color) {\n            if (!adj[min(color_to_assign, neighbor_color)][max(color_to_assign, neighbor_color)]) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> n >> m;\n\n    initial_grid.resize(n, vector<int>(n));\n    output_grid.resize(n, vector<int>(n, -1)); // Initialize all cells as unassigned (-1)\n\n    // Store first occurrence of each color (1 to m) as a seed\n    vector<pair<int, int>> seeds(m + 1, {-1, -1});\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> initial_grid[i][j];\n            if (initial_grid[i][j] >= 1 && initial_grid[i][j] <= m) {\n                if (seeds[initial_grid[i][j]].first == -1) {\n                    seeds[initial_grid[i][j]] = {i, j};\n                }\n            }\n        }\n    }\n\n    // Compute adjacency matrix for colors 0 to m\n    adj.resize(m + 1, vector<bool>(m + 1, false));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = initial_grid[i][j];\n            if (c1 != 0) { // Only check adjacencies for non-zero colors in the input\n                for (auto& move : dx) {\n                    int ni = i + move.first;\n                    int nj = j + move.second;\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int c2 = initial_grid[ni][nj];\n                        if (c1 != c2) {\n                            adj[min(c1, c2)][max(c1, c2)] = true;\n                        }\n                    } else { // Neighbor is outside the grid, which means it's adjacent to color 0\n                        adj[min(c1, 0)][max(c1, 0)] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // BFS queue stores cells to process. We prioritize processing non-zero colors.\n    queue<pair<int, int>> q;\n\n    // Seed the grid with initial colors and add them to the queue\n    // Priority is given to non-zero colors.\n    for (int k = 1; k <= m; ++k) {\n        if (seeds[k].first != -1) {\n            int r = seeds[k].first;\n            int c = seeds[k].second;\n            if (output_grid[r][c] == -1) { // If cell is unassigned\n                output_grid[r][c] = k;\n                q.push({r, c});\n            }\n        }\n    }\n\n    // Initialize color 0 for cells that are initially 0 and on the border,\n    // or if the input color was 0. These ensure color 0 connectivity.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (initial_grid[i][j] == 0) {\n                if (output_grid[i][j] == -1) { // If unassigned and input was 0\n                    output_grid[i][j] = 0;\n                    // We don't push color 0 to the queue because color 0 expansion is implicit\n                    // and doesn't drive the assignment of non-zero colors.\n                    // However, if 0 is the *only* color assigned initially (e.g. all 0s input),\n                    // we might need to seed it if it's a border cell.\n                }\n            }\n        }\n    }\n    // Ensure border cells that are unassigned default to 0.\n    for (int i = 0; i < n; ++i) {\n        if (output_grid[i][0] == -1) { output_grid[i][0] = 0; }\n        if (output_grid[i][n-1] == -1) { output_grid[i][n-1] = 0; }\n    }\n    for (int j = 0; j < n; ++j) {\n        if (output_grid[0][j] == -1) { output_grid[0][j] = 0; }\n        if (output_grid[n-1][j] == -1) { output_grid[n-1][j] = 0; }\n    }\n\n\n    // BFS to fill the grid\n    // The queue `q` primarily contains seeds of non-zero colors.\n    // When a non-zero cell expands, it decides the color of its unassigned neighbors.\n    while (!q.empty()) {\n        pair<int, int> current_cell = q.front();\n        q.pop();\n        int r = current_cell.first;\n        int c = current_cell.second;\n        int current_color = output_grid[r][c];\n\n        for (auto& move : dx) {\n            int nr = r + move.first;\n            int nc = c + move.second;\n\n            if (nr >= 0 && nr < n && nc >= 0 && nc < n) {\n                if (output_grid[nr][nc] == -1) { // If neighbor is unassigned\n                    // Collect colors of already assigned neighbors of (nr, nc)\n                    set<int> neighbor_colors;\n                    for (auto& next_move : dx) {\n                        int nnr = nr + next_move.first;\n                        int nnc = nc + next_move.second;\n                        if (nnr >= 0 && nnr < n && nnc >= 0 && nnc < n) {\n                            if (output_grid[nnr][nnc] != -1) { // Collect colors of assigned neighbors\n                                neighbor_colors.insert(output_grid[nnr][nnc]);\n                            }\n                        }\n                    }\n\n                    int color_to_assign = -1;\n\n                    // Strategy:\n                    // 1. Try to assign color 0 if it's valid.\n                    // 2. If 0 is not valid, try to assign a non-zero color K.\n                    //    - Prioritize K if it's required by `current_color` (i.e., `adj[current_color][K]` is true).\n                    //    - If multiple such K exist, pick the smallest.\n                    //    - If no prioritized K is found, pick the smallest valid K.\n\n                    bool can_be_zero = is_valid(0, neighbor_colors);\n\n                    if (can_be_zero) {\n                        // Color 0 is valid. We prefer it to maximize score.\n                        // Assigning 0 means it remains 0 (since output_grid[nr][nc] was -1, and now becomes 0).\n                        // We do not push 0 to the queue as its expansion is implicit.\n                        color_to_assign = 0;\n                    } else {\n                        // Color 0 is NOT valid. We MUST assign a non-zero color.\n                        int best_k = -1;\n\n                        // First, try to find a K required by current_color\n                        if (current_color != 0) { // current_color is non-zero, check its adjacencies\n                            for (int k = 1; k <= m; ++k) {\n                                if (adj[min(current_color, k)][max(current_color, k)]) { // k is required by current_color\n                                    if (is_valid(k, neighbor_colors)) { // k is valid for this cell\n                                        best_k = k; // Found a candidate K\n                                        break; // Prioritize first such K\n                                    }\n                                }\n                            }\n                        }\n\n                        // If no prioritized K was found, find any valid non-zero color K\n                        if (best_k == -1) {\n                            for (int k = 1; k <= m; ++k) {\n                                if (is_valid(k, neighbor_colors)) {\n                                    best_k = k;\n                                    break; // Found first valid non-zero color K\n                                }\n                            }\n                        }\n                        color_to_assign = best_k;\n                    }\n\n                    // Assign the determined color and enqueue if it's non-zero.\n                    if (color_to_assign != -1) {\n                        output_grid[nr][nc] = color_to_assign;\n                        if (color_to_assign != 0) { // Only push non-zero colors to the queue\n                            q.push({nr, nc});\n                        }\n                    } else {\n                        // This case implies that no color (0 or 1..m) could be validly assigned.\n                        // This could happen if the problem constraints are impossible for this heuristic,\n                        // or if the seeding/expansion order leads to a dead end.\n                        // For a contest, leaving it as -1 and filling later might be an option,\n                        // but the problem implies a solution exists. We assume best_k is found if !can_be_zero.\n                        // As a fallback, we might assign 0 if it was valid but not preferred, or if problem implies any solution is fine.\n                        // However, the logic implies if !can_be_zero, then best_k MUST be found.\n                        // If it's not found, the strategy fails.\n                        // Given the scoring and heuristic nature, this state is unlikely if adjacencies are feasible.\n                    }\n                }\n            }\n        }\n    }\n\n    // Final pass: Fill any remaining unassigned cells (-1) with color 0.\n    // This ensures connectivity of color 0 and maximizes the score.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (output_grid[i][j] == -1) {\n                output_grid[i][j] = 0;\n            }\n        }\n    }\n\n    // Print the output grid\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << output_grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Use a large value for infinity in distance calculations.\n// Given N <= 100, a path length is at most N-1. Max difference per step is 1.\n// So N+5 should be sufficiently large for INF.\nconst long long INF = 1e18; \n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, d, q;\n    cin >> n >> d >> q;\n\n    // Stores the result of pairwise comparisons:\n    // comparison[i][j] = 1 if w_i < w_j\n    // comparison[i][j] = -1 if w_i > w_j\n    // comparison[i][j] = 0 if w_i = w_j\n    // comparison[i][j] = 2 if unknown\n    vector<vector<int>> comparison(n, vector<int>(n, 2));\n\n    int queries_budget = q;\n    int current_queries = 0;\n\n    // Phase 1: Prioritize comparisons between items with small index differences.\n    // This helps establish local relationships and might reveal structured weight distributions.\n    // We check differences from 1 up to a certain limit. The limit is capped by N/2\n    // to avoid redundant checks (e.g., diff=1 queries (0,1), (1,2), ..., (N-1,0). diff=N-1 queries (0,N-1), etc. which are inverse of diff=1).\n    // Also, cap the number of differences to check to not exceed Q.\n    int max_diff_to_check = min(10, n / 2); \n\n    for (int diff = 1; diff <= max_diff_to_check; ++diff) {\n        if (current_queries >= queries_budget) break;\n        for (int i = 0; i < n; ++i) {\n            if (current_queries >= queries_budget) break;\n            int j = (i + diff) % n; // Circular index difference\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1; // Symmetric relation\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1; // Symmetric relation\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0; // Symmetric relation\n                }\n            }\n        }\n    }\n    \n    // Phase 2: If budget remains, query arbitrary pairs (i, j) with i < j.\n    // This strategy aims to gather as many direct pairwise comparisons as possible.\n    for (int i = 0; i < n; ++i) {\n        if (current_queries >= queries_budget) break;\n        for (int j = i + 1; j < n; ++j) { // Iterate through unique pairs (i, j) with i < j\n            if (current_queries >= queries_budget) break;\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1;\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1;\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0;\n                }\n            }\n        }\n    }\n\n    // Initialize distance matrix for Floyd-Warshall algorithm.\n    // dist[i][j] will store the minimum possible value of (w_i - w_j).\n    // Weights w_i are positive integers (>= 1).\n    // If w_i < w_j, then w_i - w_j <= -1. The minimum possible difference is -1.\n    // If w_i > w_j, then w_i - w_j >= 1. The minimum possible difference is 1.\n    // If w_i = w_j, then w_i - w_j = 0.\n    vector<vector<long long>> dist(n, vector<long long>(n));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (i == j) {\n                dist[i][j] = 0; // Distance to self is 0\n            } else if (comparison[i][j] == 1) { // w_i < w_j => w_i - w_j <= -1\n                dist[i][j] = -1;\n            } else if (comparison[i][j] == -1) { // w_i > w_j => w_i - w_j >= 1\n                dist[i][j] = 1;\n            } else if (comparison[i][j] == 0) { // w_i = w_j\n                dist[i][j] = 0;\n            } else { // Unknown relationship\n                dist[i][j] = INF; // Initialize with infinity\n            }\n        }\n    }\n\n    // Run Floyd-Warshall to compute all-pairs shortest paths (minimum differences).\n    // This step integrates all pairwise comparisons to infer transitive relationships.\n    for (int k = 0; k < n; ++k) { // Intermediate node\n        for (int i = 0; i < n; ++i) { // Source node\n            for (int j = 0; j < n; ++j) { // Destination node\n                // If paths through k are possible, update distance\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    // Estimate weights based on the computed differences.\n    // We use dist[0][i] which represents the minimum inferred difference w_0 - w_i.\n    // So, w_i = w_0 + dist[0][i].\n    // To get an estimate of w_i's magnitude, we can use -dist[0][i] as a proxy.\n    // If dist[0][i] is -5, it implies w_i is roughly 5 units heavier than w_0. So -dist[0][i] = 5.\n    // If dist[0][i] is 3, it implies w_i is roughly 3 units lighter than w_0. So -dist[0][i] = -3.\n    // This gives a relative ordering.\n    vector<pair<long long, int>> estimated_weights(n);\n    long long min_estimated_val = 0; // To find the minimum estimated value for shifting\n    \n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i] = {-dist[0][i], i}; // Use -dist[0][i] as estimated weight\n        min_estimated_val = min(min_estimated_val, estimated_weights[i].first);\n    }\n\n    // Shift the estimated weights so that the minimum weight is 1.\n    // This ensures all estimated weights are positive integers, respecting the problem's constraint.\n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i].first = estimated_weights[i].first - min_estimated_val + 1;\n    }\n\n    // Sort items by their estimated weights in descending order.\n    // This is for the Largest Processing Time (LPT) heuristic, commonly used for multiway number partitioning.\n    sort(estimated_weights.rbegin(), estimated_weights.rend());\n\n    // Partitioning phase using the LPT heuristic.\n    // We want to assign items to 'd' bins such that the sum of weights in each bin is as equal as possible.\n    vector<long long> bin_sums(d, 0); // Stores the current total estimated weight for each bin\n    vector<int> assignment(n);       // Stores the final bin assignment for each item\n\n    for (const auto& item_pair : estimated_weights) {\n        long long weight = item_pair.first; // Estimated weight of the current item\n        int item_idx = item_pair.second;    // Original index of the item\n\n        // Find the bin with the minimum current sum of weights.\n        int best_bin = 0;\n        for (int b = 1; b < d; ++b) {\n            if (bin_sums[b] < bin_sums[best_bin]) {\n                best_bin = b;\n            }\n        }\n\n        // Assign the current item to the bin with the minimum sum.\n        assignment[item_idx] = best_bin;\n        bin_sums[best_bin] += weight; // Update the sum for this bin\n    }\n\n    // Output the final assignment of items to bins.\n    for (int i = 0; i < n; ++i) {\n        cout << assignment[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <deque> // Use deque for stacks for better performance and memory management\n\n// Structure to store box location: stack index and position within the stack.\nstruct BoxLocation {\n    int stack_idx;    // 0-indexed stack index\n    int pos_in_stack; // 0-indexed position from the bottom of the stack\n};\n\n// Global variables to store the state of the stacks and box locations.\nstd::vector<std::deque<int>> stacks;         // Stacks are implemented as deques of box IDs.\nstd::vector<BoxLocation> box_locations;      // Maps box ID (1 to n) to its location.\nint n_boxes, m_stacks;                       // Total number of boxes and stacks.\nint next_box_to_carry_id = 1;                // The ID of the next box to be carried out.\nstd::vector<std::pair<int, int>> operations; // Stores the sequence of operations: {box_id, destination_stack_id (1-based) or 0 for carry-out}.\n\n// Helper function to update the 'box_locations' array after a stack is modified.\n// It iterates through the given stack_content (a deque) and updates the location for each box.\nvoid update_box_locations_in_stack(int stack_idx, const std::deque<int>& stack_content) {\n    for (int i = 0; i < stack_content.size(); ++i) {\n        int box_id = stack_content[i];\n        box_locations[box_id] = {stack_idx, i}; // Update location: stack index and position.\n    }\n}\n\n// Function to perform Operation 1: moving a block of boxes.\n// 'v_initiator_id': The ID of the box that is at the bottom of the block being moved.\n//                   This box is chosen because it's the one directly above the target box\n//                   (or is the target box itself if it was the only one not carried out and we move it).\n// 'dest_stack_idx': The 0-indexed destination stack.\nvoid perform_move_operation(int v_initiator_id, int dest_stack_idx) {\n    int src_stack_idx = box_locations[v_initiator_id].stack_idx;\n    int initiator_pos_in_src_stack = box_locations[v_initiator_id].pos_in_stack;\n    \n    std::deque<int>& src_stack = stacks[src_stack_idx];\n\n    // The block to move starts from the initiator's position to the top of the source stack.\n    int start_move_pos = initiator_pos_in_src_stack;\n    \n    // Record the operation: (initiator_box_id, destination_stack_id + 1).\n    operations.push_back({v_initiator_id, dest_stack_idx + 1});\n\n    // Temporarily store the block of boxes to be moved.\n    // Using std::vector here for a contiguous block is efficient.\n    std::vector<int> block_to_move;\n    block_to_move.reserve(src_stack.size() - start_move_pos); // Reserve space to avoid reallocations.\n    for (int i = start_move_pos; i < src_stack.size(); ++i) {\n        block_to_move.push_back(src_stack[i]);\n    }\n    \n    // Store the current height of the destination stack. This is crucial for updating\n    // the positions of the moved boxes correctly.\n    int current_dest_height = stacks[dest_stack_idx].size();\n    \n    // Append the block of boxes to the destination stack.\n    // std::deque's push_back is efficient (amortized O(1)).\n    for (size_t i = 0; i < block_to_move.size(); ++i) {\n        int box_id = block_to_move[i];\n        stacks[dest_stack_idx].push_back(box_id);\n        // Update the location for the moved box. Its new position is based on the\n        // original height of the destination stack plus its index within the block.\n        box_locations[box_id] = {dest_stack_idx, current_dest_height + (int)i};\n    }\n\n    // Update the source stack: remove the moved block by resizing.\n    // std::deque's resize from the end is efficient.\n    src_stack.resize(start_move_pos);\n    \n    // After resizing the source stack, update the locations of the remaining boxes in it.\n    update_box_locations_in_stack(src_stack_idx, src_stack);\n}\n\n// Main function to solve the problem.\nvoid solve() {\n    // Optimize C++ standard streams for competitive programming.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> n_boxes >> m_stacks;\n\n    stacks.resize(m_stacks);\n    box_locations.resize(n_boxes + 1); // Resize for 1-based indexing of box IDs.\n\n    // Initialize stacks and record initial box locations.\n    for (int i = 0; i < m_stacks; ++i) {\n        int num_boxes_in_stack = n_boxes / m_stacks; // Constraint: N is divisible by M.\n        stacks[i].resize(num_boxes_in_stack); // Initialize deque with n/m elements.\n        for (int j = 0; j < num_boxes_in_stack; ++j) {\n            std::cin >> stacks[i][j];\n            box_locations[stacks[i][j]] = {i, j}; // Record location.\n        }\n    }\n\n    // Main loop: continue until all boxes are carried out.\n    while (next_box_to_carry_id <= n_boxes) {\n        int target_box_id = next_box_to_carry_id; // The box we are currently trying to carry out.\n        \n        // Get current location of the target box.\n        int src_stack_idx = box_locations[target_box_id].stack_idx;\n        int target_pos_in_stack = box_locations[target_box_id].pos_in_stack;\n        std::deque<int>& current_stack = stacks[src_stack_idx];\n\n        // Check if the target box is at the top of its stack.\n        if (target_pos_in_stack == current_stack.size() - 1) { \n            // Operation 2: Carry out the box (cost is 0).\n            operations.push_back({target_box_id, 0}); // 0 signifies carry-out.\n            current_stack.pop_back(); // Remove the box from the stack.\n            next_box_to_carry_id++; // Move to the next box in sequence.\n        } else { \n            // Target box is NOT at the top. We need to move boxes above it.\n            // The box directly above the target box will initiate the move.\n            // This box is at index 'target_pos_in_stack + 1'.\n            int box_above_target_id = current_stack[target_pos_in_stack + 1];\n\n            // Determine the best destination stack using the heuristic:\n            // 1. Prefer an empty stack with the smallest index.\n            // 2. If no empty stacks, prefer a non-empty stack with the minimum height.\n            //    If heights are tied, prefer the stack with the smallest index.\n            \n            int dest_stack_idx = -1;\n            int min_height = -1; \n            bool found_empty_stack = false;\n\n            for (int i = 0; i < m_stacks; ++i) {\n                if (i == src_stack_idx) continue; // Cannot move to the same stack.\n\n                if (stacks[i].empty()) {\n                    if (!found_empty_stack) { // Found the first empty stack (smallest index).\n                        dest_stack_idx = i;\n                        found_empty_stack = true;\n                    }\n                } else { // Stack `i` is not empty.\n                    if (!found_empty_stack) { // Only consider non-empty stacks if no empty ones were found.\n                        int current_height = stacks[i].size();\n                        if (min_height == -1 || current_height < min_height) {\n                            min_height = current_height;\n                            dest_stack_idx = i;\n                        } else if (current_height == min_height) {\n                            // Tie-breaking: prefer smaller index.\n                            if (i < dest_stack_idx) {\n                                dest_stack_idx = i;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Fallback for selecting destination stack if loop didn't assign one (should not happen if m_stacks > 1).\n            if (dest_stack_idx == -1) {\n                 for(int i = 0; i < m_stacks; ++i) {\n                     if (i != src_stack_idx) {\n                         dest_stack_idx = i;\n                         break;\n                     }\n                 }\n            }\n            \n            // Perform the move operation. The 'box_above_target_id' initiates the move,\n            // and it, along with boxes above it, are moved. The 'target_box_id' remains in place.\n            perform_move_operation(box_above_target_id, dest_stack_idx);\n            \n            // 'next_box_to_carry_id' does NOT increment because the target box has not been carried out yet.\n            // The loop will re-evaluate 'target_box_id' in the next iteration, and it will be\n            // one step closer to the top, or at the top if all boxes above it were removed.\n        }\n    }\n\n    // Output all recorded operations.\n    for (const auto& op : operations) {\n        std::cout << op.first << \" \" << op.second << \"\\n\";\n    }\n}\n\nint main() {\n    solve(); // Call the main solving function.\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\nint N;\nvector<string> h_walls, v_walls;\nvector<vector<int>> d;\n\n// Adjacency list for grid graph\n// Stores pairs of {neighbor_row, neighbor_col, move_char, wall_type}\n// wall_type: 0 for no wall, 1 for horizontal wall, 2 for vertical wall\n// This information is not strictly needed if we check walls dynamically,\n// but could be useful for pathfinding. For this problem, we check walls directly.\nvector<pair<int, int>> adj[40][40];\n\nint dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar moves[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (r, c) to (nr, nc) is valid (no wall)\nbool is_valid_move(int r, int c, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n        return false;\n    }\n    if (nr == r - 1) { // Moving Up\n        if (v_walls[r][c] == '1') return false;\n    } else if (nr == r + 1) { // Moving Down\n        if (h_walls[r][c] == '1') return false;\n    } else if (nc == c - 1) { // Moving Left\n        if (v_walls[r][c-1] == '1') return false;\n    } else if (nc == c + 1) { // Moving Right\n        if (v_walls[r][c] == '1') return false;\n    }\n    return true;\n}\n\n// DFS to generate an initial path that visits all nodes\nstring initial_path_str;\nbool visited_dfs[40][40];\nint initial_path_len = 0;\nmap<pair<int, int>, int> visit_counts_dfs;\n\nvoid dfs_generate(int r, int c) {\n    visited_dfs[r][c] = true;\n    visit_counts_dfs[{r, c}]++;\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited_dfs[nr][nc]) {\n            if (is_valid_move(r, c, nr, nc)) {\n                initial_path_str += moves[i];\n                initial_path_len++;\n                dfs_generate(nr, nc);\n                initial_path_str += moves[i ^ 1]; // Move back\n                initial_path_len++;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[i];\n\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Build adjacency list implicitly by checking walls in is_valid_move\n    // DFS to generate initial path\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_dfs[i][j] = false;\n        }\n    }\n    dfs_generate(0, 0);\n    \n    // Ensure (0,0) is visited twice if DFS starts/ends there\n    // The DFS logic above adds return moves, so (0,0) is visited at start and end\n    // If initial_path_len is 0 (e.g. 1x1 grid, though N>=20), handle it.\n    if (N > 0 && initial_path_len == 0) { // For N=1, this might happen. But N>=20.\n        // If grid is just one cell (0,0), path is empty, length 0.\n        // But problem says N>=20. So DFS should generate a path.\n    }\n\n\n    // Target visit counts proportional to sqrt(d_i,j)\n    // Minimize sum( d_i,j / N_i,j^2 )\n    // Equivalent to maximizing sum( d_i,j / N_i,j^2 )\n    // For total visits V, N_i,j should be proportional to sqrt(d_i,j)\n    // N_i,j = C * sqrt(d_i,j)\n    // Sum(N_i,j) = V => C = V / Sum(sqrt(d_i,j))\n    // N_i,j = V * sqrt(d_i,j) / Sum(sqrt(d_k,m))\n\n    // Max path length is 100000.\n    // Initial path length L_dfs.\n    // Each additional visit can be achieved by a detour X->Y->X, adding 2 moves.\n    // Max number of extra visits K_max = (100000 - L_dfs) / 2\n    // Total max visits V_max = N*N + K_max\n\n    long double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((long double)d[i][j]);\n        }\n    }\n\n    int max_total_visits = 100000; // Maximum allowed path length\n\n    vector<long long> target_N(N * N, 0);\n    long long current_total_visits = 0;\n\n    // Ensure each cell is visited at least once\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            target_N[i * N + j] = 1;\n            current_total_visits++;\n        }\n    }\n    \n    // Distribute remaining visits greedily based on sqrt(d_i,j)\n    // We have `max_total_visits - current_total_visits` visits to distribute.\n    // This number is an upper bound on the sum of ADDITIONAL visits beyond the first one for each cell.\n    // Let's use the objective function to guide distribution: maximize sum(d_i,j / N_i,j^2)\n    // This implies N_i,j should be proportional to sqrt(d_i,j).\n\n    // Strategy: calculate proportional counts for all cells, then scale and adjust.\n    vector<pair<long double, pair<int, int>>> proportional_visits;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            proportional_visits.push_back({sqrt((long double)d[i][j]), {i, j}});\n        }\n    }\n    sort(proportional_visits.rbegin(), proportional_visits.rend());\n\n    // Distribute visits until total path length constraint is met.\n    // We have `max_total_visits` moves. Each visit adds at least 1 move, often 2 (detour).\n    // Let's use the rule that each visit adds 2 moves (detour)\n    // Total visits V should satisfy L_dfs + 2 * (V - N*N) <= 100000\n    // 2 * (V - N*N) <= 100000 - L_dfs\n    // V - N*N <= (100000 - L_dfs) / 2\n    // V <= N*N + (100000 - L_dfs) / 2\n    int max_additional_visits = (100000 - initial_path_len) / 2;\n    if (max_additional_visits < 0) max_additional_visits = 0;\n\n    current_total_visits = N * N; // All cells visited once initially\n\n    // Greedily assign additional visits to cells with high sqrt(d_i,j)\n    vector<long long> N_final(N * N, 1); // Start with 1 visit for each cell\n    long long visits_added_count = 0;\n\n    // First, distribute visits to reach max_additional_visits for sqrt(d_i,j) based proportional counts\n    vector<pair<long double, pair<int,int>>> sqrt_d_sorted;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) sqrt_d_sorted.push_back({sqrt((long double)d[i][j]), {i,j}});\n    sort(sqrt_d_sorted.rbegin(), sqrt_d_sorted.rend());\n    \n    for(const auto& p : sqrt_d_sorted) {\n        if (visits_added_count >= max_additional_visits) break;\n        int r = p.second.first;\n        int c = p.second.second;\n        N_final[r*N+c]++;\n        visits_added_count++;\n    }\n\n    // If we still have budget for more visits (e.g. if max_additional_visits was very large, and sum of sqrt(d_i,j) was small)\n    // we can add more visits to cells with highest d_i,j, using the priority queue logic.\n    // However, the proportional distribution up to max_additional_visits is likely optimal.\n\n    // If current_total_visits (N*N) + visits_added_count > 100000 (this check is redundant if max_additional_visits is calculated correctly)\n    // we need to cap it. But max_additional_visits ensures total length <= 100000.\n\n    // Current visit counts based on initial DFS and N_final assignment\n    map<pair<int, int>, int> current_N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_N[{i, j}] = visit_counts_dfs.count({i, j}) ? visit_counts_dfs[{i, j}] : 0;\n        }\n    }\n\n    // Adjust initial DFS counts to match N_final targets\n    // The DFS path might visit cells more than once initially.\n    // We need to reach N_final counts.\n    vector<pair<long double, pair<int, int>>> pq_cells; // (priority, {r, c})\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (current_N[{i, j}] < N_final[i * N + j]) {\n                pq_cells.push_back({ (long double)d[i][j] / (long double)(current_N[{i, j}] * current_N[{i, j}]), {i, j} });\n            }\n        }\n    }\n    sort(pq_cells.rbegin(), pq_cells.rend());\n\n    vector<pair<int, int>> cells_to_visit_extra; // Cells to add extra visits to\n    vector<int> extra_visits_count(N*N, 0);\n\n    int current_extra_visits_total = 0;\n    for(const auto& p : pq_cells) {\n        int r = p.second.first;\n        int c = p.second.second;\n        int needed = N_final[r*N+c] - current_N[{r,c}];\n        for(int k=0; k<needed; ++k) {\n            if (current_extra_visits_total >= max_additional_visits) break;\n            cells_to_visit_extra.push_back({r, c});\n            extra_visits_count[r*N+c]++;\n            current_extra_visits_total++;\n        }\n        if (current_extra_visits_total >= max_additional_visits) break;\n    }\n    \n    // Construct final path by adding detours\n    string final_path = initial_path_str;\n    int current_path_len = initial_path_len;\n\n    // Store path as sequence of cells for easier detour insertion\n    vector<pair<int, int>> path_cells;\n    path_cells.push_back({0,0});\n    int cur_r = 0, cur_c = 0;\n    for(char move : initial_path_str) {\n        if (move == 'U') cur_r--;\n        else if (move == 'D') cur_r++;\n        else if (move == 'L') cur_c--;\n        else if (move == 'R') cur_c++;\n        path_cells.push_back({cur_r, cur_c});\n    }\n\n    // Add detours\n    for (int r_target = 0; r_target < N; ++r_target) {\n        for (int c_target = 0; c_target < N; ++c_target) {\n            int count_to_add = extra_visits_count[r_target * N + c_target];\n            if (count_to_add == 0) continue;\n\n            // For each cell, add `count_to_add` detours.\n            // Simple detour: find last visit to (r_target, c_target) and insert a minimal path to it.\n            // This is complicated. A simpler approach: append detours from the END of current path.\n            // Path: P_dfs, then for each (r,c) to visit K times: append path(current_pos, r, c), append path(r,c, current_pos)\n            \n            for(int k=0; k<count_to_add; ++k) {\n                 if (current_path_len + 2 > 100000) break; // Safety break\n\n                // Find current end of path\n                cur_r = path_cells.back().first;\n                cur_c = path_cells.back().second;\n                \n                // Find shortest path from (cur_r, cur_c) to (r_target, c_target)\n                queue<pair<int, int>> q;\n                q.push({cur_r, cur_c});\n                vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited(N, vector<bool>(N, false));\n                visited[cur_r][cur_c] = true;\n                bool found = false;\n\n                while (!q.empty()) {\n                    pair<int, int> curr = q.front();\n                    q.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == r_target && c_curr == c_target) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited[nr][nc]) {\n                            visited[nr][nc] = true;\n                            parent[nr][nc] = {r_curr, c_curr};\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen as all cells are reachable */ continue; }\n\n                // Reconstruct path from (cur_r, cur_c) to (r_target, c_target)\n                vector<char> detour_fwd;\n                vector<pair<int, int>> detour_cells_fwd;\n                pair<int, int> trace = {r_target, c_target};\n                while (trace.first != cur_r || trace.second != cur_c) {\n                    pair<int, int> p_trace = parent[trace.first][trace.second];\n                    if (p_trace.first == -1) break; // Should not happen\n\n                    if (trace.first == p_trace.first - 1) detour_fwd.push_back('U');\n                    else if (trace.first == p_trace.first + 1) detour_fwd.push_back('D');\n                    else if (trace.second == p_trace.second - 1) detour_fwd.push_back('L');\n                    else if (trace.second == p_trace.second + 1) detour_fwd.push_back('R');\n                    \n                    detour_cells_fwd.push_back(trace);\n                    trace = p_trace;\n                }\n                reverse(detour_fwd.begin(), detour_fwd.end());\n                reverse(detour_cells_fwd.begin(), detour_cells_fwd.end());\n\n                // Add detour path to cells list\n                for(char move : detour_fwd) {\n                    path_cells.push_back({r_target,c_target}); // add target cell\n                    if (move == 'U') path_cells.push_back({path_cells.back().first - 1, path_cells.back().second});\n                    else if (move == 'D') path_cells.push_back({path_cells.back().first + 1, path_cells.back().second});\n                    else if (move == 'L') path_cells.push_back({path_cells.back().first, path_cells.back().second - 1});\n                    else if (move == 'R') path_cells.push_back({path_cells.back().first, path_cells.back().second + 1});\n                }\n                \n                // Add the final (r_target, c_target) cell itself\n                path_cells.push_back({r_target, c_target});\n                \n                // Now add path back to original current position (cur_r, cur_c)\n                // This is BFS from (r_target, c_target) to (cur_r, cur_c)\n                queue<pair<int, int>> q_ret;\n                q_ret.push({r_target, c_target});\n                vector<vector<pair<int, int>>> parent_ret(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited_ret(N, vector<bool>(N, false));\n                visited_ret[r_target][c_target] = true;\n                found = false;\n\n                while (!q_ret.empty()) {\n                    pair<int, int> curr = q_ret.front();\n                    q_ret.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == cur_r && c_curr == cur_c) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited_ret[nr][nc]) {\n                            visited_ret[nr][nc] = true;\n                            parent_ret[nr][nc] = {r_curr, c_curr};\n                            q_ret.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen */ continue; }\n\n                // Reconstruct path back\n                trace = {cur_r, cur_c};\n                while(trace.first != r_target || trace.second != c_target) {\n                     pair<int, int> p_trace = parent_ret[trace.first][trace.second];\n                     if (p_trace.first == -1) break;\n\n                     if (trace.first == p_trace.first - 1) path_cells.push_back({p_trace.first - 1, p_trace.second});\n                     else if (trace.first == p_trace.first + 1) path_cells.push_back({p_trace.first + 1, p_trace.second});\n                     else if (trace.second == p_trace.second - 1) path_cells.push_back({p_trace.second - 1, p_trace.second});\n                     else if (trace.second == p_trace.second + 1) path_cells.push_back({p_trace.second + 1, p_trace.second});\n                     trace = p_trace;\n                }\n\n                // Update current path length and position\n                current_path_len = path_cells.size() - 1;\n                if (current_path_len > 100000) { // Cap path length\n                    path_cells.resize(100000 + 1); // Keep start and end for length 100000\n                    current_path_len = 100000;\n                }\n            }\n        }\n    }\n\n    // Convert path_cells back to moves string, truncated if necessary\n    final_path = \"\";\n    for (size_t i = 0; i < path_cells.size() - 1; ++i) {\n        if (final_path.length() >= 100000) break;\n\n        int r1 = path_cells[i].first;\n        int c1 = path_cells[i].second;\n        int r2 = path_cells[i+1].first;\n        int c2 = path_cells[i+1].second;\n\n        if (r2 == r1 - 1) final_path += 'U';\n        else if (r2 == r1 + 1) final_path += 'D';\n        else if (c2 == c1 - 1) final_path += 'L';\n        else if (c2 == c1 + 1) final_path += 'R';\n    }\n\n    cout << final_path << endl;\n\n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <map>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nint N;\nchar grid[15][15];\nvector<string> t;\nint start_r, start_c;\n\n// For Dijkstra to find path for one string\n// dp[p][r][c]: min cost to type first p characters of target string, ending at (r,c)\n// where grid[r][c] matches the p-th character.\n// p from 1 to 5.\nlong long dp[6][15][15];\npair<int, int> pred[6][15][15]; // Stores previous coordinates to reconstruct path\n\n// Directions for BFS/Dijkstra\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nstruct State {\n    long long cost;\n    int r, c;\n\n    bool operator>(const State& other) const {\n        return cost > other.cost;\n    }\n};\n\n// Computes the minimum cost and path to type target_str starting from (sr, sc)\n// Returns {min_total_cost, end_r, end_c, sequence_of_operations}\ntuple<long long, int, int, vector<pair<int, int>>> compute_path(const string& target_str, int sr, int sc) {\n    for (int p = 0; p <= 5; ++p) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                dp[p][r][c] = INF;\n                pred[p][r][c] = {-1, -1};\n            }\n        }\n    }\n\n    char first_char = target_str[0];\n    \n    // Base case: p=1 (typing the first character)\n    // dp[1][r][c] = min cost to type first character (target_str[0]) ending at (r,c)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] == first_char) {\n                dp[1][r][c] = abs(r - sr) + abs(c - sc) + 1;\n                // pred[1][r][c] remains {-1, -1} to signify start\n            }\n        }\n    }\n\n    // Fill DP table for p = 2 to 5\n    for (int p = 2; p <= 5; ++p) {\n        char current_char_needed = target_str[p - 1];\n        \n        priority_queue<State, vector<State>, greater<State>> pq;\n        vector<vector<long long>> dist(N, vector<long long>(N, INF));\n        vector<vector<pair<int, int>>> layer_pred(N, vector<pair<int, int>>(N, {-1,-1}));\n\n        // Initialize Dijkstra PQ with costs from previous step (p-1)\n        // States in PQ are (cost_to_type_p-1_chars_ending_here, r, c)\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (dp[p - 1][r][c] != INF) {\n                    pq.push({dp[p - 1][r][c], r, c});\n                    dist[r][c] = dp[p - 1][r][c]; // dist here is min cost to reach (r,c) having typed p-1 chars\n                }\n            }\n        }\n\n        // Run Dijkstra\n        // We want to find min cost to reach any cell (nr, nc) for current_char_needed\n        // from any cell (r,c) which is a valid end for p-1 characters.\n        while (!pq.empty()) {\n            State current = pq.top();\n            pq.pop();\n\n            long long d = current.cost;\n            int r = current.r;\n            int c = current.c;\n\n            if (d > dist[r][c]) continue;\n\n            // Explore neighbors\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i];\n                int nc = c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    // Cost to move from (r,c) to (nr,nc) AND append grid[nr][nc]\n                    long long move_cost = abs(nr - r) + abs(nc - c) + 1;\n                    \n                    // If the neighbor cell (nr, nc) has the character needed for the current step (p)\n                    if (grid[nr][nc] == current_char_needed) {\n                        if (dist[r][c] + move_cost < dist[nr][nc]) {\n                            dist[nr][nc] = dist[r][c] + move_cost;\n                            layer_pred[nr][nc] = {r, c}; // Store predecessor for path reconstruction\n                            pq.push({dist[nr][nc], nr, nc});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Update DP table for step p\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (grid[r][c] == current_char_needed && dist[r][c] != INF) {\n                    dp[p][r][c] = dist[r][c];\n                    pred[p][r][c] = layer_pred[r][c]; // Store predecessor for path reconstruction\n                }\n            }\n        }\n    }\n\n    // Find the minimum cost to type the whole string (length 5)\n    long long min_total_cost = INF;\n    int final_r = -1, final_c = -1;\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[5][r][c] < min_total_cost) {\n                min_total_cost = dp[5][r][c];\n                final_r = r;\n                final_c = c;\n            }\n        }\n    }\n\n    // Reconstruct path\n    vector<pair<int, int>> path_ops;\n    if (final_r != -1) {\n        int curr_r = final_r;\n        int curr_c = final_c;\n        for (int p = 5; p >= 1; --p) {\n            path_ops.push_back({curr_r, curr_c});\n            if (p > 1) { // For p=1, pred is {-1,-1}\n                pair<int, int> prev_pos = pred[p][curr_r][curr_c];\n                curr_r = prev_pos.first;\n                curr_c = prev_pos.second;\n            }\n        }\n        reverse(path_ops.begin(), path_ops.end());\n    }\n    \n    return {min_total_cost, final_r, final_c, path_ops};\n}\n\n// Helper to check if string 'needle' is a substring of 'haystack'\nbool contains(const string& haystack, const string& needle) {\n    return haystack.find(needle) != string::npos;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M >> start_r >> start_c;\n    --start_r; --start_c; // 0-indexed\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    t.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> t[i];\n    }\n\n    vector<pair<int, int>> operations;\n    set<int> uncovered_indices;\n    for (int i = 0; i < M; ++i) {\n        uncovered_indices.insert(i);\n    }\n\n    int current_r = start_r;\n    int current_c = start_c;\n    long long total_cost = 0;\n    \n    // We can perform at most 5000 operations.\n    // Our strategy is to greedily type the cheapest full string that is not yet covered.\n    // Each typed string requires 5 operations.\n    // We continue this until we have typed 1000 strings (total 5000 operations)\n    // or until all strings are covered.\n\n    int max_strings_to_type = 1000; \n\n    for (int iter = 0; iter < max_strings_to_type; ++iter) {\n        if (uncovered_indices.empty()) break; // All strings are covered\n\n        long long min_iter_cost = INF;\n        int best_t_idx = -1;\n        int best_end_r = -1, best_end_c = -1;\n        vector<pair<int, int>> ops_for_best_t;\n\n        // Find the cheapest string to type among the currently uncovered ones\n        for (int idx : uncovered_indices) {\n            auto [cost, end_r, end_c, current_ops] = compute_path(t[idx], current_r, current_c);\n            \n            if (cost < min_iter_cost) {\n                min_iter_cost = cost;\n                best_t_idx = idx;\n                best_end_r = end_r;\n                best_end_c = end_c;\n                ops_for_best_t = current_ops;\n            }\n        }\n\n        // If no string can be typed (e.g., required chars not on grid, which is guaranteed not to happen)\n        if (best_t_idx == -1) { \n            break;\n        }\n\n        // Append operations for the chosen string\n        operations.insert(operations.end(), ops_for_best_t.begin(), ops_for_best_t.end());\n        current_r = best_end_r;\n        current_c = best_end_c;\n        total_cost += min_iter_cost;\n        \n        // Remove the typed string from the set of uncovered indices\n        uncovered_indices.erase(best_t_idx);\n    }\n\n    // Output the operations\n    cout << operations.size() << endl;\n    for (const auto& op : operations) {\n        cout << op.first + 1 << \" \" << op.second + 1 << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath> // Included for completeness, though not directly used in the final strategy.\n#include <iomanip> // Included for completeness, though not directly used in the final strategy.\n#include <utility> // Required for std::pair.\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // This can significantly speed up input/output operations, which is crucial\n    // for problems with large I/O or strict time limits.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // The size of the island grid (N x N). Constraints: 10 <= N <= 20.\n    int m; // The number of unexplored oil fields. Constraints: 2 <= M <= 20.\n    double epsilon; // The error parameter for the noisy divine query operation. Constraints: 0.01 <= epsilon <= 0.2.\n\n    // Read the initial problem parameters from standard input.\n    std::cin >> n >> m >> epsilon;\n\n    // Read the shapes of the M oil fields.\n    // Each shape is defined by its area (d) and a list of relative coordinates\n    // for the squares it occupies.\n    // For the chosen strategy (drilling every square), this information is not directly used.\n    // A more complex heuristic or optimization strategy might leverage these shapes\n    // to infer potential locations or prune search spaces.\n    for (int k = 0; k < m; ++k) {\n        int d; // The number of squares in the k-th oil field (area).\n        std::cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int r, c; // Relative coordinates (row, column) of a square within the k-th oil field shape.\n            std::cin >> r >> c;\n            // The current strategy ignores these shapes.\n        }\n    }\n\n    // This vector will store the coordinates (row, column) of all squares\n    // that are found to contain oil reserves (i.e., v(i,j) > 0).\n    // This list will form the basis of our final \"guess\" operation.\n    std::vector<std::pair<int, int>> positive_oil_squares;\n\n    // --- Chosen Strategy: Drill every square on the island ---\n    //\n    // This is a deterministic, brute-force approach. It queries each of the N*N squares\n    // individually to reveal its exact oil reserve value v(i,j).\n    //\n    // Cost Analysis:\n    // - Operation Type: \"Drill\" (q 1 i j). Cost per operation: 1.\n    // - Total number of squares on the island: N*N.\n    // - Total cost for performing N*N drill operations: N*N.\n    //\n    // Operation Limit Analysis:\n    // - The problem statement allows a maximum of 2*N*N operations in total.\n    // - For the maximum island size N=20, N*N = 400 operations, and 2*N*N = 800 operations.\n    // - The N*N cost of this strategy is well within the allowed operation limit.\n    //\n    // Correctness Guarantee:\n    // - By drilling every square, we obtain the exact value of v(i,j) for every cell.\n    // - This guarantees that we can precisely identify *all* squares where v(i,j) > 0.\n    // - The final \"guess\" operation will therefore be 100% accurate, leading to a successful completion.\n    //\n    // Justification for ignoring the \"divine\" operation:\n    // - The \"divine\" operation (querying a set S of k squares) has a cost of 1/sqrt(k) but returns a noisy sum.\n    // - The noise (variance) increases with k, making it difficult to obtain precise information about individual v(i,j) values,\n    //   especially small values or distinguishing v(i,j)=0 from v(i,j)=1.\n    // - To guarantee identifying *all* squares with v(i,j) > 0, definitive information is required. Drilling provides this.\n    // - Given the small constraints on N (N <= 20), the total cost of N*N is sufficiently low. The guaranteed correctness\n    //   and simplicity of the drilling strategy make it a robust choice for achieving a high score. More complex strategies\n    //   involving divine queries might offer marginal benefits only for much larger grid sizes.\n    //\n    // Implementation Loop:\n    // - We iterate through each row 'i' from 0 to N-1.\n    // - Within each row, we iterate through each column 'j' from 0 to N-1.\n    // - For every square (i, j), we issue a \"drill\" query.\n    // - We then read the revealed oil reserves for that square.\n    // - If the reserves are positive, we record the square's coordinates.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            // Output the drill query command: \"q 1 <row> <column>\"\n            // std::endl automatically flushes the output buffer.\n            std::cout << \"q 1 \" << i << \" \" << j << std::endl;\n\n            int reserves; // The value v(i, j) revealed for the current square.\n            std::cin >> reserves; // Read the result from standard input.\n\n            // If the square contains oil (reserves > 0), store its coordinates.\n            if (reserves > 0) {\n                positive_oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // --- Output the Final Guess ---\n    //\n    // Once all squares have been drilled, the 'positive_oil_squares' vector contains\n    // the exact set of squares that have oil reserves. We now form the final \"guess\" operation.\n    //\n    // The format for the guess operation is: \"a <d> <i1> <j1> <i2> <j2> ...\"\n    // where 'd' is the total number of squares guessed to have oil.\n    std::cout << \"a \" << positive_oil_squares.size();\n    for (const auto& p : positive_oil_squares) {\n        std::cout << \" \" << p.first << \" \" << p.second;\n    }\n    std::cout << std::endl; // Flush the output buffer to ensure the guess is sent.\n\n    // --- Read Confirmation from Judge ---\n    //\n    // The judge will respond with '1' if our guess is correct and '0' if it is incorrect.\n    // Given the deterministic nature of the drilling strategy, we expect this to always be '1'.\n    int correct;\n    std::cin >> correct;\n\n    // If the guess was correct, the program has successfully completed its task.\n    if (correct == 1) {\n        return 0; // Exit with a success code.\n    } else {\n        // If the guess was incorrect (correct == 0), this indicates an unexpected issue.\n        // The N^2 drilling strategy is designed to be infallible for this problem.\n        // If this branch is reached, it might point to a subtle problem interpretation error\n        // or an extremely rare edge case. We exit with a non-zero code to signal abnormal termination.\n        return 1; \n    }\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n#include <map>\n#include <set>\n#include <iomanip>\n\nusing namespace std;\n\nlong long W;\nint D, N;\n\n// Represents a rectangular section.\nstruct Rect {\n    int x0, y0, x1, y1;       // Top-left (x0, y0) and bottom-right (x1, y1) coordinates.\n    long long area;           // Pre-calculated area.\n    int original_idx;         // Index within the generated list for a specific structure type (for debugging/tracking).\n};\n\n// Enum to identify different partition structures.\n// These are pre-defined layouts that divide the WxW area into N rectangles.\nenum StructureType {\n    RECURSIVE_BALANCED = 0, // Dynamically balanced subdivision.\n    VERTICAL_STRIPS = 1,    // N vertical strips of roughly equal width.\n    HORIZONTAL_STRIPS = 2,  // N horizontal strips of roughly equal height.\n    // Grid types: p x q grids where p is small and q is approx N/p.\n    GRID_2xN = 3, // 2 rows, approx N/2 cols\n    GRID_3xN = 4, // 3 rows, approx N/3 cols\n    GRID_4xN = 5, // 4 rows, approx N/4 cols\n    GRID_5xN = 6, // 5 rows, approx N/5 cols\n    GRID_6xN = 7, // 6 rows, approx N/6 cols\n    GRID_Nx2 = 8, // approx N/2 rows, 2 cols\n    GRID_Nx3 = 9, // approx N/3 rows, 3 cols\n    GRID_Nx4 = 10, // approx N/4 rows, 4 cols\n    GRID_Nx5 = 11, // approx N/5 rows, 5 cols\n    GRID_Nx6 = 12, // approx N/6 rows, 6 cols\n    NUM_STRUCTURES // Count of all defined types.\n};\n\n// Limit the number of candidate structures to evaluate to manage computation time.\nconst int MAX_STRUCTURES = 10; \n// Stores the types of partition structures that will be considered.\nvector<StructureType> active_structure_types;\n\n// --- Structure Generation Functions ---\n\n// Recursive helper to generate N rectangles by balanced subdivision.\n// Splits along the larger dimension to maintain aspect ratios.\nvoid generate_recursive_helper(vector<Rect>& rects, int x0, int y0, int x1, int y1, int count_needed, int& rect_idx) {\n    if (count_needed == 0) return; // No rectangles needed.\n    if (count_needed == 1) { // Base case: create the single rectangle.\n        rects.push_back({x0, y0, x1, y1, (long long)(x1 - x0) * (y1 - y0), rect_idx++});\n        return;\n    }\n\n    long long total_width = x1 - x0;\n    long long total_height = y1 - y0;\n    // Divide `count_needed` into two parts for the children.\n    int num_left_child = count_needed / 2;\n    int num_right_child = count_needed - num_left_child;\n\n    // Split along the larger dimension to keep rectangles somewhat square-like.\n    if (total_width >= total_height) { // Split vertically\n        // Calculate the split point `mid_x` such that the resulting child areas are proportional\n        // to the number of rectangles they will hold.\n        long long mid_x = x0 + total_width * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, mid_x, y1, num_left_child, rect_idx);\n        generate_recursive_helper(rects, mid_x, y0, x1, y1, num_right_child, rect_idx);\n    } else { // Split horizontally\n        long long mid_y = y0 + total_height * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, x1, mid_y, num_left_child, rect_idx);\n        generate_recursive_helper(rects, x0, mid_y, x1, y1, num_right_child, rect_idx);\n    }\n}\n\n// Helper to generate a p x q grid of rectangles, ensuring exactly N rectangles are created.\n// If `rows * cols < N`, it subdivides existing rectangles until N are generated.\nvoid generate_grid_structure(vector<Rect>& rects, int rows, int cols, int& rect_idx) {\n    if (rows <= 0 || cols <= 0) return; // Ensure valid grid dimensions.\n    \n    long long total_width = W;\n    long long total_height = W;\n\n    // Calculate width for each column, distributing any remainder pixels.\n    vector<long long> col_widths(cols);\n    long long base_w = total_width / cols;\n    long long remainder_w = total_width % cols;\n    for (int j = 0; j < cols; ++j) {\n        col_widths[j] = base_w + (j < remainder_w ? 1 : 0);\n    }\n\n    // Calculate height for each row, distributing any remainder pixels.\n    vector<long long> row_heights(rows);\n    long long base_h = total_height / rows;\n    long long remainder_h = total_height % rows;\n    for (int i = 0; i < rows; ++i) {\n        row_heights[i] = base_h + (i < remainder_h ? 1 : 0);\n    }\n\n    int current_y = 0;\n    int rect_count_initially = 0; // Count rectangles generated by initial grid layout.\n    for (int i = 0; i < rows; ++i) {\n        long long h = row_heights[i]; // Height of the current row.\n        int current_x = 0;\n        for (int j = 0; j < cols; ++j) {\n            // Only add rectangles if we haven't reached the target N.\n            // The loop structure naturally generates rows * cols cells.\n            if (rect_count_initially < N) { \n                long long w = col_widths[j]; // Width of the current column.\n                if (w > 0 && h > 0) { // Create rectangle if dimensions are positive.\n                    rects.push_back({current_x, current_y, current_x + (int)w, current_y + (int)h, w * h, rect_idx++});\n                    rect_count_initially++;\n                } else { // If dimensions are zero, add a dummy (should be rare).\n                    rects.push_back({current_x, current_y, current_x, current_y, 0, rect_idx++});\n                    rect_count_initially++;\n                }\n                current_x += w;\n            } else {\n                break; // Stop adding cells if N rectangles have already been generated.\n            }\n        }\n        current_y += h;\n        if (rect_count_initially == N) break; // Stop if N rectangles are generated.\n    }\n    \n    // Subdivision phase: If the initial grid layout produced fewer than N rectangles,\n    // subdivide existing rectangles until N are generated. This ensures no zero-area dummy rectangles.\n    while (rects.size() < static_cast<size_t>(N)) {\n        // Find the largest rectangle that can be subdivided into two valid rectangles.\n        int best_rect_idx_to_subdivide = -1;\n        long long max_subdiv_dim = -1; // Max dimension (width or height) that can be split.\n\n        for(int i = 0; i < rects.size(); ++i) {\n            long long current_w = rects[i].x1 - rects[i].x0;\n            long long current_h = rects[i].y1 - rects[i].y0;\n            // Prefer splitting the largest dimension.\n            if (current_w > 1 && current_w >= max_subdiv_dim) { // Can split vertically\n                max_subdiv_dim = current_w;\n                best_rect_idx_to_subdivide = i;\n            }\n            if (current_h > 1 && current_h >= max_subdiv_dim) { // Can split horizontally\n                max_subdiv_dim = current_h;\n                best_rect_idx_to_subdivide = i;\n            }\n        }\n\n        if (best_rect_idx_to_subdivide != -1) {\n            Rect rect_to_subdivide = rects[best_rect_idx_to_subdivide];\n            // Remove the rectangle to be subdivided.\n            rects.erase(rects.begin() + best_rect_idx_to_subdivide);\n\n            long long sub_w = rect_to_subdivide.x1 - rect_to_subdivide.x0;\n            long long sub_h = rect_to_subdivide.y1 - rect_to_subdivide.y0;\n\n            // Decide split direction: prefer splitting the larger dimension.\n            if (sub_w >= sub_h) { // Split vertically\n                int mid_x = rect_to_subdivide.x0 + sub_w / 2;\n                // Add first part\n                rects.push_back({rect_to_subdivide.x0, rect_to_subdivide.y0, mid_x, rect_to_subdivide.y1, (long long)(mid_x - rect_to_subdivide.x0) * sub_h, rect_idx++});\n                // Add second part\n                rects.push_back({mid_x, rect_to_subdivide.y0, rect_to_subdivide.x1, rect_to_subdivide.y1, (long long)(rect_to_subdivide.x1 - mid_x) * sub_h, rect_idx++});\n            } else { // Split horizontally\n                int mid_y = rect_to_subdivide.y0 + sub_h / 2;\n                // Add first part\n                rects.push_back({rect_to_subdivide.x0, rect_to_subdivide.y0, rect_to_subdivide.x1, mid_y, (long long)sub_w * (mid_y - rect_to_subdivide.y0), rect_idx++});\n                // Add second part\n                rects.push_back({rect_to_subdivide.x0, mid_y, rect_to_subdivide.x1, rect_to_subdivide.y1, (long long)sub_w * (rect_to_subdivide.y1 - mid_y), rect_idx++});\n            }\n        } else {\n            // If no rectangle can be subdivided (e.g., all are 1x1 or similar edge cases)\n            // and rects.size() < N, it means we are in a state where we cannot create N valid rectangles.\n            // This should be extremely rare given W=1000 and N<=50. Break to avoid infinite loop.\n            // The generated output might be invalid if N is not met, but this path is highly unlikely.\n            break; \n        }\n    }\n}\n\n// Generates the list of N Rect objects for a given structure type.\nvector<Rect> generate_rects_for_structure(StructureType type, int num_rects) {\n    vector<Rect> rects;\n    rects.reserve(num_rects); // Reserve space for efficiency.\n    int current_idx = 0; // Tracks the index for each generated rectangle.\n\n    if (type == RECURSIVE_BALANCED) {\n        generate_recursive_helper(rects, 0, 0, W, W, num_rects, current_idx);\n    } else if (type == VERTICAL_STRIPS) {\n        long long base_w = W / num_rects;\n        long long remainder_w = W % num_rects;\n        int current_x = 0;\n        for (int i = 0; i < num_rects; ++i) {\n            long long w = base_w + (i < remainder_w ? 1 : 0);\n            if (w > 0) { // Add rectangle if width is positive.\n                rects.push_back({current_x, 0, current_x + (int)w, (int)W, w * W, current_idx++});\n                current_x += w;\n            } else { // Safeguard for N > W (though constraints say N <= 50, W=1000). Add dummy if width is zero.\n                 rects.push_back({current_x, 0, current_x, (int)W, 0, current_idx++});\n            }\n        }\n    } else if (type == HORIZONTAL_STRIPS) {\n        long long base_h = W / num_rects;\n        long long remainder_h = W % num_rects;\n        int current_y = 0;\n        for (int i = 0; i < num_rects; ++i) {\n            long long h = base_h + (i < remainder_h ? 1 : 0);\n            if (h > 0) { // Add rectangle if height is positive.\n                rects.push_back({0, current_y, (int)W, current_y + (int)h, W * h, current_idx++});\n                current_y += h;\n            } else { // Safeguard for N > W. Add dummy if height is zero.\n                 rects.push_back({0, current_y, (int)W, current_y, 0, current_idx++});\n            }\n        }\n    } else { // Grid types (e.g., 2xN, Nx3).\n        int rows = -1, cols = -1;\n        // Define rows and columns for specific grid types using integer division for cols/rows.\n        if (type == GRID_2xN) { rows = 2; cols = N / 2; }\n        else if (type == GRID_3xN) { rows = 3; cols = N / 3; }\n        else if (type == GRID_4xN) { rows = 4; cols = N / 4; }\n        else if (type == GRID_5xN) { rows = 5; cols = N / 5; }\n        else if (type == GRID_6xN) { rows = 6; cols = N / 6; }\n        else if (type == GRID_Nx2) { rows = N / 2; cols = 2; }\n        else if (type == GRID_Nx3) { rows = N / 3; cols = 3; }\n        else if (type == GRID_Nx4) { rows = N / 4; cols = 4; }\n        else if (type == GRID_Nx5) { rows = N / 5; cols = 5; }\n        else if (type == GRID_Nx6) { rows = N / 6; cols = 6; }\n        \n        // Call grid generator if rows/cols are valid. `generate_grid_structure` handles creating exactly N rects.\n        if (rows > 0 && cols > 0) {\n            generate_grid_structure(rects, rows, cols, current_idx);\n        }\n    }\n\n    // Ensure exactly `num_rects` are generated by padding with dummy rectangles if needed.\n    // This is a final safeguard, but the subdivision logic in generate_grid_structure should prevent zero-area dummies.\n    while (rects.size() < static_cast<size_t>(num_rects)) { \n        rects.push_back({0, 0, 0, 0, 0, current_idx++}); // Add a zero-area dummy rectangle if N is not met.\n    }\n    return rects;\n}\n\n// --- Partition Cost Calculation ---\n\n// Represents partition lines using maps of intervals.\n// `h_lines`: maps row index -> list of [y_start, y_end) intervals for horizontal segments on that row.\n// `v_lines`: maps column index -> list of [x_start, x_end) intervals for vertical segments on that column.\nusing PartitionLines = pair<map<int, vector<pair<int, int>>>, map<int, vector<pair<int, int>>>>;\n\n// Merges overlapping or adjacent intervals in a list. Essential for simplifying partition representations.\nvoid normalize_intervals(vector<pair<int, int>>& intervals) {\n    if (intervals.empty()) return;\n    sort(intervals.begin(), intervals.end()); // Sort intervals by start point.\n    vector<pair<int, int>> merged;\n    merged.push_back(intervals[0]);\n    for (size_t i = 1; i < intervals.size(); ++i) {\n        // If current interval starts before or at the end of the last merged interval, merge them.\n        if (intervals[i].first <= merged.back().second) {\n            merged.back().second = max(merged.back().second, intervals[i].second);\n        } else {\n            merged.push_back(intervals[i]); // Otherwise, start a new merged interval.\n        }\n    }\n    intervals = merged;\n}\n\n// Generates the `PartitionLines` representation from a list of `Rect` objects.\nPartitionLines get_partition_lines(const vector<Rect>& rects) {\n    map<int, vector<pair<int, int>>> h_lines; // Map for horizontal partition segments.\n    map<int, vector<pair<int, int>>> v_lines; // Map for vertical partition segments.\n\n    for (const auto& r : rects) {\n        // Horizontal segments are on grid lines `i` where `1 <= i <= W-1`.\n        // Vertical segments are on grid lines `j` where `1 <= j <= W-1`.\n\n        // Top edge partition at row r.x0 (if it's an interior grid line).\n        if (r.x0 >= 1 && r.x0 <= W - 1 && r.y0 < r.y1) {\n            h_lines[r.x0].push_back({r.y0, r.y1});\n        }\n        // Bottom edge partition at row r.x1 (if it's an interior grid line).\n        if (r.x1 >= 1 && r.x1 <= W - 1 && r.y0 < r.y1) {\n            h_lines[r.x1].push_back({r.y0, r.y1});\n        }\n\n        // Left edge partition at column r.y0 (if it's an interior grid line).\n        if (r.y0 >= 1 && r.y0 <= W - 1 && r.x0 < r.x1) {\n            v_lines[r.y0].push_back({r.x0, r.x1});\n        }\n        // Right edge partition at column r.y1 (if it's an interior grid line).\n        if (r.y1 >= 1 && r.y1 <= W - 1 && r.x0 < r.x1) {\n            v_lines[r.y1].push_back({r.x0, r.x1});\n        }\n    }\n    \n    // Normalize intervals for each row/column to simplify calculations.\n    for (auto& pair : h_lines) normalize_intervals(pair.second);\n    for (auto& pair : v_lines) normalize_intervals(pair.second);\n    \n    return {h_lines, v_lines};\n}\n\n// Helper to get a boolean array representing segment coverage using a sweep-line algorithm.\n// `present` array of size `W_bound` indicates if a segment at index `k` (0 to W_bound-1) is covered.\nvector<bool> get_coverage_array(const vector<pair<int, int>>& intervals, int W_bound) {\n    vector<bool> present(W_bound, false); // Initialize all segments as not present.\n    if (intervals.empty()) return present;\n\n    // Create event points: {coordinate, type (+1 for interval start, -1 for interval end)}.\n    vector<pair<int, int>> events;\n    events.reserve(intervals.size() * 2);\n    for(const auto& interval : intervals) {\n        if (interval.first < interval.second) { // Ensure valid interval [start, end).\n            events.push_back({interval.first, 1});  // Event at start of interval.\n            events.push_back({interval.second, -1}); // Event at end of interval.\n        }\n    }\n    sort(events.begin(), events.end()); // Sort events by coordinate.\n\n    int current_coverage = 0; // Tracks how many intervals cover the current position.\n    int current_pos = 0;      // The current position in the sweep.\n\n    // Process events to determine coverage.\n    for(const auto& event : events) {\n        int pos = event.first;\n        int type = event.second;\n\n        // Fill the `present` array for the segment [current_pos, pos) if it's covered.\n        // Clamp `pos` to `W_bound` to avoid out-of-bounds access.\n        int end_pos = min(pos, W_bound);\n        if (current_coverage > 0) { // If coverage > 0, this range is covered.\n            for (int k = current_pos; k < end_pos; ++k) {\n                present[k] = true;\n            }\n        }\n        current_coverage += type; // Update coverage based on event type.\n        current_pos = pos;        // Move sweep position.\n        if (current_pos >= W_bound) break; // Stop if we've swept past the boundary.\n    }\n    return present;\n}\n\n// Calculates the partition installation/removal cost between two `PartitionLines` configurations.\n// Cost is incurred for each unit segment where the partition state differs.\nlong long calculate_partition_cost(const PartitionLines& p1, const PartitionLines& p2) {\n    long long cost = 0;\n    const auto& H1 = p1.first; const auto& V1 = p1.second;\n    const auto& H2 = p2.first; const auto& V2 = p2.second;\n\n    // Collect all unique row and column indices that have partitions in either configuration.\n    set<int> h_rows, v_cols;\n    for(const auto& pair : H1) h_rows.insert(pair.first);\n    for(const auto& pair : H2) h_rows.insert(pair.first);\n    for(const auto& pair : V1) v_cols.insert(pair.first);\n    for(const auto& pair : V2) v_cols.insert(pair.first);\n\n    // Calculate horizontal cost: iterate through relevant rows.\n    // Horizontal segments exist on grid lines i = 1 to W-1.\n    for (int r : h_rows) {\n        if (r < 1 || r >= W) continue; // Skip rows outside the valid interior partition lines.\n\n        // Get interval lists for this row from both partition configurations. Use empty list if no partitions.\n        const vector<pair<int,int>>& intervals1 = (H1.count(r) ? H1.at(r) : vector<pair<int,int>>{});\n        const vector<pair<int,int>>& intervals2 = (H2.count(r) ? H2.at(r) : vector<pair<int,int>>{});\n        \n        // Get coverage arrays for this row to represent partition presence for each segment.\n        vector<bool> present1 = get_coverage_array(intervals1, W);\n        vector<bool> present2 = get_coverage_array(intervals2, W);\n\n        // Compare segment presence for segments (r,j)-(r,j+1) where j = 0 to W-1.\n        for (int j = 0; j < W; ++j) {\n            if (present1[j] != present2[j]) { // If partition state differs for segment j, increment cost.\n                cost++;\n            }\n        }\n    }\n\n    // Calculate vertical cost: iterate through relevant columns.\n    // Vertical segments exist on grid lines j = 1 to W-1.\n    for (int c : v_cols) {\n        if (c < 1 || c >= W) continue; // Skip columns outside the valid interior partition lines.\n\n        // Get interval lists for this column from both partition configurations.\n        const vector<pair<int,int>>& intervals1 = (V1.count(c) ? V1.at(c) : vector<pair<int,int>>{});\n        const vector<pair<int,int>>& intervals2 = (V2.count(c) ? V2.at(c) : vector<pair<int,int>>{});\n        \n        // Get coverage arrays for this column.\n        vector<bool> present1 = get_coverage_array(intervals1, W);\n        vector<bool> present2 = get_coverage_array(intervals2, W);\n\n        // Compare segment presence for segments (i,c)-(i+1,c) where i = 0 to W-1.\n        for (int i = 0; i < W; ++i) {\n            if (present1[i] != present2[i]) { // If partition state differs for segment i, increment cost.\n                cost++;\n            }\n        }\n    }\n    \n    return cost;\n}\n\n// --- Main Logic ---\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> W >> D >> N;\n\n    // Store desired areas for each reservation on each day.\n    // `a_d_k_sorted_by_area[d][i]` will store {area, original_k} for the reservation\n    // that has the i-th largest area on day `d`. This allows for greedy assignment.\n    vector<vector<pair<int, int>>> a_d_k_sorted_by_area(D, vector<pair<int, int>>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a_d_k_sorted_by_area[d][k].first;\n            a_d_k_sorted_by_area[d][k].second = k; // Store original reservation index.\n        }\n        // Sort reservations for day `d` by area in descending order.\n        sort(a_d_k_sorted_by_area[d].rbegin(), a_d_k_sorted_by_area[d].rend());\n    }\n\n    // --- Generate candidate structures and precompute ---\n    // Using maps for cleaner storage and retrieval of structure-specific data.\n    map<StructureType, vector<Rect>> base_rects_map;\n    map<StructureType, PartitionLines> partition_lines_map;\n    map<StructureType, vector<long long>> area_costs_map; // Stores area costs per day for each structure type.\n\n    // Select a limited set of diverse partition structures to evaluate.\n    active_structure_types.clear();\n    active_structure_types.push_back(RECURSIVE_BALANCED);\n    active_structure_types.push_back(VERTICAL_STRIPS);\n    active_structure_types.push_back(HORIZONTAL_STRIPS);\n\n    // Add grid structures for small p (2 to 6).\n    // We include p x (N/p) and (N/p) x p grids using integer division.\n    // `generate_grid_structure` will then ensure exactly N rectangles are produced, subdividing if necessary.\n    for (int p = 2; p <= 6; ++p) {\n        // p x (N/p) grid type\n        if (active_structure_types.size() < MAX_STRUCTURES) {\n            // Assign to GRID_2xN + (p-2) for p=2..6\n            active_structure_types.push_back(static_cast<StructureType>(StructureType::GRID_2xN + (p - 2)));\n        }\n        // (N/p) x p grid type\n        // Only add if it's different from p x (N/p) aspect ratio AND we have space.\n        if (p != N / p && active_structure_types.size() < MAX_STRUCTURES) {\n            // Assign to GRID_Nx2 + (p-2) for p=2..6\n            active_structure_types.push_back(static_cast<StructureType>(StructureType::GRID_Nx2 + (p - 2)));\n        }\n    }\n    \n    // Trim the list of active structures if it exceeds the predefined MAX_STRUCTURES limit.\n    if (active_structure_types.size() > MAX_STRUCTURES) {\n        active_structure_types.resize(MAX_STRUCTURES);\n    }\n    \n    int num_active_structures = active_structure_types.size(); // Number of structures to evaluate.\n\n    // Precompute data for each selected structure type.\n    for (int i = 0; i < num_active_structures; ++i) {\n        StructureType current_type = active_structure_types[i];\n        \n        // 1. Generate the N base rectangles for this structure.\n        base_rects_map[current_type] = generate_rects_for_structure(current_type, N);\n        // 2. Get the partition line representation for this structure.\n        partition_lines_map[current_type] = get_partition_lines(base_rects_map[current_type]);\n        \n        // 3. Calculate area costs for each day using this structure.\n        area_costs_map[current_type].resize(D);\n        \n        // Sort the base rectangles by area in descending order. This defines the available \"slots\".\n        vector<Rect> sorted_base_rects = base_rects_map[current_type];\n        sort(sorted_base_rects.begin(), sorted_base_rects.end(), [](const Rect& a, const Rect& b) {\n            return a.area > b.area; // Descending order of area.\n        });\n\n        // Calculate area cost for each day by greedily assigning the i-th largest reservation\n        // to the i-th largest base rectangle slot.\n        for (int d = 0; d < D; ++d) {\n            long long current_day_area_cost = 0;\n            for (int res_rank = 0; res_rank < N; ++res_rank) { // Iterate through reservations sorted by area.\n                long long required_area = a_d_k_sorted_by_area[d][res_rank].first;\n                long long assigned_area = sorted_base_rects[res_rank].area;\n                current_day_area_cost += 100LL * max(0LL, required_area - assigned_area);\n            }\n            area_costs_map[current_type][d] = current_day_area_cost;\n        }\n    }\n\n    // Precompute partition costs between all pairs of *active* structure types.\n    // The cost matrix uses indices corresponding to the `active_structure_types` vector (0 to `num_active_structures - 1`).\n    vector<vector<long long>> partition_cost_matrix(num_active_structures, vector<long long>(num_active_structures));\n    for (int i = 0; i < num_active_structures; ++i) {\n        for (int j = 0; j < num_active_structures; ++j) {\n            // Calculate cost to transition from structure active_structure_types[j] to active_structure_types[i].\n            partition_cost_matrix[i][j] = calculate_partition_cost(partition_lines_map[active_structure_types[i]], partition_lines_map[active_structure_types[j]]);\n        }\n    }\n\n    // --- Dynamic Programming to find the optimal sequence of structures ---\n    // DP[d][i]: Minimum total cost up to day 'd', ending with the structure `active_structure_types[i]`.\n    vector<vector<long long>> DP(D, vector<long long>(num_active_structures));\n    // parent[d][i]: Stores the index (in `active_structure_types`) of the structure used on day 'd-1'\n    // that led to the minimum cost DP[d][i]. Used for backtracking the optimal path.\n    vector<vector<int>> parent(D, vector<int>(num_active_structures));\n\n    // Base case: Day 0. The cost is just the area cost for each structure type. No partition cost on day 0.\n    for (int i = 0; i < num_active_structures; ++i) {\n        StructureType current_type = active_structure_types[i];\n        DP[0][i] = area_costs_map[current_type][0]; // Area cost for day 0.\n        parent[0][i] = -1; // Sentinel value indicating the start of the path.\n    }\n\n    // Transitions: Calculate DP values for Day 1 up to Day D-1.\n    for (int d = 1; d < D; ++d) {\n        for (int i = 0; i < num_active_structures; ++i) { // Current structure type index for day 'd'.\n            StructureType curr_s_type = active_structure_types[i];\n            long long min_prev_total_cost = -1;\n            int best_prev_idx = -1; // Index in `active_structure_types` for the best previous structure.\n\n            long long current_day_area_cost = area_costs_map[curr_s_type][d]; // Area cost for current day with current structure.\n\n            // Iterate through all possible previous structure types for day 'd-1'.\n            for (int j = 0; j < num_active_structures; ++j) {\n                long long prev_day_total_cost = DP[d - 1][j]; // Min cost up to day d-1 ending with structure j.\n                long long partition_change_cost = partition_cost_matrix[i][j]; // Cost to transition from structure j to structure i.\n                \n                long long total_cost_through_prev = prev_day_total_cost + current_day_area_cost + partition_change_cost;\n\n                // Update if this path is better.\n                if (best_prev_idx == -1 || total_cost_through_prev < min_prev_total_cost) {\n                    min_prev_total_cost = total_cost_through_prev;\n                    best_prev_idx = j; // Store the index of the optimal previous structure.\n                }\n            }\n            DP[d][i] = min_prev_total_cost;\n            parent[d][i] = best_prev_idx;\n        }\n    }\n\n    // --- Find overall minimum cost and backtrack to determine the optimal structure sequence ---\n    long long min_total_overall_cost = -1;\n    int last_active_idx = -1; // Index in `active_structure_types` for the optimal structure on the last day.\n\n    // Find the minimum cost across all structures on the last day (D-1).\n    for (int i = 0; i < num_active_structures; ++i) {\n        if (last_active_idx == -1 || DP[D - 1][i] < min_total_overall_cost) {\n            min_total_overall_cost = DP[D - 1][i];\n            last_active_idx = i;\n        }\n    }\n\n    // Backtrack using the `parent` array to reconstruct the optimal sequence of structure indices.\n    vector<int> optimal_active_idx_sequence(D);\n    int current_active_idx = last_active_idx;\n    for (int d = D - 1; d >= 0; --d) {\n        optimal_active_idx_sequence[d] = current_active_idx; // Store the optimal structure index for day `d`.\n        if (d > 0) {\n            current_active_idx = parent[d][current_active_idx]; // Move to the parent structure index for the previous day.\n        }\n    }\n\n    // --- Output the rectangles for each day ---\n    // For each day, use the chosen structure and greedily assign reservations to rectangles.\n    for (int d = 0; d < D; ++d) {\n        // Get the chosen structure type for the current day from the optimal sequence.\n        StructureType chosen_s_type = active_structure_types[optimal_active_idx_sequence[d]];\n        const auto& structure_rects = base_rects_map[chosen_s_type]; // Base rectangles for this structure.\n\n        // Sort the base rectangles of the chosen structure by area in descending order.\n        vector<Rect> sorted_base_rects = structure_rects;\n        sort(sorted_base_rects.begin(), sorted_base_rects.end(), [](const Rect& a, const Rect& b) {\n            return a.area > b.area; // Descending order of area.\n        });\n\n        // Get the reservations for day 'd', already sorted by desired area (descending).\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; \n\n        // Determine the final assignment of rectangles for day 'd'.\n        // `current_day_assignments[k]` will store the `Rect` assigned to the original reservation `k`.\n        vector<Rect> current_day_assignments(N); \n        for (int res_rank = 0; res_rank < N; ++res_rank) { // `res_rank` is the rank by area (0 = largest).\n            int original_reservation_k = daily_reservations_sorted[res_rank].second; // Original index of this reservation.\n            \n            // Greedily assign: the `res_rank`-th largest reservation gets the `res_rank`-th largest base rectangle slot.\n            current_day_assignments[original_reservation_k] = sorted_base_rects[res_rank];\n        }\n\n        // Output the assigned rectangles for day 'd' in the order of original reservations (k=0 to N-1).\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = current_day_assignments[k];\n            // Ensure output rectangle is valid. This check is defensive against potential bugs.\n            // The subdivision logic in `generate_grid_structure` should prevent 0-area rects.\n            if (r.x0 >= r.x1 || r.y0 >= r.y1) {\n                // This indicates a problem. In a contest, this might lead to WA.\n                // For debugging, one could print an error or a minimal valid rectangle.\n                // Given the problem context and W=1000, N<=50, a 1x1 rect is always possible.\n                // For submission, we assume the subdivision logic works.\n                // The previous error `0 0 0 0` was due to dummy rects. This is now handled.\n                // If this specific case occurs again, a more complex structure generation strategy is needed.\n            }\n            cout << r.x0 << \" \" << r.y0 << \" \" << r.x1 << \" \" << r.y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global constants and variables for the problem.\n// N, M, K are small enough that long long is not strictly necessary for them,\n// but using it for consistency and to avoid potential issues with larger constraints.\nlong long N_val, M_val, K_val; \nconst long long MOD = 998244353; // The modulus for scoring.\n\n// Structure to hold a state in the beam search.\n// A state includes the current board configuration, the sequence of operations to reach it,\n// and its total score.\nstruct State {\n    vector<vector<long long>> board; // The board configuration for this state.\n    vector<tuple<int, int, int>> operations; // The sequence of operations to reach this state.\n    long long current_score; // The score of this state (sum of board[i][j] % MOD).\n\n    // Operator for comparison in a priority queue.\n    // We want states with higher scores to have higher priority.\n    // std::priority_queue is a max-heap by default, so it will keep the element with the largest value\n    // (based on this operator) at the top.\n    bool operator<(const State& other) const {\n        return current_score < other.current_score;\n    }\n};\n\n/**\n * @brief Calculates the immediate score gain by applying a specific stamp at a given position on a given board.\n * \n * The gain is the sum of (new_cell_value % MOD - old_cell_value % MOD) for all affected cells.\n * This value can be positive, zero, or negative. Only positive gains are considered for extending the search.\n * \n * @param current_board The current board state.\n * @param stamp_idx The index of the stamp to consider (0 to M-1).\n * @param p The top row coordinate on the board where the stamp's (0,0) is placed.\n * @param q The left column coordinate on the board where the stamp's (0,0) is placed.\n * @param stamps The collection of all stamps.\n * @return The total score gain (sum of modulo differences) for this operation.\n */\nlong long calculate_gain_for_state(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    long long current_gain_sum = 0; // Accumulates the score change.\n    \n    // Iterate over the 3x3 squares of the stamp.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int r = p + i; // Corresponding row on the board.\n            int c = q + j; // Corresponding column on the board.\n\n            // The current score contribution of the cell (r, c) to the total score.\n            // Since input values are non-negative, direct modulo is sufficient.\n            long long current_score_contrib = current_board[r][c] % MOD;\n            \n            // The value from the stamp at relative position (i, j).\n            long long stamp_val = stamps[stamp_idx][i][j];\n            \n            // The new total value on the board cell (r, c) after applying the stamp.\n            long long new_board_val = current_board[r][c] + stamp_val;\n            \n            // The new score contribution of the cell (r, c) after the operation.\n            long long new_score_contrib = new_board_val % MOD;\n            \n            // The change in score for this specific cell.\n            long long delta = new_score_contrib - current_score_contrib;\n            \n            current_gain_sum += delta; // Add the cell's score change to the total gain.\n        }\n    }\n    return current_gain_sum;\n}\n\n/**\n * @brief Applies a stamp to a board and returns the new board state.\n * \n * This function creates a copy of the board and applies the stamp values to it.\n * \n * @param current_board The board to apply the stamp to.\n * @param stamp_idx The index of the stamp to apply.\n * @param p The top row coordinate for placement.\n * @param q The left column coordinate for placement.\n * @param stamps The collection of all stamps.\n * @return A new board with the stamp applied.\n */\nvector<vector<long long>> apply_stamp_to_board(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    vector<vector<long long>> next_board = current_board; // Copy the board to avoid modifying the original state.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            next_board[p + i][q + j] += stamps[stamp_idx][i][j];\n        }\n    }\n    return next_board;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read board dimensions (N) and number of stamps (M), and max operations (K).\n    cin >> N_val >> M_val >> K_val;\n\n    // Initialize the board with the given initial values and calculate initial score.\n    vector<vector<long long>> initial_board(N_val, vector<long long>(N_val));\n    long long initial_score = 0;\n    for (int i = 0; i < N_val; ++i) {\n        for (int j = 0; j < N_val; ++j) {\n            cin >> initial_board[i][j];\n            // Calculate initial score: sum of (value % MOD).\n            initial_score = (initial_score + (initial_board[i][j] % MOD)) % MOD;\n        }\n    }\n\n    // Read the values for all M stamps.\n    vector<vector<vector<long long>>> stamps(M_val, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M_val; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n\n    // --- Beam Search Strategy ---\n    // Beam search explores multiple promising states simultaneously to escape local optima.\n    // BEAM_WIDTH determines how many of the best states are kept at each step.\n    // Adjusted BEAM_WIDTH to 7. This value often provides a good balance between exploration\n    // and computational cost, aiming for more consistent score improvements.\n    const int BEAM_WIDTH = 7; \n    \n    // Priority queue to store states for the current step. `std::priority_queue` is a max-heap by default,\n    // so states with higher scores will be at the top.\n    priority_queue<State> pq;\n\n    // Create the initial state and push it into the priority queue.\n    State initial_state;\n    initial_state.board = initial_board;\n    initial_state.current_score = initial_score;\n    pq.push(initial_state);\n\n    // Track the best overall state found throughout the search.\n    State best_overall_state = initial_state;\n\n    // Perform beam search for up to K_val steps. Each step represents applying one more operation.\n    for (int k = 0; k < K_val; ++k) {\n        // Store candidate next states generated from the current step's states.\n        vector<State> candidates;\n\n        // Process up to BEAM_WIDTH states from the current priority queue.\n        // This is the number of states we will expand at this depth.\n        int states_to_process = min((int)pq.size(), BEAM_WIDTH);\n        \n        // If no states are left to process (pq is empty), break the loop.\n        if (states_to_process == 0) break;\n\n        // Expand each of the top 'states_to_process' states.\n        for(int i = 0; i < states_to_process; ++i) {\n            State current_state = pq.top();\n            pq.pop();\n\n            // Explore all possible next operations (stamp type and position) from this state.\n            for (int m = 0; m < M_val; ++m) {\n                for (int p = 0; p <= N_val - 3; ++p) { // Possible top-left row for stamp placement.\n                    for (int q = 0; q <= N_val - 3; ++q) { // Possible top-left column for stamp placement.\n                        \n                        // Calculate the immediate score gain from this potential operation.\n                        long long gain = calculate_gain_for_state(current_state.board, m, p, q, stamps);\n\n                        // Only consider operations that strictly increase the score.\n                        // This ensures we always move towards a better score and avoid unnecessary operations.\n                        // If gain is 0 or negative, it doesn't improve the score.\n                        if (gain > 0) {\n                            // Create a new state by applying the operation.\n                            State next_state;\n                            next_state.board = apply_stamp_to_board(current_state.board, m, p, q, stamps);\n                            next_state.operations = current_state.operations; // Copy operations from current state.\n                            next_state.operations.emplace_back(m, p, q); // Add the new operation.\n                            \n                            // Update the score: current score + gain. The gain is already the sum of modulo differences.\n                            // This summation is safe as both current_score and gain fit within long long.\n                            next_state.current_score = current_state.current_score + gain;\n                            \n                            // Add this new state to the list of candidates for the next step.\n                            candidates.push_back(next_state);\n\n                            // Update the best overall state found so far if this new state is better.\n                            // This ensures we keep track of the global best, even if it's not in the current beam.\n                            if (next_state.current_score > best_overall_state.current_score) {\n                                best_overall_state = next_state;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If no operations resulted in a positive gain from any of the processed states,\n        // it means we cannot improve the score further with positive gain operations.\n        // We can stop the search early.\n        if (candidates.empty()) {\n            break;\n        }\n\n        // Sort the generated candidates by their score in descending order.\n        // This is necessary to select the top BEAM_WIDTH candidates for the next iteration.\n        sort(candidates.begin(), candidates.end(), [](const State& a, const State& b){\n            return a.current_score > b.current_score;\n        });\n\n        // Push the top BEAM_WIDTH candidates into the priority queue for the next iteration.\n        // This prunes the search space, keeping only the most promising states for further exploration.\n        for(int i = 0; i < min((int)candidates.size(), BEAM_WIDTH); ++i) {\n            pq.push(candidates[i]);\n        }\n    }\n\n    // --- Output ---\n    // The 'best_overall_state' now holds the sequence of operations that yielded the highest score\n    // found during the beam search.\n    cout << best_overall_state.operations.size() << endl;\n    for (const auto& op : best_overall_state.operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << endl;\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int MAX_TURNS = 10000;\nint N;\n\n// Grid state\nvector<vector<int>> grid; // container ID, -1 if empty\nvector<vector<int>> crane_id_at; // crane ID, -1 if empty\n\n// Crane state\nstruct Crane {\n    int id;\n    pair<int, int> pos;\n    int holding_container_id; // -1 if not holding\n    bool is_large;\n    int base_priority; // For task assignment logic\n};\nvector<Crane> cranes;\n\n// Container state is implicitly managed by grid and crane_holding_id\n\n// Receiving Gate state\nvector<int> receiving_gate_next_container_idx; // For each receiving gate i, index into A[i]\n\n// Dispatch Gate state\nvector<int> dispatch_gate_expected_container; // For each dispatch gate i, the ID of the next container to be dispatched. -1 if all dispatched.\n\n// Container to Target Gate mapping\nvector<int> container_target_gate;\n\n// Temporary storage cells\nvector<pair<int, int>> temp_storage_cells;\n\n// Helper to check if a cell is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Helper to get target dispatch gate for a container\nint get_target_gate(int container_id) {\n    if (container_id < 0) return -1; // Should not happen for valid containers\n    return container_id / N;\n}\n\n// Greedy best-step pathfinding to target_pos\npair<int, int> get_next_step(pair<int, int> current_pos, pair<int, int> target_pos) {\n    if (current_pos == target_pos) return current_pos;\n\n    int r = current_pos.first;\n    int c = current_pos.second;\n    int tr = target_pos.first;\n    int tc = target_pos.second;\n\n    int dr = tr - r;\n    int dc = tc - c;\n\n    // Prioritize moving vertically if difference is larger or equal, otherwise horizontally.\n    if (abs(dr) >= abs(dc)) { \n        if (dr > 0) return {r + 1, c}; // D\n        else if (dr < 0) return {r - 1, c}; // U\n    }\n    // If vertical difference is smaller or zero, prioritize horizontal movement.\n    if (abs(dc) > abs(dr)) {\n        if (dc > 0) return {r, c + 1}; // R\n        else if (dc < 0) return {r, c - 1}; // L\n    }\n    \n    // Fallback: This should ideally not be reached if current_pos != target_pos.\n    // It means dr=0 and dc=0, which is handled by the initial check.\n    return current_pos; \n}\n\n// Crane Task types for priority\nenum TaskType {\n    WAIT,\n    PICKUP_REC,       // Pickup from Receiving Gate\n    PICKUP_TEMP,      // Pickup from Temporary Storage\n    STORE_CONTAINER,  // Store container in Temporary Storage\n    DELIVER_TO_GATE   // Deliver container to Dispatch Gate\n};\n\n// Structure to hold a crane's task and its priority\nstruct CraneTask {\n    TaskType type;\n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n};\n\n// Function to determine the crane's highest priority task\nCraneTask determine_crane_task(int crane_idx) {\n    Crane& crane = cranes[crane_idx];\n    pair<int, int> current_pos = crane.pos;\n\n    // Assign base priority. Large crane has highest base priority.\n    // Small cranes have priority decreasing with their initial index.\n    // Adjusted priorities for better separation and SC distinctiveness.\n    int current_base_priority = crane.is_large ? 1000 : 100 * (N - 1 - crane_idx); \n\n    // Task 4: DELIVER_TO_GATE\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n        \n        // Check if the container is the *next expected* for its target dispatch gate\n        if (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]) {\n            pair<int, int> deliver_pos = {target_gate, N - 1};\n            // Highest priority task: DELIVER_TO_GATE\n            return {DELIVER_TO_GATE, deliver_pos, current_base_priority + 100}; // Very high priority\n        }\n    }\n\n    // Task 1 & 2: PICKUP_REQ (from Receiving Gate or Temp Storage) for required containers\n    if (crane.holding_container_id == -1) { // Only pick up if not holding anything\n        // Check for required containers at dispatch gates\n        for (int i = 0; i < N; ++i) { // Iterate through dispatch gates\n            int expected_container_id = dispatch_gate_expected_container[i];\n            if (expected_container_id != -1) { // If a container is still expected for this gate\n                // Check if this container belongs to gate i (redundant check but good for clarity)\n                if (get_target_gate(expected_container_id) == i) {\n                    // Find its current location\n                    // Check Receiving Gates (Task 1: PICKUP_REC)\n                    if (grid[i][0] == expected_container_id) {\n                        // High priority: PICKUP_REC for required container\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 80}; // High priority\n                    }\n                    // Check Temporary Storage Cells (Task 2: PICKUP_TEMP)\n                    for (const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == expected_container_id) {\n                            // High priority: PICKUP_TEMP for required container\n                            return {PICKUP_TEMP, cell, current_base_priority + 70}; // High priority\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 3: STORE_CONTAINER\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n\n        // If the container is NOT the next one needed for its dispatch gate, and we have somewhere to store it.\n        bool is_needed_now = (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]);\n        if (!is_needed_now) {\n            pair<int, int> temp_storage_target = {-1, -1};\n            for (const auto& cell : temp_storage_cells) {\n                // Cell must be empty (no container, no crane)\n                if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                    temp_storage_target = cell;\n                    break;\n                }\n            }\n            if (temp_storage_target != make_pair(-1, -1)) {\n                // Medium priority: STORE_CONTAINER\n                return {STORE_CONTAINER, temp_storage_target, current_base_priority + 50}; // Medium priority\n            }\n        }\n    }\n    \n    // Task 1 (low priority): Proactive fetch from Receiving Gates\n    // Only if not holding a container and not already going to pick up a *required* container\n    if (crane.holding_container_id == -1) {\n        for (int i = 0; i < N; ++i) { // Iterate through receiving gates\n            if (receiving_gate_next_container_idx[i] < N) { // If containers are still arriving\n                // Check if cell (i,0) has an arrived container and is not occupied by a crane\n                if (grid[i][0] != -1 && crane_id_at[i][0] == -1) { \n                    // Check if there's an available temporary storage cell to move it to\n                    pair<int, int> temp_storage_target = {-1, -1};\n                    for(const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n                            temp_storage_target = cell;\n                            break;\n                        }\n                    }\n                    if (temp_storage_target != make_pair(-1, -1)) {\n                        // Low priority: PICKUP_REC (proactive)\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 20}; // Low priority\n                    }\n                }\n            }\n        }\n    }\n\n    // Task 0: WAIT\n    return {WAIT, current_pos, current_base_priority}; // Default to WAIT\n}\n\n// Structure to hold a crane's requested move for collision resolution\nstruct MoveRequest {\n    int crane_idx;\n    // Renamed 'type' to 'task_kind' to avoid potential compiler issues with reserved names or conflicts.\n    TaskType task_kind; \n    pair<int, int> target_pos;\n    int priority; // Higher value = higher priority\n\n    bool operator<(const MoveRequest& other) const {\n        // Sort by priority descending. If priorities are equal, sort by crane_idx ascending\n        // to ensure deterministic behavior.\n        if (priority != other.priority) {\n            return priority > other.priority;\n        }\n        return crane_idx < other.crane_idx; \n    }\n};\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    grid.assign(N, vector<int>(N, -1));\n    crane_id_at.assign(N, vector<int>(N, -1));\n    receiving_gate_next_container_idx.assign(N, 0);\n    dispatch_gate_expected_container.assign(N, -1); // Initialize with -1\n\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n        }\n    }\n\n    // Initialize container_target_gate mapping\n    container_target_gate.resize(N * N);\n    for (int i = 0; i < N * N; ++i) {\n        container_target_gate[i] = get_target_gate(i);\n    }\n\n    // Initialize dispatch gate expected containers\n    for (int i = 0; i < N; ++i) {\n        dispatch_gate_expected_container[i] = N * i;\n    }\n\n    // Initialize cranes\n    cranes.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].id = i;\n        cranes[i].pos = {i, 0};\n        cranes[i].holding_container_id = -1;\n        cranes[i].is_large = (i == 0);\n        // Base priority: LC highest, SCs decreasing.\n        cranes[i].base_priority = (i == 0) ? 1000 : 100 * (N - 1 - i); \n\n        crane_id_at[i][0] = i; // Place cranes on grid\n    }\n\n    // Initialize temporary storage cells. Aim for inner cells, away from edges.\n    // Prioritize cells further from receiving/dispatch gates.\n    for (int r = 1; r < N - 1; ++r) {\n        for (int c = 1; c < N - 1; ++c) {\n            temp_storage_cells.push_back({r, c});\n        }\n    }\n    // If N is small (e.g., N=1, N=2), the inner grid might not exist. Add cells from other rows/columns if available.\n    // Add cells on inner columns (not edges) first.\n    if (temp_storage_cells.empty() && N > 1) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 1; c < N - 1; ++c) { // Cells not on the left edge (receiving gates)\n                temp_storage_cells.push_back({r, c});\n            }\n        }\n    }\n    // Add remaining cells if still empty (e.g., N=1 or N=2).\n    if (temp_storage_cells.empty() && N > 1) { // Avoid adding (0,0) which is LC start\n         for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Avoid receiving gates (c=0), dispatch gates (c=N-1), and LC start position for initial temp cells\n                // Prefer inner cells (c=1 to N-2).\n                if (c > 0 && c < N-1) { \n                     temp_storage_cells.push_back({r,c});\n                }\n            }\n        }\n    }\n    // Sort temp storage cells by distance from LC start {0,0} to potentially prioritize closer ones first for initial storage.\n    sort(temp_storage_cells.begin(), temp_storage_cells.end(), [&](const pair<int, int>& a, const pair<int, int>& b) {\n        int dist_a = abs(a.first - 0) + abs(a.second - 0);\n        int dist_b = abs(b.first - 0) + abs(b.second - 0);\n        return dist_a < dist_b;\n    });\n\n\n    vector<string> output_ops(N, \"\");\n\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        // Step 1: Container Arrival\n        for (int i = 0; i < N; ++i) { // For each receiving gate row i\n            if (receiving_gate_next_container_idx[i] < N) {\n                // Place container if receiving gate cell (i,0) is empty (no container, no crane)\n                if (grid[i][0] == -1 && crane_id_at[i][0] == -1) {\n                    int container_id = A[i][receiving_gate_next_container_idx[i]];\n                    grid[i][0] = container_id;\n                    receiving_gate_next_container_idx[i]++;\n                }\n            }\n        }\n\n        // Step 2: Crane Actions\n        vector<MoveRequest> requests;\n        \n        // Determine desired tasks for all cranes\n        for (int i = 0; i < N; ++i) {\n            CraneTask task = determine_crane_task(i);\n            requests.push_back({i, task.type, task.target_pos, task.priority});\n        }\n\n        // Sort requests by priority (highest first). The operator< in MoveRequest handles this.\n        sort(requests.begin(), requests.end());\n\n        // `next_crane_id_at` stores the state of crane positions *after* all actions in this turn are resolved.\n        vector<vector<int>> next_crane_id_at = crane_id_at; \n        \n        // Keep track of the final state for each crane after its action for this turn.\n        vector<pair<int, int>> final_crane_pos(N);\n        vector<int> final_crane_holding(N);\n        vector<char> final_crane_action(N);\n        vector<bool> crane_action_committed(N, false); // Track if crane committed to an action/move\n\n        // Initialize with current state, assuming no action initially.\n        for(int i=0; i<N; ++i) {\n            final_crane_pos[i] = cranes[i].pos;\n            final_crane_holding[i] = cranes[i].holding_container_id;\n            final_crane_action[i] = '.';\n        }\n\n        // Iterate through sorted requests to resolve conflicts.\n        for (const auto& req : requests) {\n            int k = req.crane_idx; // Current crane index\n\n            // If crane k has already committed to an action (e.g., due to higher priority or being part of a prior committed move), skip.\n            if (crane_action_committed[k]) continue;\n\n            Crane& current_crane_state = cranes[k]; // Reference to the actual crane object\n            pair<int, int> current_pos = current_crane_state.pos; // Its position BEFORE this turn's action\n            \n            // Determine the intended next position and action based on the request.\n            pair<int, int> intended_next_pos = current_pos;\n            char intended_action_char = '.';\n            bool action_possible = true;\n\n            // Assign intended action based on task type\n            if (req.task_kind == DELIVER_TO_GATE || req.task_kind == STORE_CONTAINER) { // Tasks involving releasing a container\n                if (current_pos == req.target_pos) { // Already at target for Q action\n                    intended_action_char = 'Q';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to eventually drop\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target (already there or blocked by logic)\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else if (req.task_kind == PICKUP_REC || req.task_kind == PICKUP_TEMP) { // Tasks involving picking up a container\n                if (current_pos == req.target_pos) { // Already at target for P action\n                    intended_action_char = 'P';\n                    intended_next_pos = current_pos; // Stay put\n                } else { // Need to move towards target to pick up\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target\n                        intended_action_char = '.'; // Stay put\n                        intended_next_pos = current_pos;\n                    }\n                }\n            } else { // WAIT or other task not requiring specific movement now\n                intended_action_char = '.';\n                intended_next_pos = current_pos;\n            }\n\n            // --- Collision and Constraint Checking ---\n            \n            // 1. Basic validity of destination\n            if (!is_valid(intended_next_pos.first, intended_next_pos.second)) {\n                action_possible = false; // Cannot move out of bounds\n            }\n\n            // 2. Check for crane-crane conflicts at destination (intended_next_pos)\n            // This check depends on the state *after* higher priority cranes have committed their moves.\n            // `next_crane_id_at` stores committed crane positions for the next turn.\n            if (action_possible && intended_next_pos != current_pos && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1) {\n                // Destination is occupied by another crane. Since `next_crane_id_at` is updated progressively,\n                // if it's occupied by `occupying_crane_id` != `k`, it means `occupying_crane_id` has higher or equal priority and has already committed to being there.\n                // Thus, crane `k` cannot move to `intended_next_pos`.\n                action_possible = false; \n            }\n\n            // 3. Small crane carrying container to a cell with a container (not allowed)\n            if (action_possible && !current_crane_state.is_large && current_crane_state.holding_container_id != -1) {\n                if (grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Small crane carrying cannot move to cell with a container\n                }\n            }\n            \n            // 4. If intended action is Pick/Drop, check if the cell itself is valid for the action\n            if (action_possible && (intended_action_char == 'P' || intended_action_char == 'Q')) {\n                // Cell must contain the container for 'P', and be empty for 'Q' (except for the crane)\n                // Check if the cell has a container if trying to pick up\n                if (intended_action_char == 'P' && grid[current_pos.first][current_pos.second] == -1) {\n                    action_possible = false; // Cannot pick up from empty cell\n                }\n                // Check if the cell is already occupied by a container if trying to drop\n                // This check must consider the state *after* crane movement, so check `grid` at `intended_next_pos`.\n                if (intended_action_char == 'Q' && grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Cannot drop into an occupied cell\n                }\n                // If attempting P/Q, the destination cell must not be occupied by another crane.\n                // This is already handled by point 2 for movement, but P/Q is an action at the *current* pos or *intended_next_pos*.\n                // If action is 'P', current_pos = intended_next_pos.\n                // If action is 'Q', intended_next_pos is the target.\n                if (next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1 && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != k) {\n                     action_possible = false; // Cannot P/Q if destination cell occupied by other crane\n                }\n            }\n\n\n            if (action_possible) {\n                // Crane k successfully commits to its action and move.\n                final_crane_action[k] = intended_action_char;\n                final_crane_pos[k] = intended_next_pos;\n                crane_action_committed[k] = true;\n\n                // Update crane's holding status and grid state if 'P' or 'Q'\n                if (intended_action_char == 'P') {\n                    // Crane picks up container from its current cell.\n                    int container_id = grid[current_pos.first][current_pos.second]; \n                    grid[current_pos.first][current_pos.second] = -1; // Remove container from cell\n                    final_crane_holding[k] = container_id; // Crane now holds it\n                } else if (intended_action_char == 'Q') {\n                    // Crane drops container at its intended next position.\n                    int container_id = current_crane_state.holding_container_id;\n                    grid[intended_next_pos.first][intended_next_pos.second] = container_id; // Place container in destination cell\n                    final_crane_holding[k] = -1; // Crane no longer holds it\n                }\n                \n                // Update `next_crane_id_at` for collision detection for *subsequent* (lower priority) cranes in this turn.\n                // Mark old position as empty, new position as occupied by crane k.\n                if (current_pos != intended_next_pos) { // Only update if crane actually moved\n                    next_crane_id_at[current_pos.first][current_pos.second] = -1; \n                    next_crane_id_at[intended_next_pos.first][intended_next_pos.second] = k;\n                } else {\n                    // If crane stayed put (action '.' or 'P'/'Q' at same spot), its position in next_crane_id_at is already correct from initialization.\n                    // If P/Q happened at current_pos, it still occupies current_pos.\n                }\n            } else {\n                // Crane k is blocked or action is impossible. It stays put and does nothing.\n                final_crane_action[k] = '.';\n                final_crane_pos[k] = current_pos; // Stays at current position\n                final_crane_holding[k] = current_crane_state.holding_container_id; // Holding status unchanged\n                // crane_action_committed[k] remains false. Its position in next_crane_id_at is unchanged.\n            }\n        }\n        \n        // Apply the final state changes for all cranes after conflict resolution.\n        for(int i=0; i<N; ++i) {\n            cranes[i].pos = final_crane_pos[i];\n            cranes[i].holding_container_id = final_crane_holding[i];\n            output_ops[i] += final_crane_action[i];\n        }\n        // Update crane_id_at to reflect the final positions for the START of the next turn.\n        crane_id_at = next_crane_id_at; \n\n        // Step 3: Dispatch\n        for (int i = 0; i < N; ++i) { // For each dispatch gate row i\n            if (dispatch_gate_expected_container[i] != -1 && grid[i][N - 1] != -1) {\n                if (grid[i][N - 1] == dispatch_gate_expected_container[i]) {\n                    // Dispatch container\n                    grid[i][N - 1] = -1; // Remove from dispatch gate\n                    \n                    // Update expected container for this dispatch gate\n                    dispatch_gate_expected_container[i]++;\n                    if (dispatch_gate_expected_container[i] >= N * (i + 1)) {\n                        dispatch_gate_expected_container[i] = -1; // All containers for this gate dispatched\n                    }\n                }\n            }\n        }\n        \n        // Optional: Early exit condition if all containers are dispatched.\n        // This might save time if the simulation finishes before MAX_TURNS.\n        bool all_dispatched = true;\n        for(int i=0; i<N; ++i) {\n            if (dispatch_gate_expected_container[i] != -1) {\n                all_dispatched = false;\n                break;\n            }\n        }\n        if (all_dispatched && turn > 0) { // Check if all were dispatched in this turn or previous\n             // Break loop, padding will handle the rest.\n             // However, the problem states output length must be between 1 and 10000.\n             // So, we must ensure padding up to MAX_TURNS if we break early.\n             // The padding at the end handles this.\n             break; \n        }\n    }\n\n    // Pad output strings with '.' if they are shorter than MAX_TURNS\n    for (int i = 0; i < N; ++i) {\n        while (output_ops[i].length() < MAX_TURNS) {\n            output_ops[i] += '.';\n        }\n    }\n\n    for (int i = 0; i < N; ++i) {\n        cout << output_ops[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <vector> // Explicitly include vector\n\nusing namespace std;\n\nint N;\n// current_height: Stores the remaining height of soil in each grid cell.\n// This grid is modified as soil is loaded onto the truck or unloaded from it.\nvector<vector<int>> current_height;\n// current_pos: Stores the (row, column) coordinates of the dump truck.\npair<int, int> current_pos;\n// truck_load: Stores the current amount of soil loaded onto the dump truck.\nlong long truck_load;\n// operations: A list to store the sequence of commands to be output.\nvector<string> operations;\n\n// CHUNK_SIZE: Defines the maximum amount of soil transferred in a single load or unload operation.\n// We'll use a moderate value (20). The key is how it's applied in an interleaved strategy.\nconst long long CHUNK_SIZE = 20; \n\n// Adds a given operation string to the `operations` list.\nvoid add_op(const string& op) {\n    operations.push_back(op);\n}\n\n// Adds a load ('+') or unload ('-') operation.\n// 'd' is the amount of soil transferred. Ensures d > 0 as per problem statement.\nvoid add_load_unload(char type, long long d) {\n    if (d <= 0) return; // Do not add operations with zero or negative amount.\n    add_op(string(1, type) + to_string(d));\n}\n\n// Moves the dump truck from its `current_pos` to the target cell (`target_r`, `target_c`).\n// It appends the necessary 'U', 'D', 'L', 'R' operations to the `operations` list\n// and updates `current_pos`. This function is crucial for calculating movement cost.\nvoid move_to(int target_r, int target_c) {\n    // Vertical movement: Up or Down\n    while (current_pos.first < target_r) {\n        add_op(\"D\");\n        current_pos.first++;\n    }\n    while (current_pos.first > target_r) {\n        add_op(\"U\");\n        current_pos.first--;\n    }\n    // Horizontal movement: Left or Right\n    while (current_pos.second < target_c) {\n        add_op(\"R\");\n        current_pos.second++;\n    }\n    while (current_pos.second > target_c) {\n        add_op(\"L\");\n        current_pos.second--;\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the grid size N.\n    cin >> N;\n\n    // Initialize the current_height grid with input values.\n    current_height.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> current_height[i][j];\n        }\n    }\n\n    // Initialize the truck's starting position and load.\n    current_pos = {0, 0};\n    truck_load = 0;\n\n    // Define a snake-like traversal path. This path visits every cell exactly once\n    // in a systematic manner (row by row, alternating direction).\n    vector<pair<int, int>> snake_path;\n    snake_path.reserve(N * N); // Reserve memory for efficiency.\n    for (int r = 0; r < N; ++r) {\n        if (r % 2 == 0) { // Even rows: traverse left to right.\n            for (int c = 0; c < N; ++c) {\n                snake_path.push_back({r, c});\n            }\n        } else { // Odd rows: traverse right to left.\n            for (int c = N - 1; c >= 0; --c) {\n                snake_path.push_back({r, c});\n            }\n        }\n    }\n\n    // --- Single Pass: Interleaved Loading and Unloading Strategy ---\n    // Iterate through the snake path. For each cell, perform both loading (if positive height)\n    // and unloading (if negative height and truck has load). This aims to keep the truck's\n    // load `d` as low as possible during movements, thereby reducing the `100+d` move cost.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        // Move the truck to the current cell. The cost of this move depends on `truck_load`\n        // *before* operations at this cell. Interleaving aims to reduce this `truck_load`.\n        move_to(r, c);\n\n        // --- Perform operations at the current cell ---\n\n        // 1. Load soil if the cell has positive height.\n        // Load soil in chunks up to CHUNK_SIZE until the cell's height becomes 0.\n        // This loop might execute multiple load operations at the same cell without movement.\n        while (current_height[r][c] > 0) {\n            // Determine the amount to load: minimum of remaining height in cell and CHUNK_SIZE.\n            long long amount_to_load = min((long long)current_height[r][c], CHUNK_SIZE);\n            add_load_unload('+', amount_to_load); // Add load operation.\n            truck_load += amount_to_load;          // Update truck's current load.\n            current_height[r][c] -= amount_to_load; // Decrease cell's height.\n        }\n\n        // 2. Unload soil if the cell has negative height AND the truck has soil to unload.\n        // Unload soil in chunks up to CHUNK_SIZE until the cell's height becomes 0\n        // or the truck becomes empty. This happens immediately after potential loading,\n        // or if there was already soil on the truck from previous cells.\n        while (current_height[r][c] < 0 && truck_load > 0) {\n            long long needed = -current_height[r][c]; // Amount of soil this cell requires.\n            // Determine amount to unload: minimum of needed soil, current truck load, and CHUNK_SIZE.\n            long long amount_to_unload = min({needed, truck_load, CHUNK_SIZE});\n            add_load_unload('-', amount_to_unload); // Add unload operation.\n            truck_load -= amount_to_unload;        // Update truck's current load.\n            current_height[r][c] += amount_to_unload; // Increase cell's height.\n        }\n    }\n    \n    // The problem guarantees that the sum of initial heights is 0.\n    // Therefore, by visiting all cells and performing the interleaved loading/unloading,\n    // all soil collected from positive-height cells must have been distributed to\n    // negative-height cells. As a result, at the end of this single pass,\n    // all `current_height` values should be 0, and `truck_load` should also be 0.\n    // No additional cleanup passes are needed if the logic is correct.\n\n    // Output all the generated operations, one per line.\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <numeric> // Not strictly necessary as sum is manual, but good practice to include if using numeric algorithms.\n#include <algorithm> // For std::sort\n\n// Use long long for sums to avoid potential overflow.\n// With M=15 and max value 100 per component, the max sum for a single seed is 15*100 = 1500,\n// which fits in a 32-bit integer. However, using `long long` is safer practice and has no performance penalty here.\nusing ll = long long;\n\n// Structure to hold seed information: its identifier, evaluation vector, and sum of values.\nstruct Seed {\n    int id; // Identifier of the seed within the current generation (0 to seed_count-1).\n    std::vector<int> evaluation_vector;\n    ll sum_v;\n\n    // Custom comparison operator for sorting seeds by sum_v in descending order.\n    // std::sort uses operator< to sort in ascending order. By defining it such that\n    // `a < b` if `a.sum_v > b.sum_v`, we achieve descending order sorting.\n    bool operator<(const Seed& other) const {\n        return sum_v > other.sum_v;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // Disables synchronization with C stdio and unties cin from cout for faster I/O.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, T;\n    std::cin >> N >> M >> T;\n\n    // Total number of seeds in each generation.\n    // For N=6, this is 2 * 6 * (6 - 1) = 2 * 6 * 5 = 60 seeds.\n    int seed_count = 2 * N * (N - 1);\n\n    // Vector to hold the current generation of seeds.\n    std::vector<Seed> current_seeds(seed_count);\n\n    // Read initial seeds. Their initial indices are implicitly 0, 1, ..., seed_count-1.\n    for (int i = 0; i < seed_count; ++i) {\n        current_seeds[i].id = i; // Assign initial ID for this seed.\n        current_seeds[i].evaluation_vector.resize(M);\n        ll current_sum = 0;\n        for (int j = 0; j < M; ++j) {\n            std::cin >> current_seeds[i].evaluation_vector[j];\n            current_sum += current_seeds[i].evaluation_vector[j];\n        }\n        current_seeds[i].sum_v = current_sum;\n    }\n\n    // Main loop for T turns of the operation.\n    for (int t = 0; t < T; ++t) {\n        // 1. Sort the current seeds based on their sum_v in descending order.\n        // The `std::sort` function uses the `operator<` defined in the `Seed` struct.\n        std::sort(current_seeds.begin(), current_seeds.end());\n\n        // 2. Select the top N*N seeds for planting.\n        // These are the first N*N seeds in the sorted `current_seeds` vector.\n        // We need to output their `id`s arranged in the N*N grid.\n        std::vector<std::vector<int>> A(N, std::vector<int>(N));\n        \n        // Assign selected seeds to grid cells in row-major order.\n        // The seed placed at A[i][j] is the (i*N + j)-th best seed from the sorted list.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                // `current_seeds[i * N + j]` refers to the Seed struct which is the (i*N + j)-th best.\n                // Its `id` field holds the identifier of this seed within the current generation.\n                A[i][j] = current_seeds[i * N + j].id;\n            }\n        }\n\n        // 3. Output the grid assignment to standard output.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                std::cout << A[i][j] << (j == N - 1 ? \"\" : \" \"); // Space separated values, no space after last element in a row.\n            }\n            std::cout << std::endl; // Newline after each row.\n        }\n        std::cout.flush(); // Ensure the output is sent immediately to the judge.\n\n        // 4. Read the evaluation vectors of the newly generated seeds for the next generation.\n        std::vector<Seed> next_seeds(seed_count);\n        for (int i = 0; i < seed_count; ++i) {\n            // Assign new sequential IDs (0 to seed_count-1) for the seeds in the next generation.\n            next_seeds[i].id = i; \n            next_seeds[i].evaluation_vector.resize(M);\n            ll current_sum = 0;\n            for (int j = 0; j < M; ++j) {\n                std::cin >> next_seeds[i].evaluation_vector[j];\n                current_sum += next_seeds[i].evaluation_vector[j];\n            }\n            next_seeds[i].sum_v = current_sum;\n        }\n\n        // 5. Replace the current seeds with the newly generated ones.\n        // `std::move` is used for efficiency, as it transfers ownership of the\n        // `next_seeds` vector's internal buffer to `current_seeds` without copying elements.\n        current_seeds = std::move(next_seeds);\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <numeric> // For std::iota\n\n// Global variables for grid and arm parameters\nint N_GRID, M_TAKOYAKI, V_ARM;\n\n// Structure for 2D points\nstruct Point {\n    int r, c;\n    // Equality operators for comparisons\n    bool operator==(const Point& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Manhattan distance for grid movement cost\nint manhattan_distance(Point p1, Point p2) {\n    return std::abs(p1.r - p2.r) + std::abs(p1.c - p2.c);\n}\n\n// --- Arm Design Parameters ---\nint V_prime; // Actual number of vertices in the arm (<= V_ARM)\nstd::vector<int> parent_map; // parent_map[i] is parent of vertex i+1 (0-indexed for edge array)\nstd::vector<int> edge_lengths; // edge_lengths[i] is length of edge connected to vertex i+1\nstd::vector<int> edge_orientations; // Current orientation of edges: 0:R(0,+1), 1:D(+1,0), 2:L(0,-1), 3:U(-1,0)\n\nPoint root_pos; // Current position of the arm's root\nstd::vector<Point> vertex_pos; // Stores current positions of all arm vertices\nstd::vector<int> fingertip_vertex_ids; // Vertex IDs that are fingertips\nstd::vector<int> joint_vertex_ids; // Vertex IDs that are joints (internal nodes, can rotate subtrees)\n\n// Direction vectors for R, D, L, U\nint dr[] = {0, 1, 0, -1}; // Corresponds to orientations 0, 1, 2, 3\nint dc[] = {1, 0, -1, 0}; // Corresponds to orientations 0, 1, 2, 3\n\n// Function to calculate the positions of all vertices based on root_pos and edge_orientations\nvoid calculate_vertex_positions() {\n    vertex_pos.assign(V_prime, {0, 0});\n    vertex_pos[0] = root_pos;\n\n    // Use BFS-like approach to calculate positions layer by layer\n    // For a tree, we can use a queue or simply iterate based on parent-child relationships.\n    // Let's build adjacency list for easier traversal.\n    std::vector<std::vector<std::pair<int, int>>> adj(V_prime); // {child_vertex_id, edge_index}\n    std::vector<int> edge_idx_for_child(V_prime, -1); // edge_idx_for_child[v] gives index for edge (p,v)\n\n    for (int i = 0; i < V_prime - 1; ++i) {\n        int p = parent_map[i];\n        int child = i + 1; // Vertex ID of child in path graph\n        adj[p].push_back({child, i});\n        edge_idx_for_child[child] = i;\n    }\n\n    std::vector<int> q;\n    q.push_back(0);\n    std::vector<bool> visited(V_prime, false);\n    visited[0] = true;\n\n    int head = 0;\n    while(head < q.size()) {\n        int u = q[head++];\n        \n        // Iterate through children of u\n        for (auto& edge_info : adj[u]) {\n            int v = edge_info.first;\n            int edge_idx = edge_info.second;\n\n            if (!visited[v]) {\n                int orientation = edge_orientations[edge_idx];\n                int length = edge_lengths[edge_idx];\n                \n                vertex_pos[v].r = vertex_pos[u].r + dr[orientation] * length;\n                vertex_pos[v].c = vertex_pos[u].c + dc[orientation] * length;\n                \n                q.push_back(v);\n                visited[v] = true;\n            }\n        }\n    }\n}\n\n// --- Takoyaki and Target Management ---\nstruct Takoyaki {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_taken; // Whether this takoyaki is currently held by a fingertip\n};\nstruct Target {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_filled; // Whether this target square is occupied by a takoyaki\n};\n\nstd::vector<Takoyaki> takoyaki_list;\nstd::vector<Target> target_list;\n\n// --- Fingertip State Management ---\nstruct Fingertip {\n    int vertex_id; // The vertex ID of this fingertip in the arm\n    bool is_holding; // True if currently holding a takoyaki\n    int holding_takoyaki_idx; // Index in takoyaki_list if holding, -1 otherwise\n    int assigned_pickup_source_idx; // Index in takoyaki_list for planned pickup, -1 if none\n    int assigned_drop_target_idx; // Index in target_list for planned drop, -1 if none\n};\nstd::vector<Fingertip> fingertips;\n\n// --- Operation String Generation ---\n// Generates the operation string for the current turn.\nstd::string generate_operation_string(int current_turn) {\n    std::string S(2 * V_prime, '.'); // Initialize with no operations\n\n    // 1. Update Arm Positions: Calculate current positions of all vertices.\n    calculate_vertex_positions();\n\n    // 2. Task Assignment: Assign takoyaki to free fingertips and targets to holding fingertips.\n    // Reset previous assignments for this turn.\n    for (auto& ft : fingertips) {\n        ft.assigned_pickup_source_idx = -1;\n        ft.assigned_drop_target_idx = -1;\n    }\n    \n    // Greedily assign pickups to fingertips that are not holding anything.\n    std::vector<bool> source_assigned_for_pickup(takoyaki_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (!ft.is_holding) { // If fingertip is empty\n            int best_takoyaki_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2; // Initialize with a large distance\n\n            // Find the closest available takoyaki\n            for (size_t j = 0; j < takoyaki_list.size(); ++j) {\n                if (!takoyaki_list[j].is_taken && !source_assigned_for_pickup[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], takoyaki_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_takoyaki_idx = j;\n                    }\n                }\n            }\n            // Assign the best takoyaki if found\n            if (best_takoyaki_idx != -1) {\n                ft.assigned_pickup_source_idx = best_takoyaki_idx;\n                source_assigned_for_pickup[best_takoyaki_idx] = true;\n            }\n        }\n    }\n\n    // Greedily assign drops to fingertips that are holding a takoyaki.\n    std::vector<bool> target_assigned_for_drop(target_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (ft.is_holding) { // If fingertip is holding\n            int best_target_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2;\n\n            // Find the closest available target\n            for (size_t j = 0; j < target_list.size(); ++j) {\n                if (!target_list[j].is_filled && !target_assigned_for_drop[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], target_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_target_idx = j;\n                    }\n                }\n            }\n            // Assign the best target if found\n            if (best_target_idx != -1) {\n                ft.assigned_drop_target_idx = best_target_idx;\n                target_assigned_for_drop[best_target_idx] = true;\n            }\n        }\n    }\n    \n    // 3. Determine Root Move (S[0])\n    int total_delta_r = 0;\n    int total_delta_c = 0;\n    int num_tasks_with_goal = 0;\n\n    // Calculate the aggregated movement required by all fingertips towards their goals\n    for (auto& ft : fingertips) {\n        Point current_pos = vertex_pos[ft.vertex_id];\n        Point goal_pos = {-1, -1}; // Sentinel value indicating no assigned goal\n\n        if (ft.is_holding) { // If holding, the goal is to reach its assigned drop target\n            if (ft.assigned_drop_target_idx != -1) {\n                goal_pos = target_list[ft.assigned_drop_target_idx].pos;\n            }\n        } else { // If not holding, the goal is to reach its assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1) {\n                goal_pos = takoyaki_list[ft.assigned_pickup_source_idx].pos;\n            }\n        }\n\n        // If a goal is assigned, contribute its delta to the total\n        if (goal_pos.r != -1) {\n            total_delta_r += (goal_pos.r - current_pos.r);\n            total_delta_c += (goal_pos.c - current_pos.c);\n            num_tasks_with_goal++;\n        }\n    }\n\n    // Determine the dominant direction for root movement\n    char root_move = '.'; // Default to no movement\n    if (num_tasks_with_goal > 0) {\n        int abs_delta_r = std::abs(total_delta_r);\n        int abs_delta_c = std::abs(total_delta_c);\n\n        // Prioritize movement in the direction with larger displacement sum\n        if (abs_delta_r > abs_delta_c) {\n            if (total_delta_r > 0) root_move = 'D'; // Move Down if total delta_r is positive\n            else if (total_delta_r < 0) root_move = 'U'; // Move Up if total delta_r is negative\n        } else if (abs_delta_c > abs_delta_r) {\n            if (total_delta_c > 0) root_move = 'R'; // Move Right if total delta_c is positive\n            else if (total_delta_c < 0) root_move = 'L'; // Move Left if total delta_c is negative\n        } else { // If tied, pick one direction, e.g., prefer vertical then horizontal\n            if (total_delta_r > 0) root_move = 'D';\n            else if (total_delta_r < 0) root_move = 'U';\n            else if (total_delta_c > 0) root_move = 'R';\n            else if (total_delta_c < 0) root_move = 'L';\n        }\n    }\n    S[0] = root_move; // Set the root movement character\n\n    // 4. Rotations (S[1] to S[V_prime-1])\n    // Currently, this strategy does NOT implement rotations for simplicity and speed.\n    // All rotation characters remain '.'\n    // If performance is insufficient, rotations for joints (vertices 1 to V_prime-2) could be added.\n\n    // 5. Fingertip Actions (S[V_prime] to S[2*V_prime-1])\n    // The action for vertex `vid` is at index `V_prime + vid` in string S.\n    for (const auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = '.'; // Default to no action\n        Point current_pos = vertex_pos[vid];\n        \n        if (ft.is_holding) { // If currently holding a takoyaki\n            // Check if at the assigned drop target\n            if (ft.assigned_drop_target_idx != -1 && current_pos == target_list[ft.assigned_drop_target_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        } else { // If not holding any takoyaki\n            // Check if at the assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1 && current_pos == takoyaki_list[ft.assigned_pickup_source_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        }\n        S[V_prime + vid] = action; // Set the action character for this vertex\n    }\n\n    return S;\n}\n\n// --- State Update Function ---\n// Applies the operations from the generated string and updates the game state.\nvoid apply_operation(const std::string& op_string) {\n    // Update root position based on the first character (root move)\n    char root_move = op_string[0];\n    if (root_move == 'U') root_pos.r--;\n    else if (root_move == 'D') root_pos.r++;\n    else if (root_move == 'L') root_pos.c--;\n    else if (root_move == 'R') root_pos.c++;\n\n    // Update rotations - THIS PART IS NOT IMPLEMENTED FOR NOW.\n    // The logic would go here if rotations were to be used.\n\n    // Apply fingertip actions ('P' for pickup/drop)\n    for (auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = op_string[V_prime + vid]; // Action character for this vertex\n        \n        if (action == 'P') {\n            if (ft.is_holding) { // Finger was holding, attempting to drop\n                int target_idx = ft.assigned_drop_target_idx;\n                // Check if the fingertip is at the assigned target location\n                if (target_idx != -1 && target_list[target_idx].pos == vertex_pos[vid]) {\n                    // Successfully dropped takoyaki\n                    target_list[target_idx].is_filled = true; // Mark target as filled\n                    takoyaki_list[ft.holding_takoyaki_idx].is_taken = false; // Release the takoyaki from being \"taken\"\n                    \n                    ft.is_holding = false; // Fingertip is now empty\n                    ft.holding_takoyaki_idx = -1; // No longer holding a takoyaki\n                    ft.assigned_drop_target_idx = -1; // Clear the drop assignment\n                } else {\n                    // If 'P' action occurs but not at target, it's an invalid/ineffective action.\n                    // This indicates a potential issue in assignment or movement logic.\n                }\n            } else { // Finger was not holding, attempting to pick up\n                int source_idx = ft.assigned_pickup_source_idx;\n                // Check if the fingertip is at the assigned source location\n                if (source_idx != -1 && takoyaki_list[source_idx].pos == vertex_pos[vid]) {\n                    // Successfully picked up takoyaki\n                    takoyaki_list[source_idx].is_taken = true; // Mark takoyaki as taken\n                    ft.is_holding = true; // Fingertip is now holding\n                    ft.holding_takoyaki_idx = source_idx; // Record which takoyaki is held\n                    ft.assigned_pickup_source_idx = -1; // Clear the pickup assignment\n                } else {\n                    // If 'P' action occurs but not at source, it's an invalid/ineffective action.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Read input parameters\n    std::cin >> N_GRID >> M_TAKOYAKI >> V_ARM;\n\n    // Read initial takoyaki positions\n    takoyaki_list.resize(M_TAKOYAKI);\n    int current_takoyaki_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store takoyaki: {position, initial_index, is_taken=false}\n                takoyaki_list[current_takoyaki_idx] = {{i, j}, current_takoyaki_idx, false};\n                current_takoyaki_idx++;\n            }\n        }\n    }\n\n    // Read target positions\n    target_list.resize(M_TAKOYAKI);\n    int current_target_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store target: {position, initial_index, is_filled=false}\n                target_list[current_target_idx] = {{i, j}, current_target_idx, false};\n                current_target_idx++;\n            }\n        }\n    }\n\n    // --- Design the Robotic Arm ---\n    V_prime = V_ARM; // Use the maximum available vertices\n    parent_map.resize(V_prime - 1);\n    edge_lengths.resize(V_prime - 1);\n    edge_orientations.resize(V_prime - 1);\n    vertex_pos.resize(V_prime); // Pre-allocate space for vertex positions\n    fingertips.clear();\n    joint_vertex_ids.clear();\n\n    // Arm Design: Path graph 0-1-2-...-V-1\n    // Parent of vertex i+1 is vertex i.\n    // Edge lengths are uniformly 1.\n    // Initial edge orientations are all 0 (Right).\n    for (int i = 0; i < V_prime - 1; ++i) {\n        parent_map[i] = i;          // Parent of vertex i+1 is vertex i\n        edge_lengths[i] = 1;        // Edge length is 1\n        edge_orientations[i] = 0;   // Initial orientation is Right (0)\n    }\n\n    // Initial root position: Center of the grid.\n    root_pos = {N_GRID / 2, N_GRID / 2};\n\n    // Identify fingertips and joints based on the path graph structure.\n    if (V_prime == 1) {\n        // If only one vertex, it's the root and also a fingertip. No joints.\n        fingertip_vertex_ids.push_back(0);\n    } else {\n        // For V' > 1, vertices 0 and V'-1 are leaves (fingertips).\n        fingertip_vertex_ids.push_back(0);\n        fingertip_vertex_ids.push_back(V_prime - 1);\n        // Vertices 1 to V'-2 are internal nodes (joints) where rotations can occur.\n        for (int i = 1; i < V_prime - 1; ++i) {\n            joint_vertex_ids.push_back(i);\n        }\n    }\n\n    // Initialize fingertip state trackers.\n    fingertips.resize(fingertip_vertex_ids.size());\n    for (size_t i = 0; i < fingertip_vertex_ids.size(); ++i) {\n        fingertips[i].vertex_id = fingertip_vertex_ids[i];\n        fingertips[i].is_holding = false;\n        fingertips[i].holding_takoyaki_idx = -1; // Tracks index in takoyaki_list IF holding\n        fingertips[i].assigned_pickup_source_idx = -1; // Tracks index in takoyaki_list for planned pickup\n        fingertips[i].assigned_drop_target_idx = -1; // Tracks index in target_list for planned drop\n    }\n\n    // Output the designed robotic arm structure.\n    std::cout << V_prime << std::endl;\n    for (int i = 0; i < V_prime - 1; ++i) {\n        std::cout << parent_map[i] << \" \" << edge_lengths[i] << std::endl;\n    }\n    std::cout << root_pos.r << \" \" << root_pos.c << std::endl;\n\n    // --- Operation Phase ---\n    int delivered_count = 0;\n    int max_turns = 100000; // Set a limit to prevent TLE.\n\n    // Main loop for executing turns.\n    for (int turn = 0; turn < max_turns; ++turn) {\n        // If all takoyaki are delivered, stop early.\n        if (delivered_count == M_TAKOYAKI) {\n            break;\n        }\n\n        // Generate the operation string for the current turn.\n        std::string op_string = generate_operation_string(turn);\n        \n        // Output the operation string.\n        std::cout << op_string << std::endl;\n        \n        // Apply the generated operations to update the game state.\n        apply_operation(op_string);\n\n        // Recalculate the number of delivered takoyaki after applying operations.\n        delivered_count = 0;\n        for(const auto& target : target_list) {\n            if (target.is_filled) {\n                delivered_count++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <map>\n\nstruct Point {\n    int x, y;\n    int type; // 0 for mackerel, 1 for sardine\n};\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n;\n    std::cin >> n;\n\n    std::vector<Point> points(2 * n);\n    std::vector<int> x_coords_all, y_coords_all;\n    x_coords_all.reserve(2 * n);\n    y_coords_all.reserve(2 * n);\n\n    for (int i = 0; i < 2 * n; ++i) {\n        points[i].type = (i < n) ? 0 : 1;\n        std::cin >> points[i].x >> points[i].y;\n        x_coords_all.push_back(points[i].x);\n        y_coords_all.push_back(points[i].y);\n    }\n\n    // Sort and unique coordinates to get candidate boundary points.\n    std::sort(x_coords_all.begin(), x_coords_all.end());\n    x_coords_all.erase(std::unique(x_coords_all.begin(), x_coords_all.end()), x_coords_all.end());\n    std::sort(y_coords_all.begin(), y_coords_all.end());\n    y_coords_all.erase(std::unique(y_coords_all.begin(), y_coords_all.end()), y_coords_all.end());\n\n    // K_cand is the number of candidate coordinate values to consider along each axis.\n    // A larger K_cand increases the chances of finding an optimal rectangle but also increases runtime.\n    // K_cand = 100 is chosen to balance search space and performance.\n    int K_cand = 100; \n\n    std::vector<int> sx, sy;\n    sx.reserve(K_cand);\n    sy.reserve(K_cand);\n\n    // Always include the bounding box coordinates 0 and 100000.\n    sx.push_back(0);\n    sx.push_back(100000);\n    sy.push_back(0);\n    sy.push_back(100000);\n\n    // Select K_cand-2 points from all unique x-coordinates, attempting to space them evenly.\n    // This ensures candidate boundaries cover the distribution of points.\n    if (x_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            // Select index: (i * (total_unique - 1)) / (num_points_to_select - 1)\n            // This samples points from the available unique coordinates.\n            sx.push_back(x_coords_all[(i * (x_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (x_coords_all.size() > 0) {\n        // If there are fewer than 2 unique coordinates (excluding 0 and 100000 if they are not present),\n        // add some of the existing unique coordinates to ensure some variation.\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, x_coords_all.size()); ++i) {\n            sx.push_back(x_coords_all[i]);\n        }\n    }\n    \n    // Select K_cand-2 points from all unique y-coordinates, similar to x-coordinates.\n    if (y_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            sy.push_back(y_coords_all[(i * (y_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (y_coords_all.size() > 0) {\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, y_coords_all.size()); ++i) {\n            sy.push_back(y_coords_all[i]);\n        }\n    }\n    \n    // Sort and remove duplicates from candidate coordinates to ensure valid intervals.\n    std::sort(sx.begin(), sx.end());\n    sx.erase(std::unique(sx.begin(), sx.end()), sx.end());\n    std::sort(sy.begin(), sy.end());\n    sy.erase(std::unique(sy.begin(), sy.end()), sy.end());\n\n    int num_sx = sx.size();\n    int num_sy = sy.size();\n\n    // `grid_diff` is a 2D difference array.\n    // `grid_diff[i][j]` stores the value that starts contributing to cells starting at `sx[i]` and `sy[j]`.\n    // Specifically, it applies a value change to the grid cell starting at `[sx[i], sx[i+1]) x [sy[j], sy[j+1])`.\n    // The size is `num_sx` x `num_sy` to handle points correctly.\n    std::vector<std::vector<int>> grid_diff(num_sx, std::vector<int>(num_sy, 0));\n\n    for (const auto& p : points) {\n        // Determine the grid cell index `ix` for point `p.x`.\n        // `ix` should be the index `i` such that `sx[i] <= p.x < sx[i+1]`.\n        // `std::upper_bound(sx.begin(), sx.end(), p.x)` finds the first element `sx[k]` strictly greater than `p.x`.\n        // The index `k` indicates that `p.x` is in the interval `[sx[k-1], sx[k])`. So `ix = k-1`.\n        auto it_x = std::upper_bound(sx.begin(), sx.end(), p.x);\n        int ix = (it_x - sx.begin()) - 1;\n        \n        // Similarly, determine the grid cell index `iy` for point `p.y`.\n        auto it_y = std::upper_bound(sy.begin(), sy.end(), p.y);\n        int iy = (it_y - sy.begin()) - 1;\n        \n        int val = (p.type == 0 ? 1 : -1); // +1 for mackerel, -1 for sardine.\n\n        // Apply the difference array update.\n        // `val` is added at the top-left corner of the cell `(ix, iy)`.\n        // It's subtracted at `(ix+1, iy)` and `(ix, iy+1)` to limit its effect to the cell `(ix, iy)`.\n        // It's added back at `(ix+1, iy+1)` to correct the double subtraction.\n        // Indices must be within bounds.\n        if (ix < num_sx && iy < num_sy) {\n            grid_diff[ix][iy] += val;\n            if (ix + 1 < num_sx) grid_diff[ix + 1][iy] -= val;\n            if (iy + 1 < num_sy) grid_diff[ix][iy + 1] -= val;\n            if (ix + 1 < num_sx && iy + 1 < num_sy) grid_diff[ix + 1][iy + 1] += val;\n        }\n    }\n    \n    // `grid_ps[i][j]` will store the cumulative sum for the rectangle `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n    // This is computed using 2D prefix sums on `grid_diff`.\n    std::vector<std::vector<int>> grid_ps(num_sx, std::vector<int>(num_sy, 0));\n    for (int i = 0; i < num_sx; ++i) {\n        for (int j = 0; j < num_sy; ++j) {\n            grid_ps[i][j] = grid_diff[i][j];\n            if (i > 0) grid_ps[i][j] += grid_ps[i-1][j];\n            if (j > 0) grid_ps[i][j] += grid_ps[i][j-1];\n            if (i > 0 && j > 0) grid_ps[i][j] -= grid_ps[i-1][j-1];\n        }\n    }\n\n    // Lambda function `get_ps_val` to safely retrieve prefix sum values.\n    // It handles out-of-bounds indices (e.g., for calculations involving `index-1`) by returning 0.\n    // `grid_ps[r_idx][c_idx]` stores the sum of points `p` such that `p.x < sx[r_idx+1]` and `p.y < sy[c_idx+1]`.\n    auto get_ps_val = [&](int r_idx, int c_idx) {\n        if (r_idx < 0 || c_idx < 0) return 0;\n        // Clamp indices to be within the bounds of grid_ps.\n        // This handles cases where calculation might exceed max index.\n        r_idx = std::min(r_idx, num_sx - 1);\n        c_idx = std::min(c_idx, num_sy - 1);\n        return grid_ps[r_idx][c_idx];\n    };\n\n    long long max_score_diff = -2e18; // Initialize with a very small value to find the maximum.\n    int best_x1_idx = -1, best_x2_idx = -1, best_y1_idx = -1, best_y2_idx = -1;\n\n    // Iterate through all possible rectangles defined by pairs of candidate coordinates.\n    // A rectangle is defined by its bottom-left corner (sx[i1], sy[j1]) and top-right corner (sx[i2], sy[j2]).\n    for (int i1 = 0; i1 < num_sx; ++i1) {\n        for (int i2 = i1; i2 < num_sx; ++i2) {\n            for (int j1 = 0; j1 < num_sy; ++j1) {\n                for (int j2 = j1; j2 < num_sy; ++j2) {\n                    \n                    // Variable to store the score difference (mackerels - sardines) for the current rectangle.\n                    long long current_score_diff = 0; \n\n                    // Calculate the score for the rectangle defined by [sx[i1], sx[i2]] x [sy[j1], sy[j2]].\n                    // This score is calculated using the 2D prefix sums for a rectangle query:\n                    // Sum(X_max, Y_max) - Sum(X_min-1, Y_max) - Sum(X_max, Y_min-1) + Sum(X_min-1, Y_min-1)\n                    // Here, Sum(X, Y) denotes the sum of points `p` such that `p.x <= X` and `p.y <= Y`.\n                    // Using `grid_ps`:\n                    // Sum(sx[i2], sy[j2]) corresponds to `get_ps_val(i2, j2)`\n                    // Sum(sx[i1]-1, sy[j2]) corresponds to `get_ps_val(i1-1, j2)`\n                    // Sum(sx[i2], sy[j1]-1) corresponds to `get_ps_val(i2, j1-1)`\n                    // Sum(sx[i1]-1, sy[j1]-1) corresponds to `get_ps_val(i1-1, j1-1)`\n                    current_score_diff = get_ps_val(i2, j2) \n                                       - get_ps_val(i1 - 1, j2) \n                                       - get_ps_val(i2, j1 - 1) \n                                       + get_ps_val(i1 - 1, j1 - 1);\n\n                    // Calculate the perimeter of the rectangle.\n                    long long current_perimeter = 2LL * ((long long)(sx[i2] - sx[i1]) + (long long)(sy[j2] - sy[j1]));\n\n                    // Check if the perimeter constraint is satisfied.\n                    if (current_perimeter <= 400000LL) {\n                        // If the current rectangle has a better score difference, update the best found rectangle.\n                        if (current_score_diff > max_score_diff) {\n                            max_score_diff = current_score_diff;\n                            best_x1_idx = i1;\n                            best_x2_idx = i2;\n                            best_y1_idx = j1;\n                            best_y2_idx = j2;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If no valid rectangle was found (e.g., all rectangles exceeded perimeter, or all had non-positive score diff),\n    // default to a minimal valid rectangle: a single point at (0,0) if (0,0) is a candidate.\n    // The indices sx[0], sy[0] are always 0. So this effectively picks (0,0) as the rectangle.\n    // This rectangle has perimeter 0 and a score difference of 0 if no points are at (0,0),\n    // resulting in a score of max(0, 0+1)=1, which is a valid baseline.\n    if (best_x1_idx == -1) {\n        best_x1_idx = 0;\n        best_x2_idx = 0;\n        best_y1_idx = 0;\n        best_y2_idx = 0;\n    }\n    \n    // Output the 4 vertices of the best rectangle found.\n    // The vertices are (sx[best_x1_idx], sy[best_y1_idx]), (sx[best_x2_idx], sy[best_y1_idx]),\n    // (sx[best_x2_idx], sy[best_y2_idx]), and (sx[best_x1_idx], sy[best_y2_idx}).\n    std::cout << 4 << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y2_idx] << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y2_idx] << std::endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <utility> // for std::pair\n\n// Structure to hold noisy dimensions for a rectangle\nstruct Rect {\n    long long w_prime, h_prime;\n};\n\n// Structure to hold information about a rectangle after placement\nstruct PlacedRect {\n    int id; // original index of the rectangle\n    long long x, y, w, h; // position (top-left) and dimensions\n};\n\n// Structure to represent an entry in the output placement sequence for a turn\nstruct OutputEntry {\n    int p; // rectangle index\n    int r; // rotation (0: original, 1: 90 deg rotated)\n    char d; // direction ('U' for Up, 'L' for Left)\n    int b; // reference rectangle index (-1 for origin, or index in current_placed_rects)\n};\n\nint main() {\n    // Improve I/O performance\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N; // Number of rectangles\n    int T; // Number of turns\n    long long sigma; // Standard deviation of measurement error\n    std::cin >> N >> T >> sigma;\n\n    // Read noisy dimensions for each rectangle\n    std::vector<Rect> rects(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> rects[i].w_prime >> rects[i].h_prime;\n    }\n\n    // Pre-calculate the sum of (w'_i + h'_i) for all suffixes of rectangles.\n    // penalty_sum[k] will store sum_{i=k to N-1} (rects[i].w_prime + rects[i].h_prime).\n    // This is used to quickly calculate the penalty for unused rectangles.\n    std::vector<long long> penalty_sum(N + 1, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        penalty_sum[i] = penalty_sum[i + 1] + rects[i].w_prime + rects[i].h_prime;\n    }\n\n    // Main loop for each turn\n    for (int t = 0; t < T; ++t) {\n        // Variables to store the best placement strategy found for the current turn\n        std::vector<OutputEntry> best_output_sequence;\n        int best_n = 0; // Number of rectangles to place in this turn\n        long long best_turn_score = -1; // Score for the best strategy in this turn\n\n        // Iterate through all possible numbers of rectangles to place, from N down to 0.\n        // We try to place `num_to_place` rectangles, specifically indices 0, 1, ..., num_to_place - 1.\n        // This is because rectangles must be placed in ascending order of their original indices.\n        for (int num_to_place = N; num_to_place >= 0; --num_to_place) {\n            // Case: placing 0 rectangles.\n            if (num_to_place == 0) {\n                // The score is 0 (W+H) + penalty for all N unused rectangles.\n                long long current_score = 0 + 0 + penalty_sum[0];\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = 0;\n                    best_output_sequence.clear(); // Empty sequence\n                }\n                continue; // Move to the next iteration of `num_to_place`\n            }\n\n            // State for placing `num_to_place` rectangles:\n            std::vector<PlacedRect> current_placed_rects; // Stores info about rectangles placed so far in this attempt.\n            std::vector<OutputEntry> current_output_sequence; // Stores the placement instructions for this attempt.\n            bool possible_to_place_all = true; // Flag to check if all `num_to_place` can be placed validly.\n\n            long long current_max_W = 0; // Current bounding box width after placing rectangles so far.\n            long long current_max_H = 0; // Current bounding box height after placing rectangles so far.\n\n            // Attempt to place rectangles 0, 1, ..., num_to_place - 1 in order.\n            for (int i = 0; i < num_to_place; ++i) {\n                int current_rect_idx = i; // The original index of the rectangle being considered for placement.\n\n                // Define the two possible dimensions (original and rotated) for the current rectangle.\n                std::pair<long long, long long> dims[2];\n                dims[0] = {rects[current_rect_idx].w_prime, rects[current_rect_idx].h_prime}; // r = 0 (no rotation)\n                dims[1] = {rects[current_rect_idx].h_prime, rects[current_rect_idx].w_prime}; // r = 1 (rotated 90 degrees)\n\n                // Variables to track the best placement found for the current rectangle `i`.\n                long long best_x = -1, best_y = -1; // Best position (top-left corner)\n                int best_r = -1; // Best rotation option (0 or 1)\n                char best_d_char = ' '; // Best direction ('U' or 'L')\n                int best_b_idx_in_placed = -1; // Index of the reference rectangle in `current_placed_rects` (-1 if origin).\n                long long min_placement_cost = -1; // The cost (W+H) of the best found placement for this rectangle.\n\n                // Iterate through all possible reference rectangles.\n                // `b_place_idx` is the index in `current_placed_rects`. -1 refers to the origin (0,0).\n                for (int b_place_idx = -1; b_place_idx < current_placed_rects.size(); ++b_place_idx) {\n                    // Get reference rectangle's properties if b_place_idx is valid.\n                    long long ref_x = 0, ref_y = 0, ref_w = 0, ref_h = 0;\n                    if (b_place_idx != -1) {\n                        ref_x = current_placed_rects[b_place_idx].x;\n                        ref_y = current_placed_rects[b_place_idx].y;\n                        ref_w = current_placed_rects[b_place_idx].w;\n                        ref_h = current_placed_rects[b_place_idx].h;\n                    }\n\n                    // Iterate through rotation options (0 or 1).\n                    for (int r_opt = 0; r_opt < 2; ++r_opt) {\n                        long long W = dims[r_opt].first; // Width of the rectangle in this orientation.\n                        long long H = dims[r_opt].second; // Height of the rectangle in this orientation.\n\n                        // Iterate through placement directions ('U' or 'L').\n                        for (char d_char : {'U', 'L'}) {\n                            long long cur_x, cur_y; // Proposed position for the top-left corner.\n\n                            if (d_char == 'U') {\n                                // Place upwards: align left edge with ref's right edge, top edge with ref's bottom edge.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x + ref_w);\n                                cur_y = (b_place_idx == -1) ? 0 : (ref_y + ref_h);\n                            } else { // d_char == 'L'\n                                // Place leftwards: align right edge with ref's left edge, top edge with ref's top edge.\n                                // The resulting x-coordinate must be non-negative.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x - W);\n                                cur_y = (b_place_idx == -1) ? 0 : ref_y;\n                                \n                                // Constraint: rectangles must be placed in x >= 0 and y >= 0.\n                                // For 'L' placement, if `ref_x - W` results in a negative x-coordinate,\n                                // this specific alignment with `ref_x` is not possible without going left of the origin.\n                                // The rule implies stopping at x=0. If `ref_x < W`, the rectangle cannot be placed \n                                // such that its right edge is at `ref_x` AND its left edge is >= 0.\n                                // Thus, `ref_x` must be at least `W` for this alignment to be possible.\n                                if (cur_x < 0) { \n                                    continue; // This placement combination is invalid.\n                                }\n                            }\n\n                            // Calculate the resulting bounding box dimensions if this rectangle is placed at (cur_x, cur_y).\n                            // `current_max_W` and `current_max_H` store the bounding box of already placed rectangles.\n                            long long candidate_W = std::max(current_max_W, cur_x + W);\n                            long long candidate_H = std::max(current_max_H, cur_y + H);\n                            \n                            // The cost for this placement is the sum of the bounding box dimensions.\n                            long long current_placement_cost = candidate_W + candidate_H;\n\n                            // If this is the first valid placement found, or if it yields a better (smaller) cost, update best found.\n                            if (min_placement_cost == -1 || current_placement_cost < min_placement_cost) {\n                                min_placement_cost = current_placement_cost;\n                                best_x = cur_x;\n                                best_y = cur_y;\n                                best_r = r_opt;\n                                best_d_char = d_char;\n                                best_b_idx_in_placed = b_place_idx;\n                            }\n                        } // End of loop for `d_char`\n                    } // End of loop for `r_opt`\n                } // End of loop for `b_place_idx`\n\n                // If no valid placement was found for the current rectangle `i` with the current `num_to_place` setting.\n                if (best_x == -1) {\n                    possible_to_place_all = false; // This `num_to_place` strategy is not feasible.\n                    break; // Stop trying to place more rectangles for this `num_to_place` value.\n                }\n\n                // Record the best placement found for rectangle `i`.\n                current_placed_rects.push_back({current_rect_idx, best_x, best_y, dims[best_r].first, dims[best_r].second});\n                current_output_sequence.push_back({current_rect_idx, best_r, best_d_char, best_b_idx_in_placed});\n                \n                // Update the overall bounding box dimensions with the newly placed rectangle.\n                current_max_W = std::max(current_max_W, best_x + dims[best_r].first);\n                current_max_H = std::max(current_max_H, best_y + dims[best_r].second);\n\n            } // End of loop for `i` (placing rectangles 0 to num_to_place - 1)\n\n            // If we successfully placed all `num_to_place` rectangles:\n            if (possible_to_place_all) {\n                // Calculate the total score for this specific `num_to_place` strategy.\n                // Score = (final W + final H of placed rectangles) + (penalty sum of unused rectangles).\n                long long current_score = current_max_W + current_max_H + penalty_sum[num_to_place];\n                \n                // If this score is better than the best score found so far for this turn, update bests.\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = num_to_place;\n                    best_output_sequence = current_output_sequence;\n                }\n            }\n        } // End of loop for `num_to_place` (trying different counts of rectangles to place)\n\n        // Output the chosen placement strategy for the current turn.\n        std::cout << best_n << std::endl;\n        for (const auto& p : best_output_sequence) {\n            std::cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << std::endl;\n        }\n        std::cout << std::flush; // Ensure output is sent immediately.\n\n        // Read the measured bounding box dimensions for this turn.\n        // These are not used by the current strategy, but are required by the problem protocol.\n        long long measured_W_prime, measured_H_prime;\n        std::cin >> measured_W_prime >> measured_H_prime;\n    } // End of loop for turns `t`\n\n    return 0; // Program finished successfully.\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <tuple> // Not strictly needed for PQ_Entry, but included for completeness.\n\nusing namespace std;\n\n// Structure to store information about a representative of a DSU set.\nstruct DSU_Rep_Info {\n    int root_vertex;    // The actual vertex ID that is the root of this tree.\n    int max_height;     // The maximum height among all vertices in this tree, relative to root_vertex.\n    long long sum_beauty; // The sum of beauty values of all vertices in this tree.\n    int component_size; // The number of vertices in this component.\n};\n\nvector<int> dsu_parent; // Standard DSU parent array.\nvector<DSU_Rep_Info> rep_info; // Stores information about each representative.\n\n// Finds the representative of the set containing vertex v. Path compression is used.\nint find_set(int v) {\n    if (v == dsu_parent[v])\n        return v;\n    return dsu_parent[v] = find_set(dsu_parent[v]);\n}\n\n// Structure for priority queue entries to handle custom comparison.\nstruct PQ_Entry {\n    long long gain; // Primary criterion: sum of beauty of the child component.\n    int h_child; // Secondary: max height of the child component (prefer deeper).\n    int h_parent_height; // Tertiary: max height of the parent component (prefer deeper parents).\n    long long h_parent_sum_beauty; // Quaternary: sum of beauty of the parent component (prefer higher beauty parents).\n    \n    // For comparing average beauty of children using integer cross-multiplication.\n    // We store child_sum_beauty and child_component_size.\n    long long child_sum_beauty;\n    int child_component_size;\n\n    int parent_root_repr_id; // ID of the parent's DSU representative.\n    int child_root_repr_id;  // ID of the child's DSU representative.\n\n    // Custom comparison operator for the max-heap priority queue.\n    // Returns true if 'this' is considered \"less than\" 'other', meaning 'other' has higher priority.\n    bool operator<(const PQ_Entry& other) const {\n        // Primary: maximize gain (sum of beauty of the child component).\n        if (gain != other.gain) return gain < other.gain;\n\n        // Secondary: maximize h_child (prefer deeper children).\n        if (h_child != other.h_child) return h_child < other.h_child;\n\n        // Tertiary: maximize h_parent_height (prefer deeper parents).\n        if (h_parent_height != other.h_parent_height) return h_parent_height < other.h_parent_height;\n\n        // Quaternary: maximize h_parent_sum_beauty (prefer merging into more beautiful parents).\n        if (h_parent_sum_beauty != other.h_parent_sum_beauty) return h_parent_sum_beauty < other.h_parent_sum_beauty;\n\n        // Quinary: maximize average beauty of the child component using integer cross-multiplication.\n        // Compare S1/Z1 vs S2/Z2 using cross-multiplication: S1*Z2 vs S2*Z1.\n        // Use unsigned __int128 for intermediate products to avoid overflow.\n        unsigned __int128 val1 = (unsigned __int128)child_sum_beauty * other.child_component_size;\n        unsigned __int128 val2 = (unsigned __int128)other.child_sum_beauty * child_component_size;\n        if (val1 != val2) return val1 < val2; // Prefer child with higher average beauty.\n\n        // If all criteria are equal, the order doesn't significantly impact score.\n        // Return false to indicate equality.\n        return false;\n    }\n};\n\n// Merges the set represented by root_c_repr into the set represented by root_p_repr.\n// Removed unused parameters H and adj.\nvoid union_sets(int root_p_repr, int root_c_repr, int root_p_vertex, int root_c_vertex, vector<int>& p, vector<DSU_Rep_Info>& rep_info, vector<int>& dsu_parent) {\n    dsu_parent[root_c_repr] = root_p_repr;\n    p[root_c_vertex] = root_p_vertex;\n\n    rep_info[root_p_repr].sum_beauty += rep_info[root_c_repr].sum_beauty;\n    rep_info[root_p_repr].max_height = max(rep_info[root_p_repr].max_height, rep_info[root_c_repr].max_height + 1);\n    rep_info[root_p_repr].component_size += rep_info[root_c_repr].component_size;\n    rep_info[root_p_repr].root_vertex = root_p_vertex; // Ensure root_vertex is consistent\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n; // Number of vertices\n    int m; // Number of edges\n    int h_limit; // Maximum allowed height\n    cin >> n >> m >> h_limit;\n\n    vector<long long> a(n); // Beauty values of vertices\n    for (int i = 0; i < n; ++i) {\n        cin >> a[i];\n    }\n\n    vector<vector<int>> adj(n); // Adjacency list for the graph\n    vector<pair<int, int>> edges; // List of all edges\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        edges.push_back({u, v});\n    }\n\n    // Initialize DSU structure.\n    dsu_parent.resize(n);\n    iota(dsu_parent.begin(), dsu_parent.end(), 0); // dsu_parent[i] = i for all i\n    \n    rep_info.resize(n);\n    for (int i = 0; i < n; ++i) {\n        // Initially, each vertex is a root of its own tree.\n        rep_info[i] = {i, 0, a[i], 1}; \n    }\n\n    // Priority queue to store potential merges, using the custom PQ_Entry struct.\n    priority_queue<PQ_Entry> pq;\n\n    // Populate the priority queue with initial merge candidates.\n    for (const auto& edge : edges) {\n        int u_vtx = edge.first;\n        int v_vtx = edge.second;\n\n        int root_u_repr = find_set(u_vtx);\n        int root_v_repr = find_set(v_vtx);\n\n        // If they are already in the same component, this edge doesn't form a new merge candidate between components.\n        if (root_u_repr == root_v_repr) continue;\n\n        // Option 1: Make v's component a child of u's component.\n        // Parent: u's component (representative root_u_repr), Child: v's component (representative root_v_repr).\n        if (rep_info[root_v_repr].max_height + 1 <= h_limit) {\n            pq.push({\n                rep_info[root_v_repr].sum_beauty, // gain\n                rep_info[root_v_repr].max_height, // h_child\n                rep_info[root_u_repr].max_height, // h_parent_height (re-ordered to tertiary)\n                rep_info[root_u_repr].sum_beauty, // h_parent_sum_beauty (re-ordered to quaternary)\n                rep_info[root_v_repr].sum_beauty, // child_sum_beauty for density calc\n                rep_info[root_v_repr].component_size, // child_component_size for density calc\n                root_u_repr, // parent_root_repr_id\n                root_v_repr  // child_root_repr_id\n            });\n        }\n        // Option 2: Make u's component a child of v's component.\n        // Parent: v's component (representative root_v_repr), Child: u's component (representative root_u_repr).\n        if (rep_info[root_u_repr].max_height + 1 <= h_limit) {\n            pq.push({\n                rep_info[root_u_repr].sum_beauty, // gain\n                rep_info[root_u_repr].max_height, // h_child\n                rep_info[root_v_repr].max_height, // h_parent_height (re-ordered to tertiary)\n                rep_info[root_v_repr].sum_beauty, // h_parent_sum_beauty (re-ordered to quaternary)\n                rep_info[root_u_repr].sum_beauty, // child_sum_beauty for density calc\n                rep_info[root_u_repr].component_size, // child_component_size for density calc\n                root_v_repr, // parent_root_repr_id\n                root_u_repr  // child_root_repr_id\n            });\n        }\n    }\n\n    // Initialize the final parent array. -1 indicates a root vertex.\n    vector<int> p(n, -1); \n\n    // Greedily process merges from the priority queue.\n    while (!pq.empty()) {\n        PQ_Entry entry = pq.top();\n        pq.pop();\n\n        // Find current representatives for the components.\n        int current_parent_repr = find_set(entry.parent_root_repr_id);\n        int current_child_repr = find_set(entry.child_root_repr_id);\n\n        // If they are already in the same set, this merge is redundant.\n        if (current_parent_repr == current_child_repr) continue;\n        \n        // Stale entry check: if the vertex IDs stored in PQ are no longer the current representatives.\n        // This happens if one of the components has been merged into another.\n        if (current_parent_repr != entry.parent_root_repr_id || current_child_repr != entry.child_root_repr_id) {\n             continue; // Stale entry.\n        }\n\n        // Re-check height constraint using the *current* max heights from `rep_info`.\n        // The values stored in the PQ entry (like h_child) might be stale.\n        if (rep_info[entry.child_root_repr_id].max_height + 1 > h_limit) {\n            continue; // Height limit violated with the current configuration.\n        }\n\n        // Perform the union operation.\n        // Note: Passing the actual root vertex IDs (rep_info[id].root_vertex) is crucial for setting p[].\n        union_sets(entry.parent_root_repr_id, entry.child_root_repr_id, rep_info[entry.parent_root_repr_id].root_vertex, rep_info[entry.child_root_repr_id].root_vertex, p, rep_info, dsu_parent);\n    }\n\n    // Output the resulting parent array.\n    for (int i = 0; i < n; ++i) {\n        cout << p[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    cin >> n;\n\n    // Read the initial board configuration.\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> board[i];\n    }\n\n    // Precompute safety information for each cell.\n    // has_fuku_above[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k < r.\n    // has_fuku_below[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k > r.\n    // has_fuku_left[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k < c.\n    // has_fuku_right[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k > c.\n    // These precomputed values allow O(1) safety checks for each direction.\n    vector<vector<bool>> has_fuku_above(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_below(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_left(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_right(n, vector<bool>(n, false));\n\n    // Compute has_fuku_above and has_fuku_below for all columns.\n    for (int c = 0; c < n; ++c) {\n        bool found_fuku_in_col = false;\n        // Scan downwards: for each cell (r, c), check if any Fuku was found in previous rows (k < r).\n        for (int r = 0; r < n; ++r) {\n            has_fuku_above[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column above current row.\n            }\n        }\n        \n        found_fuku_in_col = false; // Reset for scanning downwards to compute has_fuku_below.\n        // Scan upwards: for each cell (r, c), check if any Fuku was found in subsequent rows (k > r).\n        for (int r = n - 1; r >= 0; --r) {\n            has_fuku_below[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column below current row.\n            }\n        }\n    }\n\n    // Compute has_fuku_left and has_fuku_right for all rows.\n    for (int r = 0; r < n; ++r) {\n        bool found_fuku_in_row = false;\n        // Scan rightwards: for each cell (r, c), check if any Fuku was found in previous columns (k < c).\n        for (int c = 0; c < n; ++c) {\n            has_fuku_left[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the left of current column.\n            }\n        }\n        \n        found_fuku_in_row = false; // Reset for scanning rightwards to compute has_fuku_right.\n        // Scan leftwards: for each cell (r, c), check if any Fuku was found in subsequent columns (k > c).\n        for (int c = n - 1; c >= 0; --c) {\n            has_fuku_right[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the right of current column.\n            }\n        }\n    }\n\n    // Stores the sequence of operations to be performed.\n    vector<pair<char, int>> operations;\n    const int INF = 1e9; // A large enough value to represent infinity for costs.\n\n    // Iterate through each cell of the board.\n    for (int r = 0; r < n; ++r) {\n        for (int c = 0; c < n; ++c) {\n            // If the cell contains an Oni ('x').\n            if (board[r][c] == 'x') {\n                // Find the safest and cheapest direction to remove this specific Oni.\n                // The goal is to minimize operations (T) for the score 8N^2 - T.\n                int min_cost = INF;\n                char best_op_char = ' ';\n                int best_op_idx = -1;\n\n                // --- Evaluate Upward push ---\n                // Cost: r + 1 operations. An Oni at (r,c) moves up to (0,c) in 'r' steps, and then is removed by the (r+1)th UP shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k < r. This is checked by !has_fuku_above[r][c].\n                if (!has_fuku_above[r][c]) {\n                    int cost = r + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'U'; // Upward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Downward push ---\n                // Cost: N - r operations. An Oni at (r,c) moves down to (N-1,c) in (N-1)-r steps, and then is removed by the (N-r)th DOWN shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k > r. This is checked by !has_fuku_below[r][c].\n                if (!has_fuku_below[r][c]) {\n                    int cost = n - r;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'D'; // Downward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Leftward push ---\n                // Cost: c + 1 operations. An Oni at (r,c) moves left to (r,0) in 'c' steps, and then is removed by the (c+1)th LEFT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k < c. This is checked by !has_fuku_left[r][c].\n                if (!has_fuku_left[r][c]) {\n                    int cost = c + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'L'; // Leftward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // --- Evaluate Rightward push ---\n                // Cost: N - c operations. An Oni at (r,c) moves right to (r,N-1) in (N-1)-c steps, and then is removed by the (N-c)th RIGHT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k > c. This is checked by !has_fuku_right[r][c].\n                if (!has_fuku_right[r][c]) {\n                    int cost = n - c;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'R'; // Rightward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // The problem guarantees that for every Oni, at least one direction is safe.\n                // Thus, min_cost will be less than INF and greater than or equal to 1.\n                // We add 'min_cost' operations of the chosen type. This ensures each Oni is removed.\n                // The total number of operations T will be the sum of these minimum costs for each Oni.\n                // This greedy strategy aims to minimize T by making the locally optimal choice for each Oni.\n                for (int k = 0; k < min_cost; ++k) {\n                    operations.push_back({best_op_char, best_op_idx});\n                }\n            }\n        }\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output each operation in the specified format.\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N; // Number of employees\nlong long L; // Total number of weeks\nvector<long long> T; // Target counts for each employee\n\n// l_counts[i] = ceil(T[i] / 2.0)\n// r_counts[i] = floor(T[i] / 2.0)\n// These represent the number of times employee i directs the process\n// to a_i (if its count becomes odd) or b_i (if its count becomes even).\nvector<long long> l_counts; \nvector<long long> r_counts; \n\n// current_O[j] stores the total count of \"odd-parity\" assignments directed to employee j.\n// This sum comes from all i such that a_i = j, contributing l_counts[i].\nvector<long long> current_O; \n// current_E[j] stores the total count of \"even-parity\" assignments directed to employee j.\n// This sum comes from all i such that b_i = j, contributing r_counts[i].\nvector<long long> current_E; \n\n// a[i] and b[i] store the chosen successors for employee i.\nvector<int> a;\nvector<int> b;\n\n// Calculates the total error based on current O and E counts.\n// Error is sum of absolute differences between target T_j and actual assignments (O_j + E_j).\nlong long calculate_total_error() {\n    long long error = 0;\n    for (int j = 0; j < N; ++j) {\n        error += abs((current_O[j] + current_E[j]) - T[j]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Precompute l_counts and r_counts for each employee\n    l_counts.resize(N);\n    r_counts.resize(N);\n    for (int i = 0; i < N; ++i) {\n        l_counts[i] = (T[i] + 1) / 2; // Equivalent to ceil(T[i] / 2.0)\n        r_counts[i] = T[i] / 2;      // Equivalent to floor(T[i] / 2.0)\n    }\n\n    current_O.resize(N, 0);\n    current_E.resize(N, 0);\n    a.resize(N);\n    b.resize(N);\n\n    // Initialize: each employee i initially directs assignments to itself.\n    // a[i] = i, b[i] = i.\n    // Update current_O and current_E based on this initial assignment.\n    for (int i = 0; i < N; ++i) {\n        a[i] = i;\n        b[i] = i;\n        current_O[i] += l_counts[i];\n        current_E[i] += r_counts[i];\n    }\n\n    // Calculate initial total error\n    long long current_total_error = calculate_total_error();\n\n    // The core of the solution is a local search heuristic.\n    // We iterate a fixed number of times. In each iteration, for each employee i,\n    // we try to find the best pair (u, v) for (a[i], b[i]) that minimizes the total error.\n    // The total number of iterations is a hyperparameter. For N=100, N^3 complexity per iteration\n    // implies a limit around 1000-2000 iterations to stay within time limits.\n    // We chose 1500 iterations as a balance between exploration and performance.\n    int num_iterations = 1500; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        bool improved_in_iter = false; // Flag to check if any improvement was made in this iteration\n\n        // Iterate through each employee i to potentially change their a[i] and b[i]\n        for (int i = 0; i < N; ++i) {\n            int old_a = a[i]; // Store old assignment for a[i]\n            int old_b = b[i]; // Store old assignment for b[i]\n            \n            // Keep track of the best assignment found so far for employee i in this iteration\n            int best_new_a = old_a;\n            int best_new_b = old_b;\n            long long min_err_for_i = current_total_error; // Minimum error achievable by changing a[i], b[i]\n\n            // Try all possible pairs (u, v) for (a[i], b[i])\n            for (int u = 0; u < N; ++u) { // New target for a[i]\n                for (int v = 0; v < N; ++v) { // New target for b[i]\n                    \n                    // Store current counts before modification for backtracking\n                    long long temp_O_old_a = current_O[old_a];\n                    long long temp_O_u = current_O[u];\n                    long long temp_E_old_b = current_E[old_b];\n                    long long temp_E_v = current_E[v];\n\n                    // --- Calculate potential new total error if a[i] becomes u and b[i] becomes v ---\n                    // We need to efficiently update current_O and current_E.\n                    // If old_a != u, the contribution of l_counts[i] shifts from old_a to u.\n                    // If old_b != v, the contribution of r_counts[i] shifts from old_b to v.\n                    \n                    // Revert contributions of old assignments\n                    if (old_a != u) {\n                        current_O[old_a] -= l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] -= r_counts[i];\n                    }\n                    \n                    // Apply new contributions\n                    if (old_a != u) {\n                        current_O[u] += l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[v] += r_counts[i];\n                    }\n\n                    // Handle cases where u == old_a or v == old_b.\n                    // If u == old_a, the l_counts[i] contribution remains at old_a, so current_O[old_a] and current_O[u] are unchanged relative to each other for THIS i's contribution.\n                    // The logic above handles this correctly: if old_a == u, we do not subtract from old_a and do not add to u, keeping them as they were.\n                    // Same applies for b[i] and v.\n                    // If u == v == old_a == old_b, no changes happen.\n\n                    // Calculate the new total error with these tentative assignments\n                    long long temp_error = calculate_total_error();\n\n                    // If this new assignment (u, v) results in a lower total error, update best found for i\n                    if (temp_error < min_err_for_i) {\n                        min_err_for_i = temp_error;\n                        best_new_a = u;\n                        best_new_b = v;\n                        improved_in_iter = true; // Mark that an improvement has been made\n                    }\n                    \n                    // --- Backtrack: restore counts to their state before trying this (u,v) pair ---\n                    // This is crucial because current_O and current_E are global and used for next (u,v) pair.\n                    if (old_a != u) {\n                        current_O[old_a] = temp_O_old_a; // Restore old_a's count\n                        current_O[u] = temp_O_u;         // Restore u's count\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] = temp_E_old_b; // Restore old_b's count\n                        current_E[v] = temp_E_v;         // Restore v's count\n                    }\n                }\n            }\n            \n            // After trying all (u,v) for employee i, apply the best found assignment\n            if (min_err_for_i < current_total_error) {\n                // Update the global counts based on the best move for employee i\n                // First, remove the contribution of the old assignment\n                if (old_a != best_new_a) {\n                    current_O[old_a] -= l_counts[i];\n                    current_O[best_new_a] += l_counts[i];\n                }\n                if (old_b != best_new_b) {\n                    current_E[old_b] -= r_counts[i];\n                    current_E[best_new_b] += r_counts[i];\n                }\n                \n                // Update a[i] and b[i] to the best choice\n                a[i] = best_new_a;\n                b[i] = best_new_b;\n                current_total_error = min_err_for_i; // Update the global minimum error\n            }\n        }\n        // If no improvement was made in this iteration for any employee, we can stop early.\n        if (!improved_in_iter) {\n            break;\n        }\n    }\n\n    // Output the resulting a[i] and b[i] values\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n#include <numeric>\n#include <set>\n#include <string> // For potential error messages\n\n// Structure to hold city information\nstruct City {\n    int id;\n    long long lx, rx, ly, ry;\n    double est_x, est_y; // Estimated coordinates (center of bounding box)\n};\n\n// Structure to represent an edge with estimated weight for sorting\nstruct Edge {\n    int u, v;\n    long long weight; // Use estimated distance as weight\n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) {\n            return weight < other.weight;\n        }\n        if (u != other.u) {\n            return u < other.u;\n        }\n        return v < other.v;\n    }\n};\n\n// Disjoint Set Union (DSU) data structure for Kruskal's algorithm\nstruct DSU {\n    std::vector<int> parent;\n    DSU(int n) {\n        if (n < 0) {\n            std::cerr << \"DSU constructor received negative size: \" << n << std::endl;\n            exit(1); // Fatal error\n        }\n        parent.resize(n);\n        std::iota(parent.begin(), parent.end(), 0); // Initialize each node as its own parent\n    }\n    \n    int find(int i) {\n        if (i < 0 || static_cast<size_t>(i) >= parent.size()) {\n            std::cerr << \"DSU::find: Index out of bounds: i=\" << i << \", size=\" << parent.size() << std::endl;\n            exit(1); // Fatal error\n        }\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n    \n    void unite(int i, int j) {\n        if (i < 0 || static_cast<size_t>(i) >= parent.size() || j < 0 || static_cast<size_t>(j) >= parent.size()) {\n             std::cerr << \"DSU::unite: Index out of bounds: i=\" << i << \", j=\" << j << \", size=\" << parent.size() << std::endl;\n             exit(1); // Fatal error\n        }\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j; // Union by rank/size can be added for optimization\n        }\n    }\n};\n\n// Global variables\nint GLOBAL_N;\nstd::vector<City> GLOBAL_CITIES;\n\n// Function to query MST for a subset of cities\n// Returns a vector of pairs (u, v) representing MST edges.\n// IMPORTANT: For a subset of size 2, it returns the single edge connecting them.\nstd::vector<std::pair<int, int>> query_mst(const std::vector<int>& cities_subset) {\n    size_t subset_size = cities_subset.size();\n\n    // If subset has only 2 cities, the MST is the single edge between them.\n    // We do NOT query the judge for size 2 subsets, as it seems to cause issues.\n    // We return the edge directly. Its weight will be estimated later.\n    if (subset_size == 2) {\n        int u = cities_subset[0];\n        int v = cities_subset[1];\n        if (u > v) std::swap(u, v); // Ensure lexicographical order\n        return {{u, v}};\n    }\n    \n    // For subsets of size > 2, query the judge.\n    std::cout << \"? \" << subset_size;\n    for (int city_id : cities_subset) {\n        std::cout << \" \" << city_id;\n    }\n    std::cout << std::endl; // Flush output\n\n    std::vector<std::pair<int, int>> mst_edges;\n    // Read subset_size - 1 pairs of cities forming the MST\n    // This loop will run for subset_size > 2.\n    for (size_t i = 0; i < subset_size - 1; ++i) {\n        int u, v;\n        if (!(std::cin >> u >> v)) {\n            // This error condition should ideally not be reached for subset_size > 2.\n            // If it is, it indicates a problem with judge output for larger sets.\n            std::cerr << \"ERROR: Failed to read MST edge from judge for subset size \" << subset_size \n                      << \". Expected \" << subset_size - 1 << \" edges, but failed at edge \" << i << \".\" << std::endl;\n            exit(1); // Fatal error\n        }\n        \n        // Enhanced Validation (same as before)\n        bool u_valid_id = (u >= 0 && u < GLOBAL_N);\n        bool v_valid_id = (v >= 0 && v < GLOBAL_N);\n\n        if (!u_valid_id || !v_valid_id) {\n            std::cerr << \"ERROR: Received out-of-bounds city ID from judge. u=\" << u << \", v=\" << v << \", N=\" << GLOBAL_N << std::endl;\n            exit(1); // Fatal error\n        }\n        \n        bool u_in_subset = false;\n        bool v_in_subset = false;\n        for(int city_in_subset : cities_subset) {\n            if (city_in_subset == u) u_in_subset = true;\n            if (city_in_subset == v) v_in_subset = true;\n        }\n        if (!u_in_subset || !v_in_subset) {\n            std::cerr << \"ERROR: Received city ID not present in queried subset. u=\" << u << \", v=\" << v << std::endl;\n            std::cerr << \"Queried subset: \";\n            for(int city_id : cities_subset) std::cerr << city_id << \" \";\n            std::cerr << std::endl;\n            exit(1); // Fatal error\n        }\n        // End Enhanced Validation\n\n        if (u > v) std::swap(u, v); // Ensure lexicographical order\n        mst_edges.push_back({u, v});\n    }\n    return mst_edges;\n}\n\n// Calculate estimated Euclidean distance between two cities\nlong long estimated_dist(const City& c1, const City& c2) {\n    long long dx = static_cast<long long>(std::round(c1.est_x)) - static_cast<long long>(std::round(c2.est_x));\n    long long dy = static_cast<long long>(std::round(c1.est_y)) - static_cast<long long>(std::round(c2.est_y));\n    \n    long long squared_dist = dx * dx + dy * dy;\n    if (squared_dist < 0) squared_dist = 0; \n    \n    return static_cast<long long>(std::sqrt(static_cast<double>(squared_dist)));\n}\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N_val_input, M, Q, L, W;\n    std::cin >> N_val_input >> M >> Q >> L >> W;\n\n    GLOBAL_N = N_val_input;\n\n    std::vector<int> G(M);\n    for (int i = 0; i < M; ++i) {\n        std::cin >> G[i];\n    }\n\n    GLOBAL_CITIES.resize(GLOBAL_N);\n    std::vector<int> p(GLOBAL_N);\n    for (int i = 0; i < GLOBAL_N; ++i) {\n        GLOBAL_CITIES[i].id = i;\n        std::cin >> GLOBAL_CITIES[i].lx >> GLOBAL_CITIES[i].rx >> GLOBAL_CITIES[i].ly >> GLOBAL_CITIES[i].ry;\n        GLOBAL_CITIES[i].est_x = (GLOBAL_CITIES[i].lx + GLOBAL_CITIES[i].rx) / 2.0;\n        GLOBAL_CITIES[i].est_y = (GLOBAL_CITIES[i].ly + GLOBAL_CITIES[i].ry) / 2.0;\n        p[i] = i;\n    }\n\n    std::sort(p.begin(), p.end(), [&](int i, int j) {\n        if (GLOBAL_CITIES[i].est_x != GLOBAL_CITIES[j].est_x) {\n            return GLOBAL_CITIES[i].est_x < GLOBAL_CITIES[j].est_x;\n        }\n        return GLOBAL_CITIES[i].est_y < GLOBAL_CITIES[j].est_y;\n    });\n\n    std::vector<std::vector<int>> final_groups(M);\n    std::vector<int> city_to_group_idx(GLOBAL_N);\n    int current_city_p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < G[k]; ++i) {\n            int city_id = p[current_city_p_idx++];\n            final_groups[k].push_back(city_id);\n            city_to_group_idx[city_id] = k;\n        }\n    }\n\n    std::vector<Edge> collected_queried_edges;\n    std::set<std::pair<int, int>> queried_edge_pairs_set;\n    int queries_used = 0;\n\n    // Phase 1: Query entire groups if their size is within the limit L.\n    // IMPORTANT: We only query groups with size >= 3, as querying size 2 seems problematic.\n    // Groups of size 2 will rely on Kruskal's with estimated distances.\n    for (int k = 0; k < M; ++k) {\n        // Query only if group size is between 3 and L (inclusive), and we have queries left.\n        if (final_groups[k].size() >= 3 && final_groups[k].size() <= static_cast<size_t>(L) && static_cast<size_t>(queries_used) < static_cast<size_t>(Q)) {\n            std::vector<std::pair<int, int>> mst_edges = query_mst(final_groups[k]);\n            for (const auto& edge_pair : mst_edges) {\n                int u = edge_pair.first;\n                int v = edge_pair.second;\n                if (queried_edge_pairs_set.find({u, v}) == queried_edge_pairs_set.end()) {\n                    collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(GLOBAL_CITIES[u], GLOBAL_CITIES[v]))});\n                    queried_edge_pairs_set.insert({u, v});\n                }\n            }\n            queries_used++;\n        }\n    }\n\n    // Phase 2: Use remaining queries for sliding windows of size L.\n    // L is guaranteed to be >= 3, so these subsets will always have size >= 3.\n    int num_windows_to_query = std::min(Q - queries_used, GLOBAL_N); \n    for (int i = 0; i < num_windows_to_query; ++i) {\n        std::vector<int> subset;\n        for (int j = 0; j < L; ++j) {\n            subset.push_back(p[(i + j) % GLOBAL_N]);\n        }\n        // subset.size() will be L, which is >= 3.\n        std::vector<std::pair<int, int>> mst_edges = query_mst(subset);\n        for (const auto& edge_pair : mst_edges) {\n            int u = edge_pair.first;\n            int v = edge_pair.second;\n            if (queried_edge_pairs_set.find({u, v}) == queried_edge_pairs_set.end()) {\n                collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(GLOBAL_CITIES[u], GLOBAL_CITIES[v]))});\n                queried_edge_pairs_set.insert({u, v});\n            }\n        }\n    }\n\n    // Collect all potential edges for building final MSTs.\n    std::vector<Edge> all_candidate_edges;\n    // Add all edges collected from queries.\n    for(const auto& edge : collected_queried_edges) {\n        all_candidate_edges.push_back(edge);\n    }\n\n    // Add edges for pairs of cities that were NOT part of any queried subset.\n    // For groups of size 2, this is where the single edge will be implicitly considered\n    // when Kruskal's algorithm runs, if it's not covered by queried edges.\n    for(int i = 0; i < GLOBAL_N; ++i) {\n        for(int j = i + 1; j < GLOBAL_N; ++j) {\n            if(queried_edge_pairs_set.find({i, j}) == queried_edge_pairs_set.end()) {\n                all_candidate_edges.push_back({i, j, static_cast<int>(estimated_dist(GLOBAL_CITIES[i], GLOBAL_CITIES[j]))});\n            }\n        }\n    }\n    \n    std::sort(all_candidate_edges.begin(), all_candidate_edges.end());\n\n    // Build the Minimum Spanning Tree (MST) for each group.\n    std::vector<std::vector<std::pair<int, int>>> final_group_edges(M);\n    for (int k = 0; k < M; ++k) { // For each group k\n        // Groups of size 1 need no edges.\n        if (G[k] == 1) continue;\n\n        // Groups of size 2 require exactly one edge. If this edge wasn't in queried_edge_pairs_set,\n        // it will be added here if it's the shortest available edge.\n        // We don't query size 2 groups, so they rely solely on Kruskal's and estimated distances.\n\n        DSU dsu(GLOBAL_N); \n        \n        for (const auto& edge : all_candidate_edges) {\n            // Stop if we have enough edges for this group.\n            if (final_group_edges[k].size() >= static_cast<size_t>(G[k] - 1)) break;\n\n            int u = edge.u;\n            int v = edge.v;\n\n            // Check if both endpoints belong to the current group `k`.\n            if (city_to_group_idx[u] == k && city_to_group_idx[v] == k) {\n                // If adding this edge does not create a cycle within the current group's MST.\n                if (dsu.find(u) != dsu.find(v)) {\n                    dsu.unite(u, v);\n                    final_group_edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n\n    // Output the final answer.\n    std::cout << \"!\" << std::endl;\n    for (int k = 0; k < M; ++k) {\n        for (int city_id : final_groups[k]) {\n            std::cout << city_id << \" \";\n        }\n        std::cout << std::endl;\n        \n        for (const auto& edge : final_group_edges[k]) {\n            std::cout << edge.first << \" \" << edge.second << std::endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Global variables to store game state and parameters\nint N; // Size of the skating rink (N x N)\nint M; // Total number of points given in input (start position + M-1 targets)\nvector<pair<int, int>> all_points; // Stores all M points: start and targets\nset<pair<int, int>> blocks; // Stores coordinates of all placed blocks\npair<int, int> current_pos; // Current position of the player\n\n// --- Helper Functions ---\n\n// Checks if a given coordinate (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Returns the change in (row, column) for a given direction character.\npair<int, int> get_delta(char dir) {\n    if (dir == 'U') return {-1, 0}; // Up: decrease row\n    if (dir == 'D') return {1, 0};  // Down: increase row\n    if (dir == 'L') return {0, -1}; // Left: decrease column\n    if (dir == 'R') return {0, 1};  // Right: increase column\n    return {0, 0}; // Should not happen with valid input\n}\n\n// --- Game Simulation and Action Execution ---\n\n// Executes a chosen action and direction.\n// This function simulates the action's effect on the game state (current_pos, blocks)\n// and prints the action to standard output for the judge system.\nvoid execute_action(char action, char dir) {\n    pair<int, int> delta = get_delta(dir);\n    int dx = delta.first;\n    int dy = delta.second;\n\n    if (action == 'M') { // Move action\n        // Update current position by one step in the given direction.\n        current_pos.first += dx;\n        current_pos.second += dy;\n        cout << action << ' ' << dir << endl;\n    } else if (action == 'A') { // Alter action\n        // Calculate the coordinates of the adjacent square to alter.\n        int alter_r = current_pos.first + dx;\n        int alter_c = current_pos.second + dy;\n        \n        // Ensure the target square for alteration is within bounds.\n        if (is_valid(alter_r, alter_c)) {\n            // If a block exists, remove it. Otherwise, place a new block.\n            if (blocks.count({alter_r, alter_c})) {\n                blocks.erase({alter_r, alter_c});\n            } else {\n                blocks.insert({alter_r, alter_c});\n            }\n        }\n        cout << action << ' ' << dir << endl;\n        // The player's position (current_pos) does not change during an Alter action.\n    } else if (action == 'S') { // Slide action\n        int cx = current_pos.first;\n        int cy = current_pos.second;\n        int slide_dist = 0;\n        \n        // Simulate the slide step-by-step to determine how far it goes.\n        // The slide stops just before hitting a block or going out of bounds.\n        for (int k = 1; ; ++k) {\n            int r = cx + k * dx;\n            int c = cy + k * dy;\n            \n            // Stop if the next square is out of bounds or contains a block.\n            if (!is_valid(r, c) || blocks.count({r, c})) {\n                slide_dist = k - 1; // The actual distance slid is k-1 squares.\n                break;\n            }\n            // Note: The problem states \"If you slide over a target square without stopping on it, it is not considered visited.\"\n            // This means the slide continues until a block/boundary, even if it passes targets.\n            // Our simulation accurately finds the stopping point.\n        }\n        \n        // Update current position by the calculated slide distance.\n        current_pos.first += slide_dist * dx;\n        current_pos.second += slide_dist * dy;\n        cout << action << ' ' << dir << endl;\n    }\n}\n\n// --- Main Logic ---\n\nint main() {\n    // Optimize standard I/O operations.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input parameters: grid size N and number of points M.\n    cin >> N >> M; \n    // M points are provided: (i_0, j_0) is the starting position,\n    // and (i_1, j_1) through (i_{M-1}, j_{M-1}) are the M-1 targets to visit in sequence.\n    all_points.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> all_points[i].first >> all_points[i].second;\n    }\n\n    // Initialize the player's current position to the starting point.\n    current_pos = all_points[0]; \n\n    // Iterate through each target point that needs to be visited.\n    // The targets are all_points[1] up to all_points[M-1].\n    for (int target_idx = 1; target_idx < M; ++target_idx) {\n        pair<int, int> target_pos = all_points[target_idx]; // The current target to reach.\n\n        // Keep planning and executing actions until the current position matches the target position.\n        while (current_pos != target_pos) {\n            int cx = current_pos.first;\n            int cy = current_pos.second;\n            int tx = target_pos.first;\n            int ty = target_pos.second;\n\n            // --- Determine Primary Direction to Move ---\n            char dir_char = ' ';\n            int dr = tx - cx; // Row difference\n            int dc = ty - cy; // Column difference\n\n            // Decide the primary direction:\n            // If the row difference is larger, prioritize vertical movement (Up/Down).\n            // Otherwise, prioritize horizontal movement (Left/Right).\n            // If row and column differences are equal, prioritize horizontal movement.\n            if (abs(dr) > abs(dc)) {\n                if (dr > 0) dir_char = 'D'; // Target is below\n                else dir_char = 'U';        // Target is above\n            } else { \n                if (dc > 0) dir_char = 'R'; // Target is to the right\n                else dir_char = 'L';        // Target is to the left\n            }\n\n            pair<int, int> delta = get_delta(dir_char);\n            int dx = delta.first;\n            int dy = delta.second;\n\n            // Calculate the position of the immediate next square in the chosen direction.\n            int next_r = cx + dx;\n            int next_c = cy + dy;\n\n            // Check if the target square itself contains a block.\n            bool is_target_blocked = blocks.count({tx, ty});\n            char action_to_take = ' '; // Variable to store the determined action.\n\n            // --- Decision Logic for Choosing Action ---\n\n            // Case 1: The target square is blocked AND we are exactly one step away from it.\n            // To visit the target, we must first remove the block.\n            if ((next_r == tx && next_c == ty) && is_target_blocked) {\n                action_to_take = 'A'; // Use Alter to remove the block at the target.\n            }\n            // Case 2: The very next square in our primary direction is blocked.\n            // This means there's an intermediate obstacle. We must clear it to proceed.\n            else if (blocks.count({next_r, next_c})) {\n                action_to_take = 'A'; // Use Alter to remove the intermediate block.\n            }\n            // Case 3: The next square is clear.\n            else {\n                // Calculate the Manhattan distance to the target.\n                int distance_to_target = abs(tx - cx) + abs(ty - cy);\n\n                // Heuristic strategy:\n                // For longer distances (heuristic threshold of 4), and if the target is clear,\n                // using Slide is more efficient for covering ground quickly.\n                // For shorter distances, or if the target is blocked (and we are not adjacent),\n                // using Move provides better precision and control.\n                if (distance_to_target > 4 && !is_target_blocked) {\n                    action_to_take = 'S'; // Prefer Slide for longer distances.\n                } else {\n                    action_to_take = 'M'; // Prefer Move for shorter distances or when target is blocked.\n                }\n            }\n            \n            // Execute the chosen action. This prints the action/direction and updates the game state.\n            execute_action(action_to_take, dir_char);\n        }\n    }\n\n    return 0; // Program finishes after all targets are visited.\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <iomanip>\n#include <numeric>\n#include <chrono>\n#include <tuple>\n\nusing namespace std;\n\n// Use long long for area and large coordinates if needed.\n// For this problem, coordinates are up to 10000, area up to 10^8.\n// int is fine for coordinates. long long for area.\nusing ll = long long;\n\n// Represents an axis-aligned rectangle. Coordinates are [x1, x2) x [y1, y2).\nstruct Rect {\n    int x1, y1, x2, y2;\n    ll area() const { return (ll)(x2 - x1) * (y2 - y1); }\n    int width() const { return x2 - x1; }\n    int height() const { return y2 - y1; }\n};\n\n// Represents a company with its desired location and area.\nstruct Company {\n    int id;\n    int x, y; // Desired point is (x+0.5, y+0.5)\n    ll r;     // Desired area\n};\n\n// Global random number generators for reproducibility and better distribution.\n// Seeded with current time for different runs.\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\nuniform_real_distribution<double> dist_01(0.0, 1.0);\n\n// Function to calculate satisfaction for a single company.\n// p_i = 1 - (1 - min(r_i, s_i) / max(r_i, s_i))^2\ndouble calculate_satisfaction(ll r_i, ll s_i) {\n    if (s_i == 0) return 0.0; // Should not happen with positive area constraint\n    double ratio = (double)min(r_i, s_i) / max(r_i, s_i);\n    return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n}\n\n// Function to find all divisors of a number n.\n// Returns divisors in ascending order.\nvector<ll> get_divisors(ll n) {\n    vector<ll> divisors;\n    for (ll i = 1; i * i <= n; ++i) {\n        if (n % i == 0) {\n            divisors.push_back(i);\n            if (i * i != n) {\n                divisors.push_back(n / i);\n            }\n        }\n    }\n    sort(divisors.begin(), divisors.end());\n    return divisors;\n}\n\n// Structure to hold the result of one complete assignment attempt (one iteration).\nstruct AssignmentResult {\n    // Stores (a, b, c, d) for each company's assigned rectangle.\n    vector<tuple<int, int, int, int>> assignments; \n    // Total satisfaction achieved in this assignment.\n    double total_satisfaction = -1.0; // Initialize to a value lower than any possible satisfaction (0.0).\n};\n\nint N; // Number of companies\nvector<Company> companies_data; // Stores input data for each company.\nvector<Rect> initial_available_regions; // The initial bounding box for space partitioning.\n\n// Number of random trials to perform. This is a key parameter for randomized algorithms.\n// More iterations generally lead to better results but take more time.\nconst int NUM_ITERATIONS = 200; \n\n// The main solver function implementing a randomized recursive partitioning strategy.\nAssignmentResult solve() {\n    AssignmentResult overall_best_result;\n    overall_best_result.assignments.resize(N); // Pre-size for N companies.\n\n    // Indices of companies, used for shuffling and tracking.\n    vector<int> company_indices(N);\n    iota(company_indices.begin(), company_indices.end(), 0); // Fill with 0, 1, ..., N-1.\n\n    // Perform multiple independent trials to explore different random choices.\n    for (int iter = 0; iter < NUM_ITERATIONS; ++iter) {\n        vector<Rect> available_regions = initial_available_regions; // Start with the full 10000x10000 area.\n        vector<int> current_unassigned_companies = company_indices; // Companies yet to be assigned in this iteration.\n        vector<tuple<int, int, int, int>> current_assignments(N); // Stores assignments for this iteration.\n        double current_total_satisfaction = 0.0;\n        bool iteration_failed = false; // Flag to mark if this iteration produced an invalid state.\n\n        // Shuffle companies to process them in a random order for this iteration.\n        shuffle(current_unassigned_companies.begin(), current_unassigned_companies.end(), rng);\n\n        // Assign companies one by one until all are assigned.\n        while (!current_unassigned_companies.empty()) {\n            // Pick the next company to assign. It's the last one in the shuffled list.\n            int company_idx = current_unassigned_companies.back();\n            current_unassigned_companies.pop_back();\n            \n            const Company& company = companies_data[company_idx];\n            ll r_i = company.r;\n\n            // Pick an available region to place this company's ad.\n            // Heuristic: Randomly choose an available region. Other heuristics could be min area, etc.\n            if (available_regions.empty()) {\n                 // This scenario implies an issue: unassigned companies but no space left.\n                 // It suggests the partitioning logic or previous choices were flawed.\n                 iteration_failed = true; \n                 break; // Abandon this iteration.\n            }\n            \n            uniform_int_distribution<int> region_dist(0, available_regions.size() - 1);\n            int region_to_use_idx = region_dist(rng);\n            Rect region = available_regions[region_to_use_idx];\n\n            // Find all possible integer (width, height) pairs that form the desired area r_i\n            // and fit within the chosen region.\n            vector<pair<int, int>> valid_dims;\n            vector<ll> r_i_divisors = get_divisors(r_i); // Get divisors of desired area.\n\n            // Check each divisor 'w' to see if corresponding 'h' fits.\n            for (ll w_ll : r_i_divisors) {\n                int w = static_cast<int>(w_ll); // Cast is safe as w is limited by region.width() <= 10000.\n                if (w > 0 && w <= region.width()) {\n                    ll h_ll = r_i / w;\n                    if (h_ll > 0 && h_ll <= region.height()) {\n                        // If both width and height fit, this is a valid dimension pair.\n                        valid_dims.push_back({w, static_cast<int>(h_ll)}); // Cast is safe as h is limited by region.height() <= 10000.\n                    }\n                }\n            }\n\n            if (valid_dims.empty()) {\n                // If no valid (w, h) pair can form area r_i and fit in the region,\n                // this indicates that the chosen region is too small or has incompatible dimensions for r_i.\n                // Since sum of r_i equals total area, an exact fit should ideally be possible with proper partitioning.\n                // This means the current random choices led to an unresolvable state for this iteration.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose dimensions (w, h) from the list of valid options.\n            // Heuristic: Pick a random pair from valid_dims to explore different shapes.\n            uniform_int_distribution<int> dims_dist(0, valid_dims.size() - 1);\n            pair<int, int> dim = valid_dims[dims_dist(rng)];\n            int w = dim.first;\n            int h = dim.second;\n            \n            // Determine the valid range for the top-left corner (a, b) of the rectangle.\n            // The rectangle [a, a+w) x [b, b+h) must cover the point (company.x+0.5, company.y+0.5).\n            // This means: a <= company.x < a+w AND b <= company.y < b+h.\n            // With integer coordinates, this translates to:\n            // a <= company.x AND a+w >= company.x + 1  => a >= company.x + 1 - w\n            // b <= company.y AND b+h >= company.y + 1  => b >= company.y + 1 - h\n            // Additionally, the rectangle must be within the selected region:\n            // region.x1 <= a AND a+w <= region.x2  => a <= region.x2 - w\n            // region.y1 <= b AND b+h <= region.y2  => b <= region.y2 - h\n            \n            // Combining these constraints to find the valid range for 'a' and 'b'.\n            int min_a = max(region.x1, company.x + 1 - w);\n            int max_a = min(region.x2 - w, company.x);\n            int min_b = max(region.y1, company.y + 1 - h);\n            int max_b = min(region.y2 - h, company.y);\n\n            if (min_a > max_a || min_b > max_b) {\n                // If the valid ranges are empty, it means no position 'a' or 'b' exists\n                // to satisfy all conditions simultaneously. This should ideally not happen\n                // if previous steps (finding valid_dims) were correct and the point is indeed within the region.\n                iteration_failed = true; \n                break; // Abandon this iteration.\n            }\n\n            // Choose the placement (a, b).\n            // Heuristic: Push the rectangle to the top-left corner (min_a, min_b) of its valid placement range.\n            // This aims to leave larger contiguous areas in the remaining space, potentially aiding future assignments.\n            int a = min_a;\n            int b = min_b;\n            \n            // Assign the rectangle [a, a+w) x [b, b+h) to the company.\n            current_assignments[company_idx] = {a, b, a + w, b + h};\n            ll s_i = (ll)w * h; // Actual area assigned.\n            // Accumulate satisfaction for this company.\n            current_total_satisfaction += calculate_satisfaction(r_i, s_i);\n\n            // Update the list of available regions.\n            // Remove the region that was just used.\n            available_regions.erase(available_regions.begin() + region_to_use_idx);\n\n            // Add the new regions created by partitioning the used region R with the assigned rectangle R_idx.\n            Rect assigned_rect = {a, b, a + w, b + h};\n            \n            // Add region to the left of the assigned rectangle, if it has positive width.\n            if (region.x1 < assigned_rect.x1) {\n                available_regions.push_back({region.x1, region.y1, assigned_rect.x1, region.y2});\n            }\n            // Add region to the right, if it has positive width.\n            if (assigned_rect.x2 < region.x2) {\n                available_regions.push_back({assigned_rect.x2, region.y1, region.x2, region.y2});\n            }\n            // Add region below the assigned rectangle, if it has positive height.\n            if (region.y1 < assigned_rect.y1) {\n                available_regions.push_back({assigned_rect.x1, region.y1, assigned_rect.x2, assigned_rect.y1});\n            }\n            // Add region above the assigned rectangle, if it has positive height.\n            if (assigned_rect.y2 < region.y2) {\n                available_regions.push_back({assigned_rect.x1, assigned_rect.y2, assigned_rect.x2, region.y2});\n            }\n        } // End of while loop: assigning companies within one iteration.\n\n        // After assigning all companies for this iteration, check if it was successful and if it's better than the overall best found so far.\n        if (!iteration_failed && current_total_satisfaction > overall_best_result.total_satisfaction) {\n            overall_best_result.total_satisfaction = current_total_satisfaction;\n            overall_best_result.assignments = current_assignments;\n        }\n    } // End of loop: performing multiple iterations.\n\n    // The problem implies a valid solution is always achievable. If overall_best_result.total_satisfaction is still -1.0,\n    // it means all iterations failed, indicating a potential issue with the algorithm or heuristics.\n    // However, with enough iterations and a reasonable algorithm, at least one should yield a valid assignment.\n\n    return overall_best_result;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n    companies_data.resize(N);\n    ll total_r_sum = 0; // For verification, though problem guarantees sum r_i = 10^8.\n    for (int i = 0; i < N; ++i) {\n        companies_data[i].id = i;\n        cin >> companies_data[i].x >> companies_data[i].y >> companies_data[i].r;\n        total_r_sum += companies_data[i].r;\n    }\n\n    // The problem statement guarantees that the sum of desired areas equals the total area of the 10000x10000 space.\n    // This is a strong hint that an optimal solution involves no wasted space (sum of assigned areas = total area).\n\n    // Initialize the initial available region: the entire 10000x10000 canvas.\n    initial_available_regions.push_back({0, 0, 10000, 10000});\n\n    // Run the solver to get the best assignment found.\n    AssignmentResult final_assignment = solve();\n\n    // Output the resulting rectangle coordinates for each company.\n    for (int i = 0; i < N; ++i) {\n        cout << get<0>(final_assignment.assignments[i]) << \" \"\n             << get<1>(final_assignment.assignments[i]) << \" \"\n             << get<2>(final_assignment.assignments[i]) << \" \"\n             << get<3>(final_assignment.assignments[i]) << \"\\n\";\n    }\n\n    return 0;\n}","ahc002":"#include <iostream>\n#include <string>\n#include <vector> // Included for general utility, though not strictly used by the final greedy logic\n#include <algorithm> // Included for general utility, e.g., std::fill could be used for initialization\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 50;\n\n// Global arrays for grid data and visited status.\n// Static allocation is used as the grid size is fixed and memory limits are generous.\nint grid[N][N]; // Stores the score p_ij for each square (0 <= p_ij <= 99)\nint tile_map[N][N]; // Stores the tile ID t_ij for each square (0 <= t_ij <= M-1)\nint max_tile_id_plus_1 = 0; // Tracks the total number of unique tiles (M). M is max_tile_id + 1.\n\nbool visited_squares[N][N]; // Boolean matrix to ensure path simplicity (no revisiting squares).\n// The maximum possible tile ID is N*N - 1 (e.g., if all tiles are 1x1 and N*N distinct tiles exist).\n// Thus, an array of size N*N is sufficient to cover all possible tile IDs from 0 to N*N-1.\nbool used_tiles[N * N]; \n\n// Movement directions: Up, Down, Left, Right.\n// These arrays define the change in row (dr) and column (dc) for each of the four cardinal directions.\nint dr[] = {-1, 1, 0, 0}; \nint dc[] = {0, 0, -1, 1};\n// Corresponding characters for outputting the path. 'U' for Up, 'D' for Down, 'L' for Left, 'R' for Right.\nchar move_char[] = {'U', 'D', 'L', 'R'};\n\nint main() {\n    // Optimize C++ standard streams for faster input/output operations, crucial in competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the initial position (si, sj) from standard input.\n    int si, sj;\n    cin >> si >> sj;\n\n    // Read the grid scores p_ij for all 50x50 squares.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    // Read the tile map t_ij for all squares and determine the total number of unique tiles (M).\n    // The problem states that tile IDs range from 0 to M-1, so M is `max_tile_id + 1`.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> tile_map[i][j];\n            // Update `max_tile_id_plus_1` if a tile ID implies a larger total number of tiles.\n            if (tile_map[i][j] + 1 > max_tile_id_plus_1) {\n                max_tile_id_plus_1 = tile_map[i][j] + 1;\n            }\n        }\n    }\n\n    // Initialize `visited_squares` matrix. Initially, no squares have been visited.\n    // A simple nested loop is efficient for initializing fixed-size arrays.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_squares[i][j] = false;\n        }\n    }\n    \n    // Initialize `used_tiles` array. Initially, no tiles are considered used.\n    // We only need to initialize entries corresponding to actual tile IDs, from 0 up to M-1.\n    for(int i = 0; i < max_tile_id_plus_1; ++i) {\n        used_tiles[i] = false;\n    }\n\n    string path_string = \"\"; // This string will store the sequence of moves (e.g., \"UDLRU\").\n    int current_r = si;    // Initialize current row position to the starting row.\n    int current_c = sj;    // Initialize current column position to the starting column.\n\n    // Mark the starting square as visited and its corresponding tile as used.\n    // This is because Takahashi starts on this square, and it counts as being stepped on.\n    visited_squares[current_r][current_c] = true;\n    // The tile ID at the starting position is guaranteed to be a valid index into `used_tiles`.\n    used_tiles[tile_map[current_r][current_c]] = true;\n\n    // Main loop for constructing the path using a greedy strategy.\n    // The loop continues as long as there are valid moves to make.\n    while (true) {\n        int best_neighbor_score = -1; // Stores the score of the best valid neighbor found. Initialized to -1 to ensure any non-negative score is considered better.\n        int best_dr = -1, best_dc = -1; // Stores the row and column delta for the best move.\n        char best_move_char = ' ';      // Stores the character representation ('U', 'D', 'L', 'R') of the best move.\n\n        // Explore all 4 possible adjacent squares from the current position.\n        for (int i = 0; i < 4; ++i) {\n            int nr = current_r + dr[i]; // Calculate the row of the neighboring square.\n            int nc = current_c + dc[i]; // Calculate the column of the neighboring square.\n\n            // Constraint 1: Boundary Check.\n            // Ensure the neighboring square is within the 50x50 grid limits.\n            if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n                continue; // Skip this neighbor if it's out of bounds.\n            }\n\n            // Constraint 2: Path Simplicity Check.\n            // Ensure the neighboring square has not been visited before in the current path.\n            if (visited_squares[nr][nc]) {\n                continue; // Skip if the square is already visited.\n            }\n\n            // Constraint 3: Tile Usage Check.\n            // Ensure the tile covering this neighboring square has not been used yet.\n            // `tile_map[nr][nc]` is a valid index because `max_tile_id_plus_1` was determined from all tile IDs present in the input.\n            if (used_tiles[tile_map[nr][nc]]) {\n                continue; // Skip if the tile is already used.\n            }\n\n            // If the move to (nr, nc) is valid according to all constraints:\n            // Apply the greedy heuristic: Select the valid neighbor that offers the highest score (`grid[nr][nc]`).\n            if (grid[nr][nc] > best_neighbor_score) {\n                best_neighbor_score = grid[nr][nc]; // Update the highest score found so far.\n                best_dr = dr[i];                    // Record the direction of this best move.\n                best_dc = dc[i];\n                best_move_char = move_char[i];      // Record the character for this best move.\n            }\n        } // End of loop exploring neighbors.\n\n        // If `best_neighbor_score` remained -1, it means no valid moves were found from the current position.\n        // This signifies the end of the path.\n        if (best_neighbor_score == -1) {\n            break; // Exit the path construction loop.\n        }\n\n        // Execute the best move identified:\n        // Update the current position to the coordinates of the chosen neighbor.\n        current_r += best_dr;\n        current_c += best_dc;\n        // Mark the newly entered square as visited to maintain path simplicity.\n        visited_squares[current_r][current_c] = true; \n        // Mark the tile covering this new square as used, enforcing the tile constraint.\n        used_tiles[tile_map[current_r][current_c]] = true; \n        // Append the character representing this move to the output path string.\n        path_string += best_move_char; \n    }\n\n    // Output the generated path string to standard output.\n    cout << path_string << endl;\n\n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <cmath>\n#include <iomanip>\n#include <limits>\n#include <algorithm> // For std::reverse, std::min, std::max\n\nusing namespace std;\n\n// Grid dimensions\nconst int N = 30;\n// Represents infinity for distances\nconst double INF = numeric_limits<double>::infinity();\n\n// --- Edge Weights ---\n// h_weights[i][j] stores the weight of the horizontal edge between (i, j) and (i, j+1).\n// i: row index (0 to 29), j: column index (0 to 28).\ndouble h_weights[N][N - 1];\n// v_weights[i][j] stores the weight of the vertical edge between (i, j) and (i+1, j).\n// i: row index (0 to 28), j: column index (0 to 29).\ndouble v_weights[N - 1][N];\n\n// --- Dijkstra's Algorithm Data Structures ---\n// Stores the predecessor vertex for path reconstruction. pred[r][c] = {pr, pc}\npair<int, int> pred[N][N];\n// Stores the shortest estimated distance from the start node to (r, c).\ndouble dist[N][N];\n\n// --- Constants for Learning ---\n// Initial learning rate for simple linear decay (INITIAL_LR / k).\n// The current best score was achieved with INITIAL_LR = 13.0.\n// Trying a further increase to 14.0 to potentially accelerate learning slightly,\n// while retaining the successful linear decay strategy and no tanh.\nconst double INITIAL_LR = 14.0; \n\n// Maximum absolute value for a single edge weight update (delta_per_edge).\n// Prevents extreme weight changes that could destabilize learning. 2000.0 was used in the\n// successful submission (score 40.84B), so we keep it.\nconst double MAX_DELTA_PER_EDGE = 2000.0; \n\n// --- Helper Functions ---\n\n// Gets the weight of the edge between two adjacent vertices (r1, c1) and (r2, c2).\n// Assumes (r1, c1) and (r2, c2) are indeed adjacent.\ndouble get_weight(int r1, int c1, int r2, int c2) {\n    if (r1 == r2) { // Horizontal edge: same row, different columns\n        // Ensure c_min is the smaller column index for array access\n        int c_min = min(c1, c2);\n        return h_weights[r1][c_min];\n    } else { // Vertical edge: same column, different rows\n        // Ensure r_min is the smaller row index for array access\n        int r_min = min(r1, r2);\n        return v_weights[r_min][c1]; // c1 == c2 for vertical edges\n    }\n}\n\n// Updates the weight of the edge between (r1, c1) and (r2, c2) by adding 'delta'.\n// Ensures the weight does not drop below 1.0 (as edge weights must be positive).\nvoid update_weight(int r1, int c1, int r2, int c2, double delta) {\n    if (r1 == r2) { // Horizontal edge\n        int c_min = min(c1, c2);\n        h_weights[r1][c_min] = max(1.0, h_weights[r1][c_min] + delta);\n    } else { // Vertical edge\n        int r_min = min(r1, r2);\n        v_weights[r_min][c1] = max(1.0, v_weights[r_min][c1] + delta);\n    }\n}\n\n// Dijkstra's algorithm to find the shortest path from start_node to end_node\n// using the current estimated edge weights.\nvoid dijkstra(pair<int, int> start_node, pair<int, int> end_node) {\n    // Initialize distances to infinity and predecessors to an invalid state.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            dist[i][j] = INF;\n            pred[i][j] = {-1, -1}; // Sentinel value indicating no predecessor\n        }\n    }\n\n    // Distance to the start node is 0.\n    dist[start_node.first][start_node.second] = 0;\n\n    // Priority queue stores {negative_distance, {row, col}}.\n    // Using negative distance simulates a min-priority queue with std::priority_queue.\n    // This prioritizes nodes with smaller distances.\n    priority_queue<pair<double, pair<int, int>>> pq;\n    pq.push({0.0, start_node});\n\n    // Possible moves: Up, Down, Left, Right.\n    int dr[] = {-1, 1, 0, 0}; \n    int dc[] = {0, 0, -1, 1};\n\n    while (!pq.empty()) {\n        // Get the node with the smallest distance from the priority queue.\n        auto [d, curr_node] = pq.top();\n        pq.pop();\n        d = -d; // Convert negative distance back to positive.\n\n        int r = curr_node.first;\n        int c = curr_node.second;\n\n        // If the extracted distance is greater than the known shortest distance, skip.\n        // This can happen if a shorter path to 'curr_node' was found and pushed later.\n        if (d > dist[r][c]) {\n            continue;\n        }\n        \n        // Optimization: If we have reached the destination, we can stop.\n        // Since edge weights are positive, this path is guaranteed to be the shortest.\n        if (curr_node == end_node) {\n            break; \n        }\n\n        // Explore neighbors.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid boundaries.\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                double weight = get_weight(r, c, nr, nc);\n                // If a shorter path to the neighbor is found, update distance and predecessor.\n                if (dist[r][c] + weight < dist[nr][nc]) {\n                    dist[nr][nc] = dist[r][c] + weight;\n                    pred[nr][nc] = {r, c}; // Set current node as predecessor for neighbor.\n                    pq.push({-dist[nr][nc], {nr, nc}}); // Add neighbor to priority queue.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // --- Initialization ---\n    // Initialize all edge weights to a starting guess.\n    // Edge generation values are typically in the range [1000, 9000].\n    // 5000.0 is a reasonable midpoint, central to the expected range.\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N - 1; ++j) { // Horizontal edges\n            h_weights[i][j] = 5000.0;\n        }\n    }\n    for (int i = 0; i < N - 1; ++i) { // Vertical edges\n        for (int j = 0; j < N; ++j) {\n            v_weights[i][j] = 5000.0;\n        }\n    }\n\n    // --- Process Queries ---\n    for (int k = 1; k <= 1000; ++k) {\n        // Read start and end nodes for the current query.\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        pair<int, int> start_node = {si, sj};\n        pair<int, int> end_node = {ti, tj};\n\n        // Find the shortest path using Dijkstra with current estimated weights.\n        dijkstra(start_node, end_node);\n\n        // --- Path Reconstruction and Output ---\n        string path_str = \"\";\n        double estimated_path_length = 0.0;\n        \n        // Store vertices temporarily to reconstruct path and then iterate to build string and sum length.\n        vector<pair<int, int>> path_trace;\n        pair<int, int> curr = end_node;\n        while (!(curr.first == -1 && curr.second == -1)) { // Stop if predecessor is invalid (-1,-1)\n            path_trace.push_back(curr);\n            if (curr == start_node) break; // Reached the start node\n            curr = pred[curr.first][curr.second];\n        }\n        // The path_trace is collected in reverse order (end to start). Reverse it.\n        reverse(path_trace.begin(), path_trace.end()); // Path from start to end.\n\n        // If start and end nodes are different, generate the path string and calculate estimated length.\n        if (path_trace.size() > 1) { \n            for (size_t i = 0; i + 1 < path_trace.size(); ++i) {\n                pair<int, int> u = path_trace[i]; // Current vertex\n                pair<int, int> v = path_trace[i+1]; // Next vertex\n\n                // Add the weight of the edge (u, v) to the estimated path length.\n                estimated_path_length += get_weight(u.first, u.second, v.first, v.second);\n\n                // Determine the move direction and append to the path string.\n                if (u.first < v.first) path_str += 'D'; // Moved Down (row index increased)\n                else if (u.first > v.first) path_str += 'U'; // Moved Up (row index decreased)\n                else if (u.second < v.second) path_str += 'R'; // Moved Right (column index increased)\n                else if (u.second > v.second) path_str += 'L'; // Moved Left (column index decreased)\n            }\n        }\n        \n        // Output the generated path string.\n        cout << path_str << endl;\n        // Flush the output buffer. This is crucial for the judge to receive the output promptly.\n        cout << flush;\n\n        // --- Feedback and Weight Update ---\n        // Read the feedback integer from the judge. This is a noisy measurement of the path's actual length.\n        long long feedback_k_ll; \n        cin >> feedback_k_ll;\n        double feedback_k = static_cast<double>(feedback_k_ll);\n\n        // Calculate the number of edges in the found path.\n        int num_edges = path_trace.size() - 1;\n        \n        // Only update weights if the path consists of at least one edge (start != end).\n        if (num_edges > 0) { \n            // Calculate the error: difference between observed feedback and estimated length.\n            double error = feedback_k - estimated_path_length;\n            \n            // Calculate the learning rate using simple linear decay (INITIAL_LR / k).\n            // This strategy has yielded the highest scores.\n            // Incrementing INITIAL_LR to 14.0 from 13.0.\n            double learning_rate = INITIAL_LR / k; \n            \n            // Use raw error without tanh for error smoothing, as it performed best.\n            double robust_error = error; \n\n            // Calculate the update amount to be applied to each edge in the path.\n            double delta_per_edge = learning_rate * robust_error / num_edges;\n            \n            // Clamp the delta_per_edge to prevent excessively large weight updates.\n            delta_per_edge = std::max(-MAX_DELTA_PER_EDGE, std::min(MAX_DELTA_PER_EDGE, delta_per_edge));\n            \n            // Update the weights of all edges that constitute the found path.\n            for (size_t i = 0; i + 1 < path_trace.size(); ++i) {\n                pair<int, int> u = path_trace[i];\n                pair<int, int> v = path_trace[i+1];\n                update_weight(u.first, u.second, v.first, v.second, delta_per_edge);\n            }\n        }\n    }\n\n    return 0; // Program finished successfully.\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <set>\n#include <tuple>\n#include <numeric> // For iota\n#include <chrono> // For time-based seed\n\nusing namespace std;\n\nint N;\nint M;\nvector<string> s;\n\n// Matrix characters\nconst char EMPTY = '.';\nconst vector<char> ALPHABET = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nstruct Placement {\n    int string_idx;\n    int r, c, dir; // dir: 0 for horizontal, 1 for vertical\n    vector<pair<int, int>> cells; // List of (row, col) for this placement\n    int id_in_string; // Unique ID for this placement within string_idx\n};\n\nvector<vector<Placement>> all_placements_for_string;\n// cell_users[r][c] stores a list of (string_idx, placement_id_in_string, pos_in_placement) for all placements using cell (r,c).\nvector<vector<vector<tuple<int, int, int>>>> cell_users; \n\n// State tracking variables\nvector<vector<bool>> placement_validity; // Stores validity for each placement in the current matrix A\nvector<int> valid_placement_count; // Stores total number of valid placements for each string\nvector<bool> is_matched; // Stores if a string is matched (has at least one valid placement)\nint num_matched; // Total number of matched strings\nlong long total_cells_filled; // Number of non-empty cells in the matrix\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Helper for toroidal coordinates\nint mod(int a, int b) {\n    return (a % b + b) % b;\n}\n\n// Calculate score based on current state\nlong double calculate_score_value() {\n    if (num_matched < M) {\n        // Score for not all strings matched: 10^8 * c / M\n        return 1e8 * (long double)num_matched / M;\n    } else {\n        // Score for all strings matched: 10^8 * 2 N^2 / (2 N^2 - d)\n        // d = N*N - total_cells_filled is the number of dots\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) { // Avoid division by zero or very small numbers\n            return 2e8; // Effectively max score, or a very high value\n        }\n        return 1e8 * term_numerator / term_denominator;\n    }\n}\n\n// Check if a specific placement is valid in the given matrix A\nbool is_placement_valid(const Placement& p, const vector<string>& A) {\n    for (size_t i = 0; i < p.cells.size(); ++i) {\n        int r_cell = p.cells[i].first;\n        int c_cell = p.cells[i].second;\n        // A cell is valid for this placement if it's empty or matches the required character\n        if (A[r_cell][c_cell] != EMPTY && A[r_cell][c_cell] != s[p.string_idx][i]) {\n            return false; // Conflict found\n        }\n    }\n    return true; // No conflicts\n}\n\n// Attempts to make a move by changing A[r][c] to new_char.\n// Returns true if the move is accepted and applied, false otherwise.\nbool try_move(vector<string>& A, int r, int c, char new_char) {\n    char old_char = A[r][c];\n    if (old_char == new_char) return false; // No change, skip.\n\n    // --- Store current state for comparison and potential revert ---\n    long double current_score_val = calculate_score_value();\n    // FIX: Store the current global num_matched before any changes.\n    int current_num_matched_snapshot = num_matched; \n    long long current_total_cells_filled = total_cells_filled;\n    \n    // Identify strings potentially affected by changing cell (r,c)\n    set<int> potentially_affected_string_indices;\n    for (const auto& user : cell_users[r][c]) {\n        potentially_affected_string_indices.insert(get<0>(user)); // string_idx\n    }\n\n    // Store old total valid counts for affected strings to revert if the move is rejected.\n    vector<pair<int, int>> old_valid_counts_for_affected;\n    for(int s_idx : potentially_affected_string_indices) {\n        old_valid_counts_for_affected.push_back({s_idx, valid_placement_count[s_idx]});\n    }\n\n    // --- Tentatively apply the change to A ---\n    A[r][c] = new_char;\n\n    // --- Calculate potential new state and score ---\n    // Start potential_num_matched from the snapshot of the current state.\n    int potential_num_matched = current_num_matched_snapshot; \n    long long potential_total_cells_filled = current_total_cells_filled;\n\n    // Update cell count\n    if (old_char == EMPTY && new_char != EMPTY) potential_total_cells_filled++;\n    if (old_char != EMPTY && new_char == EMPTY) potential_total_cells_filled--;\n\n    // Recalculate match status and valid_placement_count for affected strings\n    for (int s_idx : potentially_affected_string_indices) {\n        int new_total_valid_count = 0;\n        // Re-evaluate validity of ALL placements for this string in the *tentatively modified* grid A.\n        for(size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n            if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                new_total_valid_count++;\n            }\n        }\n        \n        // Check if the match status of the string changes.\n        bool was_matched = (valid_placement_count[s_idx] > 0); // Use current global count from before the move.\n        bool now_matched = (new_total_valid_count > 0);\n\n        if (was_matched && !now_matched) {\n            potential_num_matched--; // String becomes unmatched\n        } else if (!was_matched && now_matched) {\n            potential_num_matched++; // String becomes matched\n        }\n        // Tentatively update the global valid_placement_count for this s_idx for use in score calculation.\n        // This value will be restored if the move is rejected.\n        valid_placement_count[s_idx] = new_total_valid_count; \n    }\n\n    // Calculate potential score\n    long double potential_score_val;\n    if (potential_num_matched < M) {\n        potential_score_val = 1e8 * (long double)potential_num_matched / M;\n    } else {\n        long double term_numerator = 2.0L * N * N;\n        long double d = (long double)N * N - potential_total_cells_filled;\n        long double term_denominator = term_numerator - d;\n        \n        if (term_denominator <= 1e-9) {\n            potential_score_val = 2e8; // Max score\n        } else {\n            potential_score_val = 1e8 * term_numerator / term_denominator;\n        }\n    }\n\n    // --- Acceptance criteria ---\n    bool accept = false;\n    if (potential_score_val > current_score_val) {\n        accept = true; // Always accept if score improves\n    } else if (abs(potential_score_val - current_score_val) < 1e-9) { // Scores are approximately equal\n        // Tie-breaking: If all strings are matched (c=M), prefer fewer dots.\n        // FIX: Use the snapshot of current_num_matched here.\n        if (potential_num_matched == M && current_num_matched_snapshot == M) { \n            if (potential_total_cells_filled > current_total_cells_filled) { // Prefer filling more cells\n                accept = true;\n            }\n        }\n    }\n\n    if (accept) {\n        // Apply changes permanently\n        total_cells_filled = potential_total_cells_filled;\n        num_matched = potential_num_matched; // Update global num_matched.\n        \n        // Update `is_matched` based on the final `valid_placement_count` for affected strings.\n        for(int s_idx : potentially_affected_string_indices) {\n            is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n        }\n        return true;\n    } else {\n        // Revert changes if move is not accepted\n        A[r][c] = old_char; // Revert matrix cell\n        \n        // Revert `valid_placement_count` for affected strings.\n        for(const auto& state : old_valid_counts_for_affected) {\n            int s_idx_revert = state.first;\n            int old_count = state.second;\n            valid_placement_count[s_idx_revert] = old_count;\n        }\n        // num_matched and total_cells_filled are implicitly restored by not updating the global variables if not accepted.\n        return false;\n    }\n}\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M;\n    s.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> s[i];\n    }\n\n    // Precomputation: Generate all possible placements for all strings.\n    // For each string, a placement is defined by its starting row, starting column, and direction (horizontal/vertical).\n    all_placements_for_string.resize(M);\n    cell_users.resize(N, vector<vector<tuple<int, int, int>>>(N, vector<tuple<int, int, int>>()));\n    \n    for (int i = 0; i < M; ++i) {\n        int k = s[i].length();\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                // Horizontal placement\n                Placement p_h;\n                p_h.string_idx = i;\n                p_h.r = r; p_h.c = c; p_h.dir = 0; // 0 for horizontal\n                p_h.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_h.cells[pi] = {r, mod(c + pi, N)};\n                }\n                p_h.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_h);\n\n                // Vertical placement\n                Placement p_v;\n                p_v.string_idx = i;\n                p_v.r = r; p_v.c = c; p_v.dir = 1; // 1 for vertical\n                p_v.cells.resize(k);\n                for (int pi = 0; pi < k; ++pi) {\n                    p_v.cells[pi] = {mod(r + pi, N), c};\n                }\n                p_v.id_in_string = all_placements_for_string[i].size(); // Unique ID for this placement within string i\n                all_placements_for_string[i].push_back(p_v);\n            }\n        }\n    }\n\n    // Populate cell_users: map each cell to which placements use it.\n    // This is crucial for efficiently finding affected strings when a cell changes.\n    for (int i = 0; i < M; ++i) {\n        for (size_t j = 0; j < all_placements_for_string[i].size(); ++j) {\n            const auto& p = all_placements_for_string[i][j];\n            for (size_t cell_idx = 0; cell_idx < p.cells.size(); ++cell_idx) {\n                int r_cell = p.cells[cell_idx].first;\n                int c_cell = p.cells[cell_idx].second;\n                cell_users[r_cell][c_cell].emplace_back(i, j, cell_idx); // Store (string_idx, placement_id_in_string, pos_in_placement)\n            }\n        }\n    }\n\n    // Initialize matrix and state tracking variables.\n    vector<string> A(N, string(N, EMPTY));\n    total_cells_filled = 0;\n\n    placement_validity.resize(M);\n    valid_placement_count.resize(M, 0);\n    is_matched.resize(M, false);\n    num_matched = 0;\n\n    // Initialize `placement_validity`, `valid_placement_count`, `is_matched` based on the initial empty matrix.\n    for (int i = 0; i < M; ++i) {\n        placement_validity[i].resize(all_placements_for_string[i].size(), false);\n        valid_placement_count[i] = 0; // Initially 0 valid placements for any string\n        is_matched[i] = false; // Initially no string is matched\n    }\n    num_matched = 0; // Initially 0 strings are matched\n\n    // --- Greedy Seeding Phase ---\n    // Iteratively fills the matrix to match as many strings as possible.\n    // Prioritizes placements that use fewer new cells (dots).\n    int max_greedy_passes = 5; // Limit passes to prevent infinite loops if greedy gets stuck.\n    for(int pass = 0; pass < max_greedy_passes; ++pass) {\n        bool new_match_made_in_pass = false;\n        \n        // Process strings in a random order to avoid consistent bias.\n        vector<int> string_order(M);\n        iota(string_order.begin(), string_order.end(), 0);\n        shuffle(string_order.begin(), string_order.end(), rng);\n\n        for (int s_idx : string_order) {\n            if (is_matched[s_idx]) continue; // Skip if already matched.\n\n            int best_p_id = -1;\n            int min_dots_used_for_best_p = N*N + 1; // Initialize with a value larger than possible\n\n            // Find the best valid placement for string `s_idx` in the current matrix `A`.\n            for (size_t p_id = 0; p_id < all_placements_for_string[s_idx].size(); ++p_id) {\n                if (is_placement_valid(all_placements_for_string[s_idx][p_id], A)) {\n                    // Calculate how many currently empty cells this placement would fill.\n                    int current_dots_used = 0;\n                    for (const auto& cell : all_placements_for_string[s_idx][p_id].cells) {\n                        if (A[cell.first][cell.second] == EMPTY) {\n                            current_dots_used++;\n                        }\n                    }\n\n                    // Prioritize placements that require filling fewer empty cells.\n                    if (current_dots_used < min_dots_used_for_best_p) {\n                        min_dots_used_for_best_p = current_dots_used;\n                        best_p_id = p_id;\n                    }\n                }\n            }\n            \n            // If a valid placement was found, apply it to the matrix.\n            if (best_p_id != -1) {\n                const auto& p_to_apply = all_placements_for_string[s_idx][best_p_id];\n                for (const auto& cell : p_to_apply.cells) {\n                    if (A[cell.first][cell.second] == EMPTY) {\n                        // Find the character for this cell from the string `s[s_idx]`.\n                        int cell_pos = -1;\n                        for(size_t pi = 0; pi < p_to_apply.cells.size(); ++pi) {\n                            if (p_to_apply.cells[pi] == cell) {\n                                cell_pos = pi;\n                                break;\n                            }\n                        }\n                        A[cell.first][cell.second] = s[s_idx][cell_pos];\n                        total_cells_filled++; // Increment filled cell count.\n                    }\n                }\n                \n                // Update match status for `s_idx` and global `num_matched`.\n                bool string_s_was_matched = is_matched[s_idx];\n                // Re-evaluate validity for all placements of `s_idx` to get its new status.\n                valid_placement_count[s_idx] = 0;\n                for(size_t p_id_check = 0; p_id_check < all_placements_for_string[s_idx].size(); ++p_id_check) {\n                    placement_validity[s_idx][p_id_check] = is_placement_valid(all_placements_for_string[s_idx][p_id_check], A);\n                    if (placement_validity[s_idx][p_id_check]) {\n                        valid_placement_count[s_idx]++;\n                    }\n                }\n                is_matched[s_idx] = (valid_placement_count[s_idx] > 0);\n                \n                if (!string_s_was_matched && is_matched[s_idx]) {\n                    num_matched++; // A new string has become matched.\n                    new_match_made_in_pass = true; // Indicate that progress was made in this pass.\n                }\n                \n                // Propagate match status updates to other strings potentially affected by the newly filled cells.\n                // Collect all strings that use any of the cells that were just filled by `p_to_apply`.\n                set<int> strings_potentially_affected_by_fill;\n                for(const auto& cell : p_to_apply.cells) {\n                    // For each cell in the placement that was just filled:\n                    for (const auto& user : cell_users[cell.first][cell.second]) {\n                        strings_potentially_affected_by_fill.insert(get<0>(user)); // Add the string_idx of users.\n                    }\n                }\n                \n                // Re-evaluate match status for these potentially affected strings.\n                for(int affected_s_idx : strings_potentially_affected_by_fill) {\n                    if (affected_s_idx == s_idx) continue; // Skip the string that was just matched.\n\n                    bool was_matched_affected = is_matched[affected_s_idx];\n                    \n                    // Re-evaluate validity for all placements of `affected_s_idx`.\n                    valid_placement_count[affected_s_idx] = 0;\n                    for(size_t p_id_check = 0; p_id_check < all_placements_for_string[affected_s_idx].size(); ++p_id_check) {\n                        placement_validity[affected_s_idx][p_id_check] = is_placement_valid(all_placements_for_string[affected_s_idx][p_id_check], A);\n                        if (placement_validity[affected_s_idx][p_id_check]) {\n                            valid_placement_count[affected_s_idx]++;\n                        }\n                    }\n                    \n                    bool now_matched_affected = (valid_placement_count[affected_s_idx] > 0);\n\n                    // Update global `num_matched` and `is_matched` if the status changed.\n                    if (was_matched_affected && !now_matched_affected) {\n                        is_matched[affected_s_idx] = false;\n                        num_matched--;\n                        new_match_made_in_pass = true; // Progress made.\n                    } else if (!was_matched_affected && now_matched_affected) {\n                        is_matched[affected_s_idx] = true;\n                        num_matched++;\n                        new_match_made_in_pass = true; // Progress made.\n                    }\n                }\n            }\n        }\n        // If no new strings were matched in a full pass, the greedy phase is done.\n        if (!new_match_made_in_pass) break;\n    }\n\n    // --- Local Search Phase ---\n    // Use simulated annealing-like random walk to improve the solution.\n    // The number of iterations is adjusted based on M to balance exploration and time limit.\n    int ITER_COUNT = 100000;\n    if (M > 600) ITER_COUNT = 80000;\n    if (M > 700) ITER_COUNT = 60000;\n    if (M > 750) ITER_COUNT = 50000;\n    if (M > 780) ITER_COUNT = 40000; // Conservative for high M\n\n    uniform_int_distribution<int> dist_N(0, N - 1);\n    // Distribution for choosing character or EMPTY.\n    // FIX: Cast ALPHABET.size() to int for signed comparison.\n    int char_alphabet_size = static_cast<int>(ALPHABET.size());\n    uniform_int_distribution<int> dist_char_or_empty(0, char_alphabet_size); // Range [0, ALPHABET.size()] inclusive.\n\n    for (int iter = 0; iter < ITER_COUNT; ++iter) {\n        // Pick a random cell to modify.\n        int r = dist_N(rng);\n        int c = dist_N(rng);\n        char old_char = A[r][c];\n        \n        char new_char;\n        // Strategy for choosing the new character depends on whether all strings are matched.\n        if (num_matched == M) { \n            // If all strings are matched, the primary goal is to reduce dots (maximize filled cells).\n            // The best move is to change a character to EMPTY, if possible.\n            if (old_char != EMPTY) {\n                new_char = EMPTY;\n            } else {\n                // If the cell is already EMPTY, changing it to a character will increase dots and decrease score.\n                // So, we skip this iteration, as such a move is unlikely to be beneficial.\n                continue;\n            }\n        } else { \n            // If not all strings are matched, the priority is to match more strings.\n            // Try changing the cell to a random character from the alphabet or to EMPTY.\n            int char_choice = dist_char_or_empty(rng);\n            if (char_choice < char_alphabet_size) { // If not EMPTY index\n                new_char = ALPHABET[char_choice];\n            } else { // If chosen index corresponds to EMPTY\n                new_char = EMPTY;\n            }\n        }\n        \n        // Attempt the move. The `try_move` function handles score evaluation and state updates.\n        try_move(A, r, c, new_char);\n    }\n\n    // Output the final resulting matrix.\n    for (int i = 0; i < N; ++i) {\n        cout << A[i] << '\\n';\n    }\n\n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <utility>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <tuple>\n#include <bitset>\n\nusing namespace std;\n\n// Use a large enough value for infinity for Dijkstra distances\nconst long long INF = 1e18;\n\nint N; // Grid size\nint si, sj; // Starting row and column\nvector<string> grid; // Stores the grid characters ('#', '5'-'9')\nvector<vector<int>> cost_grid; // Stores the cost to enter a road square\nvector<pair<int, int>> road_coords; // Stores {row, col} for all road squares\nmap<pair<int, int>, int> coord_to_id; // Maps {row, col} to a unique ID for road squares\n\n// Maximum possible number of road squares for N <= 69.\n// N*N <= 69*69 = 4761.\nconst int MAX_ROADS = 4761; \n\n// visible_from_bitset[r][c] is a bitset where the k-th bit is set if road with ID k is visible from (r, c).\nvector<vector<bitset<MAX_ROADS>>> visible_from_bitset; \n\n// adj_grid[r][c] stores a list of {neighbor_r, neighbor_c} for road squares adjacent to (r,c).\nvector<vector<vector<pair<int, int>>>> adj_grid; \n\n// Bitset for tracking covered roads. The k-th bit is 1 if road with ID k is covered.\nbitset<MAX_ROADS> is_road_covered_bitset; \n\npair<int, int> current_pos; // Current position of the patrol car\nlong long total_time = 0; // Total travel time of the route\nvector<pair<int, int>> route_path; // Stores the sequence of positions (coordinates) in the route\n\n// Directions for movement: Up, Down, Left, Right\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\n// Function to check if a coordinate is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Function to reconstruct path from Dijkstra's parent pointers\nvector<pair<int, int>> reconstruct_path(const vector<vector<pair<int, int>>>& parent, pair<int, int> start_node, pair<int, int> end_node) {\n    vector<pair<int, int>> path;\n    pair<int, int> curr = end_node; \n\n    // Trace back from end_node to start_node using parent pointers\n    while (!(curr.first == start_node.first && curr.second == start_node.second)) {\n        // If curr becomes {-1, -1}, it implies end_node was unreachable from start_node\n        if (curr.first == -1) { \n            return {}; // Indicate path not found\n        }\n        path.push_back(curr); // Add the current node to the path\n        curr = parent[curr.first][curr.second]; // Move to the parent node\n    }\n    \n    // Add the start_node itself to the path.\n    if (!path.empty() || start_node == end_node) {\n        path.push_back(start_node);\n    }\n   \n    reverse(path.begin(), path.end()); // Reverse the path to get it from start to end\n    return path;\n}\n\nvoid solve() {\n    // 1. Read input and initialize data structures\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    cost_grid.resize(N, vector<int>(N));\n    adj_grid.resize(N, vector<vector<pair<int, int>>>(N)); \n    visible_from_bitset.resize(N, vector<bitset<MAX_ROADS>>(N));\n\n    int road_id_counter = 0;\n    for (int i = 0; i < N; ++i) {\n        cin >> grid[i];\n        for (int j = 0; j < N; ++j) {\n            if (grid[i][j] != '#') { // If it's a road square\n                cost_grid[i][j] = grid[i][j] - '0'; // Store its travel cost\n                road_coords.push_back({i, j}); // Add its coordinates to the list\n                coord_to_id[{i, j}] = road_id_counter++; // Map its coordinates to a unique ID\n            }\n        }\n    }\n    \n    is_road_covered_bitset.reset(); // Reset for each test case\n\n    current_pos = {si, sj}; // Set current position to the start\n    route_path.push_back(current_pos); // Add start position to the route path\n\n    // 2. Precompute visibility using bitsets and adjacency lists\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] != '#') { // Process only road squares\n                \n                // Scan in four directions to find all visible road squares and set corresponding bits\n                // Left\n                for (int k = c - 1; k >= 0; --k) {\n                    if (grid[r][k] == '#') break; \n                    visible_from_bitset[r][c][coord_to_id.at({r, k})] = 1;\n                }\n                // Right\n                for (int k = c + 1; k < N; ++k) {\n                    if (grid[r][k] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({r, k})] = 1;\n                }\n                // Up\n                for (int k = r - 1; k >= 0; --k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({k, c})] = 1;\n                }\n                // Down\n                for (int k = r + 1; k < N; ++k) {\n                    if (grid[k][c] == '#') break;\n                    visible_from_bitset[r][c][coord_to_id.at({k, c})] = 1;\n                }\n                // The current road square is visible from itself.\n                visible_from_bitset[r][c][coord_to_id.at({r, c})] = 1;\n\n                // Build adjacency list for road squares\n                for(int i=0; i<4; ++i) {\n                    int nr = r + dr[i];\n                    int nc = c + dc[i];\n                    if (is_valid(nr, nc) && grid[nr][nc] != '#') {\n                        adj_grid[r][c].push_back({nr, nc}); \n                    }\n                }\n            }\n        }\n    }\n\n    // Mark initially covered roads based on the starting position using bitwise OR.\n    is_road_covered_bitset |= visible_from_bitset[si][sj];\n    size_t total_roads = road_coords.size();\n\n    // --- GREEDY PHASE WITH STEP LIMIT ---\n    // Define a limit for greedy steps to ensure we don't exceed time limit.\n    // A multiplier of 7 for the number of road squares seems reasonable.\n    const int MAX_GREEDY_STEPS_MULTIPLIER = 7; \n    // Calculate max steps, ensuring it's at least a small constant to make progress on sparse maps.\n    int max_greedy_steps = max((int)road_coords.size() * MAX_GREEDY_STEPS_MULTIPLIER, 1000); \n    if (total_roads == 0) max_greedy_steps = 0; // No steps if no roads\n\n    int greedy_steps_taken = 0;\n\n    while (is_road_covered_bitset.count() < total_roads && greedy_steps_taken < max_greedy_steps) {\n        \n        // Variables to track the best move that provides new coverage\n        double best_gain_per_cost = -1.0; \n        long long min_cost_for_best_gain = INF; \n        int best_gain_r = -1, best_gain_c = -1;\n\n        // Variables for the fallback strategy (when no new coverage is achieved)\n        // Prioritize min cost, then max total visibility, then first found.\n        int fallback_r = -1, fallback_c = -1;\n        long long min_fallback_cost = INF;\n        int max_total_visibility_at_min_fallback_cost = -1; \n\n        // Iterate through adjacent road squares of the current position\n        for (const auto& neighbor_pos : adj_grid[current_pos.first][current_pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; \n\n            // Calculate newly covered roads\n            bitset<MAX_ROADS> newly_covered_bits = visible_from_bitset[nr][nc] & ~is_road_covered_bitset;\n            int num_newly_covered = newly_covered_bits.count();\n\n            if (num_newly_covered > 0) {\n                // Offers new coverage: evaluate gain/cost\n                double current_gain_per_cost = (double)num_newly_covered / move_cost;\n\n                if (current_gain_per_cost > best_gain_per_cost) {\n                    best_gain_per_cost = current_gain_per_cost;\n                    min_cost_for_best_gain = move_cost;\n                    best_gain_r = nr;\n                    best_gain_c = nc;\n                } else if (abs(current_gain_per_cost - best_gain_per_cost) < 1e-9) { // Tie in score\n                    if (move_cost < min_cost_for_best_gain) { // Tie-break by cost\n                        min_cost_for_best_gain = move_cost;\n                        best_gain_r = nr;\n                        best_gain_c = nc;\n                    }\n                }\n            } else {\n                // No new coverage: consider for fallback\n                if (move_cost < min_fallback_cost) {\n                    min_fallback_cost = move_cost;\n                    fallback_r = nr;\n                    fallback_c = nc;\n                    max_total_visibility_at_min_fallback_cost = (int)visible_from_bitset[nr][nc].count();\n                } else if (move_cost == min_fallback_cost) {\n                    int current_total_visibility = (int)visible_from_bitset[nr][nc].count();\n                    if (current_total_visibility > max_total_visibility_at_min_fallback_cost) {\n                        fallback_r = nr;\n                        fallback_c = nc;\n                        max_total_visibility_at_min_fallback_cost = current_total_visibility;\n                    }\n                }\n            }\n        }\n        \n        // Decide the actual next move\n        if (best_gain_r != -1) {\n            // Found a move with new coverage. Use it.\n            current_pos = {best_gain_r, best_gain_c};\n        } else {\n            // No neighbor offers new coverage. Use the fallback move.\n            if (fallback_r != -1) { \n                current_pos = {fallback_r, fallback_c};\n            } else {\n                // This case implies current_pos has no neighbors which is only possible \n                // if total_roads == 0 or 1 (and it's covered), or if graph is disconnected (not the case here).\n                // If we're here, and still haven't covered all roads, we should break to avoid infinite loop.\n                 break; \n            }\n        }\n        \n        // Apply the chosen move\n        total_time += cost_grid[current_pos.first][current_pos.second]; // Add cost to enter the new square\n        route_path.push_back(current_pos); // Add the new position to the route path\n\n        // Update the global coverage bitset\n        is_road_covered_bitset |= visible_from_bitset[current_pos.first][current_pos.second];\n        \n        greedy_steps_taken++;\n    }\n    // --- END GREEDY PHASE ---\n\n\n    // 4. Phase 2: Return to the starting position (si, sj) using Dijkstra's algorithm\n    // This phase executes regardless of whether full coverage was achieved in the greedy phase.\n    vector<vector<long long>> dist(N, vector<long long>(N, INF)); \n    vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1})); \n    priority_queue<pair<long long, pair<int, int>>, vector<pair<long long, pair<int, int>>>, greater<pair<long long, pair<int, int>>>> pq; \n\n    dist[current_pos.first][current_pos.second] = 0; \n    pq.push({0, current_pos}); \n\n    pair<int, int> dijkstra_target = {si, sj}; \n    \n    while (!pq.empty()) {\n        auto [d, pos] = pq.top(); \n        pq.pop();\n\n        if (d > dist[pos.first][pos.second]) continue;\n        if (pos == dijkstra_target) break; \n\n        for (const auto& neighbor_pos : adj_grid[pos.first][pos.second]) {\n            int nr = neighbor_pos.first;\n            int nc = neighbor_pos.second;\n            long long move_cost = cost_grid[nr][nc]; \n\n            if (dist[pos.first][pos.second] + move_cost < dist[nr][nc]) {\n                dist[nr][nc] = dist[pos.first][pos.second] + move_cost; \n                parent[nr][nc] = pos; \n                pq.push({dist[nr][nc], {nr, nc}}); \n            }\n        }\n    }\n\n    // Reconstruct the shortest path from current_pos back to dijkstra_target\n    vector<pair<int, int>> return_path_coords = reconstruct_path(parent, current_pos, dijkstra_target);\n    \n    // Append the steps from the return path to the overall route_path.\n    if (!return_path_coords.empty()) {\n        for (size_t i = 1; i < return_path_coords.size(); ++i) {\n            route_path.push_back(return_path_coords[i]); \n            total_time += cost_grid[return_path_coords[i].first][return_path_coords[i].second];\n        }\n    }\n\n    // 5. Generate the output route string\n    string result_route = \"\";\n    for (size_t i = 0; i + 1 < route_path.size(); ++i) {\n        pair<int, int> p1 = route_path[i];   \n        pair<int, int> p2 = route_path[i+1]; \n\n        int dr_move = p2.first - p1.first;\n        int dc_move = p2.second - p1.second;\n\n        if (dr_move == -1 && dc_move == 0) result_route += 'U'; // Move Up\n        else if (dr_move == 1 && dc_move == 0) result_route += 'D'; // Move Down\n        else if (dr_move == 0 && dc_move == -1) result_route += 'L'; // Move Left\n        else if (dr_move == 0 && dc_move == 1) result_route += 'R'; // Move Right\n    }\n\n    cout << result_route << endl;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); \n    \n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <queue>\n\nusing namespace std;\n\n// Enum for task status\nenum TaskStatus {\n    UNSTARTED,\n    READY,\n    IN_PROGRESS,\n    COMPLETED\n};\n\n// A large value representing an unknown or very large estimated skill deficit.\n// The maximum possible w_ij could be around K * max(d_ik) ~ 20 * 160 = 3200.\n// Using 3300.0 ensures it's larger than any realistic w_ij.\nconst double INF_ESTIMATED_W = 3300.0; \n\nint N, M, K, R;\nvector<vector<int>> d; // d[task_idx][skill_idx]: required skill levels for task i\nvector<vector<int>> adj; // adj[task_idx]: list of tasks that depend on this task (successors)\nvector<int> in_degree; // in_degree[task_idx]: number of prerequisites not yet met for this task\n\nvector<TaskStatus> task_status;\nvector<bool> member_free; // True if member is available to take a new task\nvector<int> member_current_task; // Stores task_idx if member is busy, -1 otherwise\nvector<int> task_start_day; // Stores the day a task was STARTED (1-indexed day)\n\n// Data for learning and estimation\n// estimated_w[member_idx][task_idx]: estimated skill deficit w_ij for member j on task i.\n// Initialized to INF_ESTIMATED_W. Updated when member j completes task i.\nvector<vector<double>> estimated_w; \n\n// Statistics for members: used for fallback estimation when specific (member, task) w is unknown\nvector<int> member_task_count; // Number of tasks completed by this member\nvector<double> sum_observed_times_member; // Sum of durations of tasks completed by this member\n\n// Global statistics: used as a fallback when member-specific info is also unavailable\ndouble global_average_observed_duration = INF_ESTIMATED_W;\nlong long global_total_tasks_completed = 0;\ndouble global_total_observed_time = 0.0;\n\n// Structure to represent a potential assignment (member, task) with its estimated duration.\n// Used for sorting to greedily pick the best assignments.\nstruct Assignment {\n    double estimated_duration;\n    int member_idx;\n    int task_idx;\n\n    // Custom comparison for sorting: primarily by estimated_duration (ascending).\n    // Smaller duration is better. Tie-breaking is done by member_idx then task_idx for determinism.\n    bool operator<(const Assignment& other) const {\n        // Use a small epsilon for floating point comparisons to avoid issues with precision.\n        if (abs(estimated_duration - other.estimated_duration) > 1e-9) {\n            return estimated_duration < other.estimated_duration;\n        }\n        // Tie-breaking: Prefer lower indexed member, then lower indexed task.\n        if (member_idx != other.member_idx) {\n            return member_idx < other.member_idx;\n        }\n        return task_idx < other.task_idx;\n    }\n};\n\n// Updates the estimated_w for a specific (member_idx, task_idx) pair based on observed time.\n// This function is called at most once for each (member, task) pair because a task\n// is assigned to at most one member, and a member is assigned at most one task at a time.\nvoid update_estimated_w(int member_idx, int task_idx, int observed_time) {\n    double w_val;\n    if (observed_time == 1) {\n        // If task took 1 day, according to the problem statement (w_ij=0 => t_ij=1), w_ij must be 0.\n        w_val = 0.0;\n    } else {\n        // If observed_time > 1, then observed_time = w_ij + r_i, where r_i is a random integer in [-3, 3].\n        // This implies w_ij is in the range [max(0, observed_time - 3), observed_time + 3].\n        // We use the midpoint of this range as our best estimate for w_ij.\n        double w_min = max(0, observed_time - 3);\n        double w_max = observed_time + 3;\n        w_val = (w_min + w_max) / 2.0; \n    }\n    // Store the estimated skill deficit.\n    estimated_w[member_idx][task_idx] = w_val;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read initial problem parameters.\n    cin >> N >> M >> K >> R;\n\n    // Read task difficulty levels (d_i,k).\n    d.resize(N, vector<int>(K));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < K; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Read task dependencies, build adjacency list (successors) and in-degree array.\n    adj.resize(N);\n    in_degree.resize(N, 0);\n    for (int i = 0; i < R; ++i) {\n        int u, v; // Dependency: u must be completed before v can start.\n        cin >> u >> v;\n        --u; --v; // Convert to 0-indexed: u is prerequisite for v.\n        adj[u].push_back(v); // Add v to the adjacency list of u.\n        in_degree[v]++; // Increment in-degree of v.\n    }\n\n    // Initialize state variables for tasks and members.\n    task_status.resize(N, UNSTARTED);\n    member_free.resize(M, true);\n    member_current_task.resize(M, -1);\n    task_start_day.resize(N, -1); // -1 indicates task has not started yet.\n\n    // Initialize data structures for learning and estimation.\n    estimated_w.resize(M, vector<double>(N, INF_ESTIMATED_W));\n    member_task_count.resize(M, 0);\n    sum_observed_times_member.resize(M, 0.0);\n\n    // Identify tasks that are initially ready (have an in-degree of 0).\n    for (int i = 0; i < N; ++i) {\n        if (in_degree[i] == 0) {\n            task_status[i] = READY;\n        }\n    }\n\n    int current_day = 1; // Simulation starts from day 1.\n    int completed_tasks_count = 0; // Counter for total completed tasks.\n\n    // Main simulation loop, runs day by day until all tasks are completed or time limit is reached.\n    while (completed_tasks_count < N) {\n        // 1. Process tasks completed at the END of the previous day.\n        vector<int> completed_members_indices_today; // Store indices of members who finished tasks.\n        int n_completed_input;\n        cin >> n_completed_input;\n\n        // Check for termination signal (-1) from the judge.\n        if (n_completed_input == -1) {\n            break; // Exit simulation if signal is received.\n        }\n\n        for (int i = 0; i < n_completed_input; ++i) {\n            int f_idx_1based;\n            cin >> f_idx_1based;\n            int member_idx = f_idx_1based - 1; // Convert member ID to 0-indexed.\n\n            completed_members_indices_today.push_back(member_idx);\n\n            int task_idx = member_current_task[member_idx]; // Get the task this member was working on.\n            \n            // Calculate the time taken for the task.\n            // A task started on task_start_day[task_idx] and finished at the end of current_day\n            // took current_day - task_start_day[task_idx] days.\n            int observed_time = current_day - task_start_day[task_idx];\n\n            // Update global statistics for overall average performance.\n            global_total_observed_time += observed_time;\n            global_total_tasks_completed++;\n            // Re-calculate global average duration to be more accurate.\n            global_average_observed_duration = global_total_observed_time / global_total_tasks_completed;\n\n            // Learn from the completed task: update estimated_w for this specific (member, task) pair.\n            update_estimated_w(member_idx, task_idx, observed_time);\n            \n            // Update task status to COMPLETED.\n            task_status[task_idx] = COMPLETED;\n            completed_tasks_count++;\n\n            // Mark the member as free, ready for a new assignment.\n            member_free[member_idx] = true;\n            member_current_task[member_idx] = -1;\n            \n            // Update member-specific statistics for future estimations.\n            member_task_count[member_idx]++;\n            sum_observed_times_member[member_idx] += observed_time;\n\n            // Update dependencies: decrement in-degree of successor tasks.\n            // If a successor task's in-degree becomes 0, it becomes READY.\n            for (int dependent_task_idx : adj[task_idx]) {\n                in_degree[dependent_task_idx]--;\n                if (in_degree[dependent_task_idx] == 0) {\n                    task_status[dependent_task_idx] = READY;\n                }\n            }\n        }\n        \n        // 2. Generate potential assignments for the current day.\n        vector<Assignment> candidates; // List to store all possible assignments with their estimated durations.\n        vector<int> ready_tasks_indices;\n        // Collect indices of all tasks that are currently READY.\n        for(int i=0; i<N; ++i) {\n            if (task_status[i] == READY) {\n                ready_tasks_indices.push_back(i);\n            }\n        }\n\n        // For every free member and every ready task, calculate an estimated duration.\n        for (int j = 0; j < M; ++j) { // Iterate through all members\n            if (member_free[j]) { // If member j is available\n                for (int task_idx : ready_tasks_indices) { // Consider all ready tasks\n                    double estimated_duration;\n                    \n                    // Heuristic: Estimate task duration for this (member, task) pair.\n                    // We prioritize assignments with the shortest estimated duration.\n                    // The estimation logic follows a hierarchy of information availability:\n                    // 1. Specific (member, task) estimate: If we have observed member j doing task i before.\n                    // 2. Member's average performance: If member j has completed other tasks.\n                    // 3. Global average performance: If member j is new and no other info is available.\n                    // 4. A very large value: If no historical data exists globally.\n\n                    // 1. Check if `estimated_w[j][task_idx]` has been updated from its initial large value.\n                    // The check ` < INF_ESTIMATED_W - 1.0` is a robust way to see if it's been set.\n                    if (estimated_w[j][task_idx] < INF_ESTIMATED_W - 1.0) { \n                        // `estimated_w` is the estimated skill deficit.\n                        // The estimated time to complete is max(1, estimated_w). This assumes r_i=0 for expected time.\n                        estimated_duration = max(1.0, estimated_w[j][task_idx]);\n                    } else {\n                        // 2. Fallback: Member j has some history (completed other tasks). Use their average completion time.\n                        if (member_task_count[j] > 0) {\n                            estimated_duration = sum_observed_times_member[j] / member_task_count[j];\n                        } else {\n                            // 3. Truly global fallback: Member j is new. Use global average observed time if available.\n                            if (global_total_tasks_completed > 0) {\n                                estimated_duration = global_average_observed_duration;\n                            } else {\n                                // 4. If no tasks have been completed globally yet, use a default high value.\n                                estimated_duration = INF_ESTIMATED_W;\n                            }\n                        }\n                    }\n                    \n                    // Ensure minimum duration is 1 day, as per problem statement.\n                    estimated_duration = max(1.0, estimated_duration);\n                    candidates.push_back({estimated_duration, j, task_idx}); // Add this potential assignment to candidates.\n                }\n            }\n        }\n\n        // Sort all candidate assignments by their estimated duration (ascending).\n        sort(candidates.begin(), candidates.end());\n\n        // 3. Make assignments for the current day.\n        vector<pair<int, int>> assignments_today; // Stores {member_idx, task_idx} for output.\n        vector<bool> task_assigned_today(N, false); // Helper to ensure each task is assigned at most once per day.\n        \n        // Iterate through sorted candidates and make assignments greedily.\n        for (const auto& assignment : candidates) {\n            // Stop if we have already assigned tasks to all M members.\n            if (assignments_today.size() == M) { \n                break;\n            }\n            \n            int member_idx = assignment.member_idx;\n            int task_idx = assignment.task_idx;\n\n            // Check if the member is still free, the task is still ready, and the task hasn't been assigned today.\n            if (member_free[member_idx] && task_status[task_idx] == READY && !task_assigned_today[task_idx]) {\n                // Make the assignment.\n                member_free[member_idx] = false; // Mark member as busy.\n                member_current_task[member_idx] = task_idx; // Assign task to member.\n                task_start_day[task_idx] = current_day; // Record the start day.\n                task_status[task_idx] = IN_PROGRESS; // Update task status.\n                \n                assignments_today.push_back({member_idx, task_idx}); // Record assignment for output.\n                task_assigned_today[task_idx] = true; // Mark task as assigned for today.\n            }\n        }\n\n        // 4. Output assignments for the current day.\n        cout << assignments_today.size(); // Number of assignments.\n        for (const auto& p : assignments_today) {\n            // Output member ID and task ID (1-based).\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1; \n        }\n        cout << endl;\n        cout.flush(); // Ensure output is sent immediately.\n\n        current_day++; // Advance to the next day.\n    }\n\n    return 0; // End of simulation.\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <iomanip> // For std::fixed and std::setprecision\n\n// Use long long for coordinates and distances to be safe, although int might suffice for coordinates\nusing coord_t = int;\nusing dist_t = long long;\n\nstruct Point {\n    coord_t x, y;\n    int id; // Original order ID, or special ID for office\n\n    // Equality operator for point comparisons\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Less than operator for potential use in sets/maps\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// Calculate Manhattan distance between two points\ndist_t manhattan_distance(const Point& p1, const Point& p2) {\n    // Use static_cast to long long to prevent intermediate overflow in abs() if coordinates are large\n    return std::abs(static_cast<long long>(p1.x) - p2.x) + std::abs(static_cast<long long>(p1.y) - p2.y);\n}\n\n// Structure to hold information about a single delivery order\nstruct Order {\n    int id;\n    Point pickup;\n    Point delivery;\n    dist_t internal_dist; // Manhattan distance between pickup and delivery\n    dist_t dist_to_office_pickup; // Manhattan distance from office to pickup\n    dist_t dist_delivery_to_office; // Manhattan distance from delivery to office\n};\n\n// Structure for candidate points during route construction\n// Represents a point to visit next, along with its cost and type (pickup/delivery)\nstruct Candidate {\n    Point p;\n    dist_t cost;        // Cost to reach this point from the current location\n    int type;           // 0 for pickup, 1 for delivery\n    int order_id;       // The ID of the order this point belongs to\n    dist_t dist_to_office; // Pre-calculated distance from this point to the office (for tie-breaking)\n\n    // Custom comparison for sorting candidates by cost, then type, then distance to office\n    bool operator<(const Candidate& other) const {\n        if (cost != other.cost) {\n            return cost < other.cost;\n        }\n        // Tie-breaking:\n        // 1. Prefer pickups over deliveries.\n        if (type != other.type) {\n            return type < other.type; // 0 (pickup) < 1 (delivery)\n        }\n        // 2. If same type (both pickups or both deliveries):\n        //    Prefer the point that is closer to the office.\n        return dist_to_office < other.dist_to_office; \n    }\n};\n\n// Helper function to determine the grid cell coordinates for a given point\nstd::pair<int, int> get_cell(const Point& p) {\n    // 800x800 area, divided into 10x10 grid. Cell size is 80x80.\n    return {p.x / 80, p.y / 80}; \n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::vector<Order> all_orders(1000);\n    Point office = {400, 400, -1}; // Office location, ID -1 signifies office\n\n    // Read input for all 1000 orders\n    for (int i = 0; i < 1000; ++i) {\n        all_orders[i].id = i + 1; // Order IDs are 1-based\n        std::cin >> all_orders[i].pickup.x >> all_orders[i].pickup.y >> all_orders[i].delivery.x >> all_orders[i].delivery.y;\n        \n        // Assign original order ID to Point objects\n        all_orders[i].pickup.id = i + 1;\n        all_orders[i].delivery.id = i + 1;\n\n        // Pre-calculate distances for scoring and route construction\n        all_orders[i].internal_dist = manhattan_distance(all_orders[i].pickup, all_orders[i].delivery);\n        all_orders[i].dist_to_office_pickup = manhattan_distance(office, all_orders[i].pickup);\n        all_orders[i].dist_delivery_to_office = manhattan_distance(all_orders[i].delivery, office);\n    }\n\n    // --- Order Selection Heuristic ---\n    // Strategy: Select orders that are spatially clustered and relatively close to the office.\n    // 1. Group orders by the cell their pickup point falls into.\n    // 2. Score cells based on the average distance from the office to pickup points within them.\n    // 3. Prioritize cells closest to the office.\n    // 4. Collect candidate orders from prioritized cells, sorting them by internal travel distance.\n    // 5. Further refine candidates by a combined score and select the top 50.\n\n    // Map to group orders by their pickup cell\n    std::map<std::pair<int, int>, std::vector<Order*>> cell_to_orders_map;\n    for (auto& order : all_orders) {\n        cell_to_orders_map[get_cell(order.pickup)].push_back(&order);\n    }\n\n    // Calculate scores for each cell and store them along with cell coordinates\n    // Use double for average distance for better precision in cell scoring\n    std::vector<std::pair<double, std::pair<int, int>>> cell_scores; \n    for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n        if (order_list.empty()) continue; // Skip empty cells\n        dist_t total_dist_to_cell_pickup = 0;\n        for (Order* order_ptr : order_list) {\n            total_dist_to_cell_pickup += manhattan_distance(office, order_ptr->pickup);\n        }\n        // Average distance = total distance / number of orders in cell\n        cell_scores.push_back({static_cast<double>(total_dist_to_cell_pickup) / order_list.size(), cell_coord});\n    }\n\n    // Sort cells based on their average distance score (ascending)\n    std::sort(cell_scores.begin(), cell_scores.end());\n\n    // Pool of candidate orders to choose from. We aim for more than 50 initially to allow for better final selection.\n    std::vector<Order*> candidate_orders_pool; \n    std::set<int> added_order_ids; // Keep track of added orders to avoid duplicates\n\n    // Collect orders from the best cells first (lowest average distance to office)\n    // Increased pool size for potentially better order selection.\n    // Increased from 400 to 500.\n    const int MAX_CANDIDATES_TO_CONSIDER = 500; \n\n    for (const auto& cell_score_pair : cell_scores) {\n        std::pair<int, int> cell_coord = cell_score_pair.second;\n        if (cell_to_orders_map.count(cell_coord)) {\n            std::vector<Order*>& orders_in_cell = cell_to_orders_map[cell_coord];\n            // Sort orders within this cell by their internal travel distance (shortest first)\n            std::sort(orders_in_cell.begin(), orders_in_cell.end(), [](Order* a, Order* b) {\n                return a->internal_dist < b->internal_dist;\n            });\n            \n            // Add orders from this cell to the candidate pool if not already added\n            for (Order* order_ptr : orders_in_cell) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n        }\n        // Stop collecting if we have enough candidates\n        if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break; \n    }\n    \n    // If still not enough candidates after processing all prioritized cells,\n    // fill up from any remaining orders not yet considered.\n    if (candidate_orders_pool.size() < MAX_CANDIDATES_TO_CONSIDER) {\n        for (auto const& [cell_coord, order_list] : cell_to_orders_map) {\n            for (Order* order_ptr : order_list) {\n                if (added_order_ids.find(order_ptr->id) == added_order_ids.end()) {\n                    candidate_orders_pool.push_back(order_ptr);\n                    added_order_ids.insert(order_ptr->id);\n                }\n            }\n             if (candidate_orders_pool.size() >= MAX_CANDIDATES_TO_CONSIDER) break;\n        }\n    }\n    \n    // Sort the pool of candidates by a refined score: \n    // internal_dist + min(dist_to_office_pickup, dist_delivery_to_office).\n    // This score prioritizes orders that are short and/or have at least one endpoint near the office.\n    std::sort(candidate_orders_pool.begin(), candidate_orders_pool.end(), [](Order* a, Order* b) {\n        dist_t score_a = a->internal_dist + std::min(a->dist_to_office_pickup, a->dist_delivery_to_office);\n        dist_t score_b = b->internal_dist + std::min(b->dist_to_office_pickup, b->dist_delivery_to_office);\n        return score_a < score_b;\n    });\n\n    // Select the top 50 orders from the sorted candidate pool.\n    std::vector<int> selected_order_ids;\n    std::vector<Order*> selected_orders_ptr; // Pointers to the actual Order objects for selected orders\n    for (int i = 0; i < 50; ++i) {\n        selected_order_ids.push_back(candidate_orders_pool[i]->id);\n        selected_orders_ptr.push_back(candidate_orders_pool[i]);\n    }\n\n    // --- Route Construction (Greedy) ---\n    // Uses a greedy approach to build the route, ensuring precedence constraints.\n    // It iteratively picks the cheapest valid next point (pickup or delivery).\n\n    std::vector<Point> route_points; // The sequence of points in the delivery route\n    // Map to quickly access selected order details by their ID\n    std::map<int, Order*> order_map; \n    // Track the visited status of pickups and completed deliveries for selected orders\n    std::map<int, bool> is_pickup_visited;\n    std::map<int, bool> is_delivery_done;\n    \n    // Populate data structures for selected orders\n    for (Order* order_ptr : selected_orders_ptr) {\n        order_map[order_ptr->id] = order_ptr;\n        is_pickup_visited[order_ptr->id] = false;\n        is_delivery_done[order_ptr->id] = false;\n    }\n\n    route_points.push_back(office); // Start the route at the office\n    Point current_location = office;\n    int orders_completed = 0; // Counter for the number of orders fully delivered\n\n    // Greedy construction of the route, ensuring precedence constraints\n    while (orders_completed < 50) {\n        std::vector<Candidate> candidates; // List of possible next points\n\n        // Consider all available pickup points for selected orders\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_pickup_visited[order_id]) {\n                // Add pickup point as a candidate\n                candidates.push_back({order_ptr->pickup, \n                                      manhattan_distance(current_location, order_ptr->pickup), \n                                      0, // type: pickup\n                                      order_id,\n                                      order_ptr->dist_to_office_pickup}); // distance to office for tie-breaking\n            }\n        }\n\n        // Consider all available delivery points IF their pickup has already been visited\n        for (auto const& [order_id, order_ptr] : order_map) {\n            if (!is_delivery_done[order_id] && is_pickup_visited[order_id]) {\n                // Add delivery point if its order hasn't been completed AND its pickup has been visited\n                candidates.push_back({order_ptr->delivery, \n                                      manhattan_distance(current_location, order_ptr->delivery), \n                                      1, // type: delivery\n                                      order_id,\n                                      order_ptr->dist_delivery_to_office}); // distance to office for tie-breaking\n            }\n        }\n\n        // If no valid candidates are found, it means we are stuck.\n        // This should not happen if the problem is solvable for the selected 50 orders and the greedy logic is robust.\n        // If this occurs, `orders_completed` will be less than 50, likely leading to a WRONG_ANSWER or a suboptimal route.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates to find the best next move (using custom comparator: cost -> type -> dist_to_office)\n        std::sort(candidates.begin(), candidates.end());\n        \n        // Select the best candidate (minimum cost, then type, then distance to office)\n        Candidate best_candidate = candidates[0];\n        \n        // Add the chosen point to the route and update current location\n        route_points.push_back(best_candidate.p);\n        current_location = best_candidate.p;\n\n        // Update status based on the type of point visited\n        if (best_candidate.type == 0) { // It was a pickup\n            is_pickup_visited[best_candidate.order_id] = true;\n        } else { // It was a delivery\n            is_delivery_done[best_candidate.order_id] = true;\n            orders_completed++; // Increment count of fully delivered orders\n        }\n    }\n    \n    route_points.push_back(office); // End the route at the office\n\n    // --- Output ---\n    // Output the list of selected order IDs\n    std::cout << selected_order_ids.size() << std::endl;\n    for (int i = 0; i < selected_order_ids.size(); ++i) {\n        std::cout << selected_order_ids[i] << (i == selected_order_ids.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    // Output the sequence of points in the optimized route\n    std::cout << route_points.size() << std::endl;\n    for (int i = 0; i < route_points.size(); ++i) {\n        std::cout << route_points[i].x << \" \" << route_points[i].y << (i == route_points.size() - 1 ? \"\" : \" \");\n    }\n    std::cout << std::endl;\n\n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric> // For std::iota\n#include <algorithm> // For std::swap\n#include <vector> // For storing edge data\n\n// Disjoint Set Union (DSU) data structure\n// Used to keep track of connected components efficiently.\nstruct DSU {\n    std::vector<int> parent;\n    std::vector<int> sz;\n\n    // Constructor: Initializes DSU for n elements.\n    // Each element starts in its own set.\n    DSU(int n) {\n        parent.resize(n);\n        // Initialize each element to be its own parent.\n        std::iota(parent.begin(), parent.end(), 0);\n        // Initialize the size of each set to 1.\n        sz.assign(n, 1);\n    }\n\n    // Finds the representative (root) of the set containing element i.\n    // Implements path compression for optimization.\n    int find(int i) {\n        if (parent[i] == i)\n            return i;\n        // Path compression: make every node on the path point directly to the root.\n        return parent[i] = find(parent[i]);\n    }\n\n    // Unites the sets containing elements i and j.\n    // Returns true if the sets were different and merged, false otherwise.\n    // Implements union by size for optimization.\n    bool unite(int i, int j) {\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            // Union by size: attach the smaller tree to the root of the larger tree.\n            if (sz[root_i] < sz[root_j])\n                std::swap(root_i, root_j);\n            parent[root_j] = root_i;\n            sz[root_i] += sz[root_j];\n            return true; // Successfully merged two distinct sets\n        }\n        return false; // Elements were already in the same set\n    }\n};\n\n// Structure to store edge information: endpoints and calculated d_i\nstruct Edge {\n    int u, v;\n    long long d; // Rounded Euclidean distance\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Fixed values for N (number of vertices) and M (number of candidate edges)\n    // as specified in the problem statement for all test cases.\n    const int N = 400;\n    const int M = 1995;\n\n    // Read vertex coordinates.\n    std::vector<std::pair<int, int>> coords(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> coords[i].first >> coords[i].second;\n    }\n\n    // Pre-calculate d_i for all M candidate edges.\n    std::vector<Edge> edges(M);\n    for (int i = 0; i < M; ++i) {\n        int u_node, v_node;\n        std::cin >> u_node >> v_node; // Read endpoints for edge i\n        edges[i].u = u_node;\n        edges[i].v = v_node;\n\n        // Calculate the Euclidean distance d_i.\n        // Using long double for intermediate calculations to maintain precision.\n        long double dx = static_cast<long double>(coords[u_node].first) - coords[v_node].first;\n        long double dy = static_cast<long double>(coords[u_node].second) - coords[v_node].second;\n        long double dist_sq = dx * dx + dy * dy;\n        long double dist = std::sqrt(dist_sq);\n        \n        // Round to the nearest integer as per problem statement.\n        edges[i].d = static_cast<long long>(std::round(dist));\n    }\n\n    DSU dsu(N); // Initialize DSU for N vertices.\n    int merges_made = 0; // Counter for successful component merges.\n\n    // Heuristic: Aim to balance connectivity guarantee with cost minimization.\n    // Adopt an edge if:\n    // 1. It connects two previously disconnected components AND\n    // 2. It is \"cheap\" (l_i <= COST_THRESHOLD * d_i) OR we are forced to take it\n    //    to guarantee connectivity (i.e., not enough remaining edges to make up needed merges).\n    //\n    // We are reducing COST_THRESHOLD from 2.7 to 2.5. This makes the \"cheap\" condition harder to satisfy.\n    // Consequently, more edges will be rejected if they are also \"not forced\",\n    // leading to a potentially lower total cost A and thus a higher score B/A.\n    // The \"forced\" condition `(edges_needed_for_connectivity > edges_available_later)` ensures\n    // we still prioritize completing the spanning tree.\n    const long double COST_THRESHOLD = 2.5; \n\n    for (int i = 0; i < M; ++i) {\n        long long l_i; // The true edge length for the i-th edge, revealed now.\n        std::cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        long long d_i = edges[i].d; // Base distance for this edge.\n\n        // Check if the edge connects two different components.\n        if (dsu.find(u) != dsu.find(v)) {\n            // This edge is potentially useful for connectivity.\n            \n            // Calculate how many more merges are strictly necessary to connect all N vertices.\n            // A spanning tree of N vertices requires N-1 edges.\n            int edges_needed_for_connectivity = (N - 1) - merges_made;\n            // Calculate how many edges are still available in the input stream from this point onwards.\n            int edges_available_later = M - 1 - i;\n\n            // Determine if the current edge's cost is within our preferred \"cheap\" range.\n            bool is_cheap = false;\n            // Handle d_i = 0 case: if base distance is 0, l_i must be 0 for it to be cheap.\n            if (d_i == 0) {\n                if (l_i == 0) is_cheap = true;\n            } else {\n                // Compare using long double for precision.\n                is_cheap = (static_cast<long double>(l_i) <= COST_THRESHOLD * static_cast<long double>(d_i));\n            }\n\n            // Decision logic: Adopt the edge if it's cheap OR if we are forced to take it.\n            // We are forced if the number of merges still needed is greater than the number of edges remaining.\n            // This ensures we don't reject an edge that might be our last chance to connect components.\n            if (is_cheap || (edges_needed_for_connectivity > edges_available_later)) {\n                // Adopt the edge.\n                std::cout << 1 << std::endl;\n                dsu.unite(u, v); // Merge the components.\n                merges_made++;   // Increment the count of successful merges.\n            } else {\n                // Reject the edge: it's too expensive AND we are not forced to take it.\n                // This is where we try to save cost by foregoing an expensive edge.\n                std::cout << 0 << std::endl;\n            }\n        } else {\n            // Reject the edge: it connects vertices already in the same component.\n            // It is redundant for connectivity and only adds cost.\n            std::cout << 0 << std::endl;\n        }\n        \n        // std::endl not only inserts a newline character but also flushes the output buffer.\n        // Flushing is critically required by the problem statement to ensure the judge receives\n        // our output for each step before providing the next input. Failure to flush can lead to TLE.\n        std::cout << std::endl;\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\n// Structures\nstruct Pos {\n    int r, c;\n    // Equality operator for comparing positions\n    bool operator==(const Pos& other) const {\n        return r == other.r && c == other.c;\n    }\n    // Less than operator for sorting and using in maps/sets\n    bool operator<(const Pos& other) const {\n        if (r != other.r) return r < other.r;\n        return c < other.c;\n    }\n};\n\nstruct Pet {\n    int id;\n    Pos pos;\n    int type;\n};\n\nstruct Human {\n    int id;\n    Pos pos;\n};\n\n// Directions for movement (U, D, L, R)\n// Corresponding dr and dc values\nint dr[] = {-1, 1, 0, 0}; // U, D, L, R\nint dc[] = {0, 0, -1, 1}; // U, D, L, R\n// Corresponding characters for movement and blocking actions\nchar move_chars[] = {'U', 'D', 'L', 'R'};\nchar block_chars[] = {'u', 'd', 'l', 'r'};\n\n// --- Helper Functions ---\n\n// Check if a position is within grid bounds\nbool is_valid(int r, int c) {\n    return r >= 0 && r < GRID_SIZE && c >= 0 && c < GRID_SIZE;\n}\n\n// Calculate Manhattan distance between two positions\nint manhattan_distance(Pos p1, Pos p2) {\n    return abs(p1.r - p2.r) + abs(p1.c - p2.c);\n}\n\n// Get character for human movement action (uppercase)\nchar get_direction_char_for_move(Pos from, Pos to) {\n    if (to.r < from.r) return 'U';\n    if (to.r > from.r) return 'D';\n    if (to.c < from.c) return 'L';\n    if (to.c > from.c) return 'R';\n    return '.'; // Should not happen for movement if positions differ\n}\n\n// Get character for human blocking action (lowercase)\nchar get_direction_char_for_block(Pos from, Pos to) {\n    if (to.r < from.r) return 'u';\n    if (to.r > from.r) return 'd';\n    if (to.c < from.c) return 'l';\n    if (to.c > from.c) return 'r';\n    return '.'; // Should not happen for blocking if positions differ\n}\n\n// Get target position from current position and direction character\nPos get_pos_from_dir_char(Pos from, char dir) {\n    Pos to = from;\n    if (dir == 'U' || dir == 'u') to.r--;\n    else if (dir == 'D' || dir == 'd') to.r++;\n    else if (dir == 'L' || dir == 'l') to.c--;\n    else if (dir == 'R' || dir == 'r') to.c++;\n    return to;\n}\n\n// Get precomputed minimum Manhattan distance from a square (r, c) to any pet.\n// Uses a flattened 1D array for quick lookup.\nint get_min_dist_to_pet(int r, int c, const vector<int>& min_pet_dists_flat) {\n    return min_pet_dists_flat[r * GRID_SIZE + c];\n}\n\n// BFS to find reachable squares from a starting position.\n// This function is primarily for scoring calculation after all turns.\npair<int, vector<Pos>> get_reachable_area(Pos start_pos, const vector<vector<bool>>& is_impassable_grid) {\n    vector<vector<bool>> visited(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n    queue<Pos> q;\n    vector<Pos> reachable_squares;\n\n    // If start position is invalid or impassable, return empty area.\n    if (!is_valid(start_pos.r, start_pos.c) || is_impassable_grid[start_pos.r][start_pos.c]) {\n        return {0, {}};\n    }\n\n    q.push(start_pos);\n    visited[start_pos.r][start_pos.c] = true;\n    reachable_squares.push_back(start_pos);\n\n    while (!q.empty()) {\n        Pos curr = q.front();\n        q.pop();\n\n        // Explore adjacent squares\n        for (int i = 0; i < 4; ++i) {\n            int nr = curr.r + dr[i];\n            int nc = curr.c + dc[i];\n\n            // If adjacent square is valid, not impassable, and not visited, add to queue.\n            if (is_valid(nr, nc) && !is_impassable_grid[nr][nc] && !visited[nr][nc]) {\n                visited[nr][nc] = true;\n                Pos next_pos = {nr, nc};\n                q.push(next_pos);\n                reachable_squares.push_back(next_pos);\n            }\n        }\n    }\n    return {reachable_squares.size(), reachable_squares};\n}\n\n// --- Global Variables ---\nint N_pets, M_humans;\nvector<Pet> pets_state;\nvector<Human> humans_state;\n// Grid state: true if impassable, false if passable.\nvector<vector<bool>> is_impassable_grid(GRID_SIZE, vector<bool>(GRID_SIZE, false));\n\n// Main logic for the contest problem\nvoid solve() {\n    // Read initial state: pet positions, types, and human positions.\n    cin >> N_pets;\n    pets_state.resize(N_pets);\n    for (int i = 0; i < N_pets; ++i) {\n        pets_state[i].id = i;\n        cin >> pets_state[i].pos.r >> pets_state[i].pos.c >> pets_state[i].type;\n        pets_state[i].pos.r--; pets_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n    cin >> M_humans;\n    humans_state.resize(M_humans);\n    for (int i = 0; i < M_humans; ++i) {\n        humans_state[i].id = i;\n        cin >> humans_state[i].pos.r >> humans_state[i].pos.c;\n        humans_state[i].pos.r--; humans_state[i].pos.c--; // Convert to 0-indexed coordinates\n    }\n\n    // Game loop for each turn\n    for (int turn = 0; turn < MAX_TURNS; ++turn) {\n        \n        // --- Precomputation for Human Decision Making ---\n        // Calculate minimum distance from every square to any pet.\n        // This is crucial for the human strategy of staying away from pets.\n        vector<int> min_pet_dists_flat(GRID_SIZE * GRID_SIZE);\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                min_pet_dists_flat[r * GRID_SIZE + c] = GRID_SIZE * 2; // Initialize with a large value\n                for (const auto& pet : pets_state) {\n                    min_pet_dists_flat[r * GRID_SIZE + c] = min(min_pet_dists_flat[r * GRID_SIZE + c], manhattan_distance({r, c}, pet.pos));\n                }\n            }\n        }\n\n        // Identify squares that are potentially blockable by humans.\n        // A square is blockable if it's within bounds, not impassable from previous turns,\n        // not occupied by any human or pet at the start of this turn, and not adjacent to any pet.\n        vector<Pos> blockable_squares;\n        vector<bool> is_occupied_at_start(GRID_SIZE * GRID_SIZE, false); // Mark occupied squares for quick checks\n        for (const auto& p : pets_state) is_occupied_at_start[p.pos.r * GRID_SIZE + p.pos.c] = true;\n        for (const auto& h : humans_state) is_occupied_at_start[h.pos.r * GRID_SIZE + h.pos.c] = true;\n\n        for (int r = 0; r < GRID_SIZE; ++r) {\n            for (int c = 0; c < GRID_SIZE; ++c) {\n                // Rule: Cannot block if adjacent to a pet. Minimum distance >= 2.\n                if (!is_impassable_grid[r][c] && !is_occupied_at_start[r * GRID_SIZE + c] && get_min_dist_to_pet(r, c, min_pet_dists_flat) >= 2) {\n                    blockable_squares.push_back({r, c});\n                }\n            }\n        }\n\n        // For each human, store their best potential blocking and moving action.\n        // Format: {score, position}. Initial score is -1.0 indicating no valid option found.\n        vector<pair<double, Pos>> best_block_options(M_humans, {-1.0, {-1, -1}}); \n        vector<pair<double, Pos>> best_move_options(M_humans, {-1.0, {-1, -1}});  \n\n        // --- Evaluate Blocking Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_block_score = -1.0;\n            Pos best_block_pos = {-1, -1};\n\n            for (const auto& sq : blockable_squares) {\n                double current_block_score = 0;\n                // Heuristic: prioritize blocking squares far from pets\n                current_block_score += (double)get_min_dist_to_pet(sq.r, sq.c, min_pet_dists_flat) * 100.0;\n                \n                // Heuristic: prefer extending existing walls (adjacent to already impassable squares)\n                bool adjacent_to_impassable = false;\n                for(int d=0; d<4; ++d) {\n                    int nr = sq.r + dr[d];\n                    int nc = sq.c + dc[d];\n                    if(is_valid(nr, nc) && is_impassable_grid[nr][nc]) {\n                        adjacent_to_impassable = true;\n                        break;\n                    }\n                }\n                if (adjacent_to_impassable) {\n                    current_block_score += 50.0;\n                }\n                \n                // Heuristic: penalize blocking squares far from human's current position (encourages moving towards blocking target)\n                current_block_score -= manhattan_distance(humans_state[i].pos, sq);\n\n                // Update best option if current score is better\n                if (current_block_score > max_block_score) {\n                    max_block_score = current_block_score;\n                    best_block_pos = sq;\n                } else if (abs(current_block_score - max_block_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                    if (sq.r < best_block_pos.r || (sq.r == best_block_pos.r && sq.c < best_block_pos.c)) {\n                        best_block_pos = sq;\n                    }\n                }\n            }\n            // Store the best block option found for human i\n            if (best_block_pos.r != -1) {\n                best_block_options[i] = {max_block_score, best_block_pos};\n            }\n        }\n\n        // --- Evaluate Movement Options for each human ---\n        for (int i = 0; i < M_humans; ++i) {\n            double max_move_score = -1.0;\n            Pos best_move_pos = {-1, -1};\n\n            // Check all 4 adjacent squares for potential movement\n            for (int d = 0; d < 4; ++d) {\n                int nr = humans_state[i].pos.r + dr[d];\n                int nc = humans_state[i].pos.c + dc[d];\n                Pos next_pos = {nr, nc};\n\n                // Can only move to a valid, passable square\n                if (is_valid(nr, nc) && !is_impassable_grid[nr][nc]) {\n                    // Cannot move to a square occupied by another human at the start of the turn\n                    if (!is_occupied_at_start[nr * GRID_SIZE + nc]) { \n                        double current_move_score = 0;\n                        // Heuristic: prefer moving to squares far from pets\n                        current_move_score += (double)get_min_dist_to_pet(nr, nc, min_pet_dists_flat) * 50.0;\n\n                        // Strong incentive to move to a square that this human plans to block\n                        if (best_block_options[i].second == next_pos) {\n                            current_move_score += 100.0;\n                        }\n                        \n                        // Update best option if current score is better\n                        if (current_move_score > max_move_score) {\n                            max_move_score = current_move_score;\n                            best_move_pos = next_pos;\n                        } else if (abs(current_move_score - max_move_score) < 1e-9) { // Tie-breaking: prefer lower row, then lower column\n                            if (next_pos.r < best_move_pos.r || (next_pos.r == best_move_pos.r && next_pos.c < best_move_pos.c)) {\n                                best_move_pos = next_pos;\n                            }\n                        }\n                    }\n                }\n            }\n            // Store the best move option found for human i\n            if (best_move_pos.r != -1) {\n                best_move_options[i] = {max_move_score, best_move_pos};\n            }\n        }\n\n        // --- Conflict Resolution and Final Action Assignment ---\n        // This phase determines which actions are actually performed, resolving conflicts.\n        string human_actions_str(M_humans, '.'); // Stores the output action char for each human\n        vector<Pos> squares_to_move_to_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to move\n        vector<Pos> planned_blocks_this_turn(M_humans, {-1, -1}); // Target pos for humans who choose to block\n\n        // Structure to hold all potential actions (block or move) for sorting and conflict resolution\n        struct ActionChoice {\n            int human_id;\n            Pos target_pos;\n            double score;\n            bool is_block_action; // true if this choice is to block, false if to move\n\n            // Custom comparator for sorting: higher score first, then lower human_id for tie-breaking\n            bool operator<(const ActionChoice& other) const {\n                if (abs(score - other.score) > 1e-9) return score > other.score; // Sort by score descending\n                return human_id < other.human_id; // Sort by human_id ascending for ties\n            }\n        };\n        vector<ActionChoice> choices;\n\n        // Populate the list of all potential actions\n        for (int i = 0; i < M_humans; ++i) {\n            if (best_block_options[i].first > -1.0) { // If a block option was found\n                choices.push_back({i, best_block_options[i].second, best_block_options[i].first, true});\n            }\n            if (best_move_options[i].first > -1.0) { // If a move option was found\n                choices.push_back({i, best_move_options[i].second, best_move_options[i].first, false});\n            }\n        }\n        // Sort all potential actions based on score and human_id\n        sort(choices.begin(), choices.end());\n\n        vector<bool> human_assigned_action(M_humans, false); // Track if a human has been assigned an action\n\n        // Process sorted choices to assign actions and resolve conflicts\n        for (const auto& choice : choices) {\n            int hid = choice.human_id;\n            Pos target_pos = choice.target_pos;\n            bool is_block = choice.is_block_action;\n\n            if (human_assigned_action[hid]) continue; // Human already has an assigned action\n\n            if (is_block) {\n                // --- Check if this block action is still possible ---\n                bool can_block = true;\n                // 1. Cannot block if target square will be occupied by a moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (squares_to_move_to_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n                // 2. Cannot block if target square is permanently impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) { // If it was impassable before this turn\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) { // And it's currently empty\n                         can_block = false; // Cannot make an already blocked and empty square impassable.\n                     }\n                }\n                // 3. Cannot block if another human has already planned to block this same square.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_block = false; break;\n                    }\n                }\n\n                // If the block action is valid, assign it.\n                if (can_block) {\n                    human_actions_str[hid] = get_direction_char_for_block(humans_state[hid].pos, target_pos);\n                    planned_blocks_this_turn[hid] = target_pos; // Record this planned block\n                    human_assigned_action[hid] = true;\n                }\n                // If block failed, this human might try their best move action later if available.\n            } else { // This choice is a movement action\n                // --- Check if this move action is still possible ---\n                bool can_move = true;\n                // 1. Cannot move to a square that is already impassable (from previous turns) AND empty.\n                if (is_impassable_grid[target_pos.r][target_pos.c]) {\n                     if (!is_occupied_at_start[target_pos.r * GRID_SIZE + target_pos.c]) {\n                         can_move = false;\n                     }\n                }\n                // 2. Cannot move to a square already claimed by another moving human this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (i != hid && squares_to_move_to_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n                // 3. Cannot move to a square that another human plans to block this turn.\n                for(int i=0; i<M_humans; ++i) {\n                    if (planned_blocks_this_turn[i] == target_pos) {\n                        can_move = false; break;\n                    }\n                }\n\n                // If the move action is valid, assign it.\n                if (can_move) {\n                    human_actions_str[hid] = get_direction_char_for_move(humans_state[hid].pos, target_pos);\n                    squares_to_move_to_this_turn[hid] = target_pos; // Record this planned move\n                    human_assigned_action[hid] = true;\n                }\n                // If move failed, this human might have a block action as their next best choice.\n            }\n        }\n        \n        // --- Fallback: Handle humans who couldn't get their preferred action or any action ---\n        // If a human's top choice (block or move) was taken or invalid, they might try their second best,\n        // or default to blocking if possible, or default to staying put.\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                // Try to perform the best block action if it failed initially\n                if (best_block_options[i].first > -1.0) {\n                     Pos block_target = best_block_options[i].second;\n                     bool can_block_fallback = true;\n                     // Check availability similar to above\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (squares_to_move_to_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     if (is_impassable_grid[block_target.r][block_target.c]) {\n                          if (!is_occupied_at_start[block_target.r * GRID_SIZE + block_target.c]) { can_block_fallback = false; }\n                     }\n                     for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                         if (planned_blocks_this_turn[h_idx] == block_target) { can_block_fallback = false; break; }\n                     }\n                     \n                     if (can_block_fallback) {\n                          human_actions_str[i] = get_direction_char_for_block(humans_state[i].pos, block_target);\n                          planned_blocks_this_turn[i] = block_target;\n                          human_assigned_action[i] = true;\n                     }\n                }\n                // If blocking still not possible, try to perform the best move action if it failed initially\n                if (!human_assigned_action[i] && best_move_options[i].first > -1.0) {\n                    Pos move_target = best_move_options[i].second;\n                    bool can_move_fallback = true;\n                    // Check availability similar to above\n                    if (is_impassable_grid[move_target.r][move_target.c]) {\n                         if (!is_occupied_at_start[move_target.r * GRID_SIZE + move_target.c]) { can_move_fallback = false; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (h_idx != i && squares_to_move_to_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    for(int h_idx=0; h_idx<M_humans; ++h_idx) {\n                        if (planned_blocks_this_turn[h_idx] == move_target) { can_move_fallback = false; break; }\n                    }\n                    \n                    if (can_move_fallback) {\n                         human_actions_str[i] = get_direction_char_for_move(humans_state[i].pos, move_target);\n                         squares_to_move_to_this_turn[i] = move_target;\n                         human_assigned_action[i] = true;\n                    }\n                }\n            }\n        }\n        \n        // Final fallback: If a human still has no action assigned, they do nothing (stay put).\n        for(int i=0; i<M_humans; ++i) {\n            if (!human_assigned_action[i]) {\n                human_actions_str[i] = '.';\n            }\n        }\n\n        // --- Output Human Actions and Flush ---\n        cout << human_actions_str << endl;\n        cout << flush; // Essential to flush output for interactive problems\n\n        // --- Read Pet Movements and Update Game State ---\n        vector<string> current_pet_moves(N_pets);\n        for (int i = 0; i < N_pets; ++i) {\n            cin >> current_pet_moves[i];\n        }\n\n        // Update Pet Positions based on input movements\n        for (int i = 0; i < N_pets; ++i) {\n            Pos current_pet_pos = pets_state[i].pos; // Current position at start of turn\n            for (char move : current_pet_moves[i]) { // Process each move character in the string\n                if (move == '.') continue; // No move\n\n                Pos next_pet_pos = current_pet_pos;\n                if (move == 'U') next_pet_pos.r--;\n                else if (move == 'D') next_pet_pos.r++;\n                else if (move == 'L') next_pet_pos.c--;\n                else if (move == 'R') next_pet_pos.c++;\n                \n                // Determine if the target square for the pet is passable.\n                // A square is passable for a pet if it's within grid bounds, AND\n                // it's NOT newly blocked by human action THIS turn, AND\n                // it's NOT permanently blocked (from previous turns) AND currently empty.\n                \n                bool target_is_newly_impassable = false; // Blocked by humans THIS turn\n                for(const auto& block_pos : planned_blocks_this_turn) {\n                    if (block_pos == next_pet_pos) {\n                        target_is_newly_impassable = true;\n                        break;\n                    }\n                }\n                \n                bool is_permanently_blocked_and_empty = false; // Blocked from PREVIOUS turns and currently empty\n                if (is_impassable_grid[next_pet_pos.r][next_pet_pos.c]) { // If it was impassable before this turn\n                    if (!is_occupied_at_start[next_pet_pos.r * GRID_SIZE + next_pet_pos.c]) { // And it's currently empty\n                        is_permanently_blocked_and_empty = true;\n                    }\n                }\n\n                // If the target square is valid and passable for the pet, move the pet.\n                if (is_valid(next_pet_pos.r, next_pet_pos.c) && !target_is_newly_impassable && !is_permanently_blocked_and_empty) {\n                    current_pet_pos = next_pet_pos; // Pet successfully moves\n                } else {\n                    // If move is not possible, pet stays put for this move.\n                    // 'current_pet_pos' remains unchanged, and the next move in the string will be attempted from this position.\n                }\n            }\n            pets_state[i].pos = current_pet_pos; // Update pet's final position for the turn\n        }\n\n        // Update Grid State: Apply the squares that humans planned to block.\n        for (int i = 0; i < M_humans; ++i) {\n            if (planned_blocks_this_turn[i].r != -1) { // If human i planned to block a square\n                is_impassable_grid[planned_blocks_this_turn[i].r][planned_blocks_this_turn[i].c] = true;\n            }\n        }\n\n        // Update Human Positions based on their assigned move actions.\n        for (int i = 0; i < M_humans; ++i) {\n            if (human_actions_str[i] != '.' && human_actions_str[i] != 'u' && human_actions_str[i] != 'd' && human_actions_str[i] != 'l' && human_actions_str[i] != 'r') {\n                // This is a move action (uppercase char)\n                humans_state[i].pos = get_pos_from_dir_char(humans_state[i].pos, human_actions_str[i]);\n            }\n        }\n    }\n\n    // --- Scoring Calculation (for local testing/debugging, not submitted) ---\n    /*\n    double total_satisfaction = 0;\n    for (int i = 0; i < M_humans; ++i) {\n        auto [reachable_count, reachable_squares] = get_reachable_area(humans_state[i].pos, is_impassable_grid);\n        int caught_pets = 0;\n        for (const auto& pet : pets_state) {\n            for (const auto& sq : reachable_squares) {\n                if (pet.pos == sq) {\n                    caught_pets++;\n                    break;\n                }\n            }\n        }\n        double s_i = (double)reachable_count / 900.0 * pow(0.5, caught_pets);\n        total_satisfaction += s_i;\n    }\n    double final_score = round(1e8 * total_satisfaction / M_humans);\n    cerr << \"Final Score (approx): \" << fixed << setprecision(10) << final_score << endl;\n    */\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n    \n    solve(); // Execute the main game logic\n\n    return 0; // Program finished successfully\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Structure to store parent information for path reconstruction.\n// It records the previous grid cell (r, c), the previous step count (k),\n// and the move character that led to the current state.\nstruct ParentInfo {\n    int r, c, k; // Previous grid position and step count.\n    char move;   // The move character that was chosen to transition from (r,c,k) to the current state.\n};\n\n// Structure representing a state in the Dijkstra search.\n// It includes the expected actual time elapsed, current grid position (r, c),\n// and the number of moves (k) that have been decided/processed for the path.\nstruct State {\n    double expected_time;\n    int r, c, k; \n\n    // Custom comparator for the priority queue to implement a min-priority queue.\n    // States with lower expected_time have higher priority.\n    bool operator>(const State& other) const {\n        return expected_time > other.expected_time;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int si, sj, ti, tj; // Start and target coordinates.\n    double p;           // Probability of forgetting a move.\n    cin >> si >> sj >> ti >> tj >> p;\n\n    // Read horizontal wall information. h_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i, j+1), 0 otherwise. Size: 20x19.\n    vector<vector<int>> h_walls(20, vector<int>(19));\n    for (int i = 0; i < 20; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 19; ++j) {\n            h_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    // Read vertical wall information. v_walls[i][j] is 1 if there's a wall\n    // between (i, j) and (i+1, j), 0 otherwise. Size: 19x20.\n    vector<vector<int>> v_walls(19, vector<int>(20));\n    for (int i = 0; i < 19; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < 20; ++j) {\n            v_walls[i][j] = row[j] - '0';\n        }\n    }\n\n    const int MAX_L = 200; // Maximum allowed length of the output string.\n    const double INF = numeric_limits<double>::max(); // Represents infinity for unreachable states.\n\n    // dist[r][c][k]: Stores the minimum expected actual time to reach grid cell (r, c)\n    // after k moves have been decided/processed for the path.\n    // k ranges from 0 to MAX_L.\n    vector<vector<vector<double>>> dist(20, vector<vector<double>>(20, vector<double>(MAX_L + 1, INF)));\n\n    // parent stores ParentInfo to reconstruct the path.\n    vector<vector<vector<ParentInfo>>> parent(20, vector<vector<ParentInfo>>(20, vector<ParentInfo>(MAX_L + 1, {-1, -1, -1, ' '})));\n\n    // Priority queue for Dijkstra's algorithm.\n    priority_queue<State, vector<State>, greater<State>> pq;\n\n    // Initial state: At home (si, sj), 0 moves processed, with an expected time of 0.0.\n    dist[si][sj][0] = 0.0;\n    pq.push({0.0, si, sj, 0});\n\n    // Define movement directions and corresponding characters for 'U', 'D', 'L', 'R'.\n    int dr[] = {-1, 1, 0, 0}; // Delta row for U, D, L, R\n    int dc[] = {0, 0, -1, 1}; // Delta column for U, D, L, R\n    char moves[] = {'U', 'D', 'L', 'R'};\n\n    // Variables to track the best path found to the office.\n    // min_expected_arrival_time stores the minimum expected time to reach the office.\n    // best_k stores the number of moves processed when the office was reached with min_expected_arrival_time.\n    double min_expected_arrival_time = INF;\n    int best_k = -1; \n\n    // Dijkstra's algorithm main loop.\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        double t = current.expected_time; // Expected time to reach this state.\n        int r = current.r;                 // Current row.\n        int c = current.c;                 // Current column.\n        int k = current.k;                 // Number of moves processed so far.\n\n        // If we found a better path to this state already, skip processing.\n        if (t > dist[r][c][k]) {\n            continue;\n        }\n\n        // Check if the current cell is the office.\n        if (r == ti && c == tj) {\n            // If we reached the office and this path is better than the best found so far, update.\n            if (t < min_expected_arrival_time) {\n                min_expected_arrival_time = t;\n                best_k = k; // Record the number of moves processed for this best path.\n            }\n            // Note: We don't 'continue' here because even if we reached the office,\n            // this state might be part of an even better path to the office IF it's reached earlier in terms of actual moves.\n            // However, since the goal is minimizing expected time, and the arrival time `t` is recorded,\n            // any further exploration from `(r,c,k)` for THIS specific path's time `t` is not useful for finding a *shorter* path to the office *via this specific branch*.\n            // But other states in PQ might offer a path with a lower expected time.\n            // The check `if (k == MAX_L)` below handles the path length limit.\n        }\n        \n        // If we have already processed MAX_L moves, we cannot extend this path further.\n        if (k == MAX_L) {\n            continue;\n        }\n\n        // Explore transitions for the next move (the (k+1)-th move in the sequence).\n        // For each of the 4 possible directions ('U', 'D', 'L', 'R'):\n        for (int i = 0; i < 4; ++i) {\n            char move_char = moves[i];\n            int nr_attempt = r, nc_attempt = c; // Initialize potential next position to current.\n\n            // Determine the target cell if the move is successful, considering grid boundaries and walls.\n            bool wall_collision = false; // True if move is blocked by boundary or wall.\n\n            if (move_char == 'U') {\n                // Check for boundary (r=0) or vertical wall v_walls[r-1][c] (between (r-1,c) and (r,c)).\n                if (r > 0 && !v_walls[r - 1][c]) { nr_attempt = r - 1; } else { wall_collision = true; }\n            } else if (move_char == 'D') {\n                // Check for boundary (r=19) or vertical wall v_walls[r][c] (between (r,c) and (r+1,c)).\n                if (r < 19 && !v_walls[r][c]) { nr_attempt = r + 1; } else { wall_collision = true; }\n            } else if (move_char == 'L') {\n                // Check for boundary (c=0) or horizontal wall h_walls[r][c-1] (between (r,c-1) and (r,c)).\n                if (c > 0 && !h_walls[r][c - 1]) { nc_attempt = c - 1; } else { wall_collision = true; }\n            } else if (move_char == 'R') {\n                // Check for boundary (c=19) or horizontal wall h_walls[r][c] (between (r,c) and (r,c+1)).\n                if (c < 19 && !h_walls[r][c]) { nc_attempt = c + 1; } else { wall_collision = true; }\n            }\n\n            // The actual time advances by 1 turn for this step, regardless of success or failure.\n            double next_expected_time = t + 1.0;\n            int next_k = k + 1; // One more move is now processed.\n\n            // Case 1: Move is forgotten (probability p).\n            // Takahashi stays at the current cell (r, c). The next state is (r, c) after k+1 moves.\n            // If the path to this state (r, c, next_k) via this route is better than previously found paths:\n            if (dist[r][c][next_k] > next_expected_time) {\n                dist[r][c][next_k] = next_expected_time;\n                // Record the parent information: we came from (r, c) at step k, and chose 'move_char'\n                // to generate this state at step k+1.\n                parent[r][c][next_k] = {r, c, k, move_char}; \n                pq.push({next_expected_time, r, c, next_k});\n            }\n\n            // Case 2: Move is executed (probability 1-p).\n            // Takahashi moves to (nr_attempt, nc_attempt). The next state is (nr_attempt, nc_attempt) after k+1 moves.\n            // If the path to this state (nr_attempt, nc_attempt, next_k) via this route is better:\n            if (dist[nr_attempt][nc_attempt][next_k] > next_expected_time) {\n                dist[nr_attempt][nc_attempt][next_k] = next_expected_time;\n                // Record parent information: came from (r, c) at step k, chose 'move_char'.\n                parent[nr_attempt][nc_attempt][next_k] = {r, c, k, move_char};\n                pq.push({next_expected_time, nr_attempt, nc_attempt, next_k});\n            }\n        }\n    }\n\n    // Path reconstruction.\n    string path = \"\";\n    if (best_k != -1) { // If the office was reached at least once within MAX_L moves.\n        int curr_r = ti;\n        int curr_c = tj;\n        int curr_k = best_k;\n\n        // Trace back from the office-reaching state to the start state (0 moves processed).\n        // The loop terminates when curr_k becomes 0.\n        while (curr_k > 0) {\n            ParentInfo p_info = parent[curr_r][curr_c][curr_k];\n            // Append the move character to the path string. This character is the (curr_k)-th move in the sequence.\n            path += p_info.move;\n            // Move to the parent state.\n            curr_r = p_info.r;\n            curr_c = p_info.c;\n            curr_k = p_info.k;\n        }\n        // The path string is built in reverse order, so reverse it.\n        reverse(path.begin(), path.end());\n    }\n    // If best_k remains -1, it means the office was not reached within MAX_L moves with a finite expected time.\n    // According to problem statement, failure leads to score 0. An empty path might be output, or a default path.\n    // However, given problem guarantees and structure, best_k should be set if office is reachable.\n    // For contest robustness, if path is empty, a simple BFS path could be a fallback, but Dijkstra should yield the optimal strategy.\n    \n    cout << path << endl; // Output the constructed commuting route.\n\n    return 0;\n}","ahc010":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <random>\n#include <chrono> // For seeding the random number generator\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int NUM_DIRECTIONS = 4;\n\n// Directions: 0:Left, 1:Up, 2:Right, 3:Down\n// di[d] is the row change for direction d\n// dj[d] is the column change for direction d\nint di[] = {0, -1, 0, 1};\nint dj[] = {-1, 0, 1, 0};\n\n// Base connections for the 8 tile types\n// base_connections[tile_type][entry_direction] = exit_direction\n// -1 means no connection\n// This table is derived from the problem statement's 'to' array.\nint base_connections[8][NUM_DIRECTIONS] = {\n    {1, 0, -1, -1}, // Type 0: L-U / U-L (Curve)\n    {3, -1, -1, 0}, // Type 1: L-D / D-L (Curve)\n    {-1, -1, 3, 2}, // Type 2: R-D / D-R (Curve)\n    {-1, 2, 1, -1}, // Type 3: R-U / U-R (Curve)\n    {1, 2, 3, 0},   // Type 4: Square path L->U->R->D->L\n    {3, 2, 1, 0},   // Type 5: S-curve like L->D, U->R, R->U, D->L (as per problem's to table)\n    {2, -1, 0, -1}, // Type 6: Horizontal L<->R (Straight)\n    {-1, 3, -1, 1}  // Type 7: Vertical U<->D (Straight)\n};\n\n// Function to map initial tile type and rotation count to effective tile type\n// The problem states how rotation changes the tile type for different groups.\nint map_type(int initial_type, int rotation) {\n    if (initial_type >= 0 && initial_type <= 3) { // Group 1: {0,1,2,3} rotate cyclically\n        return (initial_type + rotation) % 4;\n    } else if (initial_type == 4) { // Group 2a: {4,5} for initial type 4\n        // Rotation 0,2 -> type 4; Rotation 1,3 -> type 5\n        return 4 + (rotation % 2);\n    } else if (initial_type == 5) { // Group 2b: {4,5} for initial type 5\n        // Rotation 0,2 -> type 5; Rotation 1,3 -> type 4\n        return 4 + ((rotation + 1) % 2);\n    } else if (initial_type == 6) { // Group 3a: {6,7} for initial type 6\n        // Rotation 0,2 -> type 6; Rotation 1,3 -> type 7\n        return 6 + (rotation % 2);\n    } else if (initial_type == 7) { // Group 3b: {6,7} for initial type 7\n        // Rotation 0,2 -> type 7; Rotation 1,3 -> type 6\n        return 6 + ((rotation + 1) % 2);\n    }\n    return -1; // Should not happen\n}\n\n// Global variables to store the current configuration and support loop detection\nvector<vector<int>> base_type_input_grid; // Stores the initial tile type for each cell\nvector<vector<int>> current_rotations_grid; // Stores rotation count (0-3) for each cell\nvector<vector<vector<int>>> effective_to_grid; // Stores the connections for the current configuration of all cells\nvector<vector<vector<bool>>> visited_edge; // To mark edges (cell, entry_direction) that have been part of a found loop or dead end path\nvector<int> loop_lengths; // Stores lengths of all detected loop lines\n\n// Function to calculate the connections for a cell (r, c) based on its base type and current rotation\nvector<int> get_cell_connections(int r, int c) {\n    int initial_type = base_type_input_grid[r][c];\n    int rotation = current_rotations_grid[r][c];\n    int effective_type = map_type(initial_type, rotation);\n    // Return a copy of the connection rules for the effective tile type\n    return vector<int>(base_connections[effective_type], base_connections[effective_type] + NUM_DIRECTIONS);\n}\n\n// Function to find all loop lines and calculate the score (L1 * L2)\n// This function is called repeatedly by the local search heuristic.\nlong long evaluate_all_loops() {\n    // 1. Populate the effective_to_grid based on current rotations\n    effective_to_grid.assign(GRID_SIZE, vector<vector<int>>(GRID_SIZE, vector<int>(NUM_DIRECTIONS)));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            effective_to_grid[i][j] = get_cell_connections(i, j);\n        }\n    }\n\n    // 2. Find all loops using Depth First Search\n    loop_lengths.clear();\n    // visited_edge[i][j][d_in] marks if the edge entering cell (i,j) from direction d_in has been visited globally.\n    // This ensures each directed edge is explored at most once across all DFS traversals, making loop detection efficient.\n    visited_edge.assign(GRID_SIZE, vector<vector<bool>>(GRID_SIZE, vector<bool>(NUM_DIRECTIONS, false)));\n\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            for (int d_in = 0; d_in < NUM_DIRECTIONS; ++d_in) {\n                // If this edge has not been visited yet, start a new DFS traversal\n                if (!visited_edge[i][j][d_in]) {\n                    vector<tuple<int, int, int>> current_path; // Stores the sequence of (row, col, entry_direction) visited in this DFS\n                    map<tuple<int, int, int>, int> visited_in_current_dfs; // Maps state to the step index in current_path for cycle detection\n                    \n                    int cur_i = i, cur_j = j, cur_d_in = d_in;\n                    int step = 0;\n\n                    while (true) {\n                        // Check for out of bounds\n                        if (cur_i < 0 || cur_i >= GRID_SIZE || cur_j < 0 || cur_j >= GRID_SIZE) {\n                            break; // Path broken (out of bounds)\n                        }\n\n                        auto state = make_tuple(cur_i, cur_j, cur_d_in);\n                        \n                        // Check for cycle\n                        if (visited_in_current_dfs.count(state)) {\n                            int cycle_start_step = visited_in_current_dfs[state];\n                            int loop_len = step - cycle_start_step;\n                            \n                            // Mark all edges in the found cycle as visited globally\n                            for (int k = cycle_start_step; k < current_path.size(); ++k) {\n                                auto [pi, pj, pd_in] = current_path[k];\n                                visited_edge[pi][pj][pd_in] = true;\n                            }\n                            loop_lengths.push_back(loop_len);\n                            break; // Found a loop, stop this DFS traversal\n                        }\n\n                        // Mark current state as visited in this DFS and add to path\n                        visited_in_current_dfs[state] = step;\n                        current_path.push_back(state);\n\n                        // Determine next tile and direction\n                        int d_out = effective_to_grid[cur_i][cur_j][cur_d_in];\n                        if (d_out == -1) {\n                            break; // Path broken (tile has no exit in this direction)\n                        }\n\n                        cur_i += di[d_out];\n                        cur_j += dj[d_out];\n                        cur_d_in = (d_out + 2) % 4; // The entry direction to the next tile is opposite of the exit direction from current tile\n                        step++;\n                    }\n                    \n                    // Mark all edges in the path explored by this DFS as globally visited.\n                    // This prevents re-exploring dead-end paths or segments that didn't form a cycle.\n                    for(const auto& path_state : current_path) {\n                        auto [pi, pj, pd_in] = path_state;\n                        visited_edge[pi][pj][pd_in] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // 3. Calculate the score: L1 * L2\n    sort(loop_lengths.rbegin(), loop_lengths.rend()); // Sort lengths in descending order\n\n    if (loop_lengths.size() < 2) {\n        return 0; // Score is 0 if less than two loop lines are found\n    }\n    // Use long long for score to prevent overflow\n    return (long long)loop_lengths[0] * loop_lengths[1];\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input and store base tile types\n    base_type_input_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE));\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            base_type_input_grid[i][j] = row[j] - '0';\n        }\n    }\n\n    // Initialize rotations: start with all tiles at 0 rotation.\n    // This is a common starting point for heuristic search.\n    current_rotations_grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0)); \n\n    long long best_score = 0;\n    vector<vector<int>> best_rotations = current_rotations_grid;\n\n    // Calculate initial score for the all-zero rotation configuration\n    best_score = evaluate_all_loops();\n\n    // --- Randomized Iterative Improvement (Hill Climbing Variant) ---\n    // Use a Mersenne Twister engine for good random number generation.\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> cell_dist(0, GRID_SIZE - 1);\n    uniform_int_distribution<int> rot_dist(0, 3);\n\n    // Number of iterations for the local search. This value is a heuristic tuning parameter.\n    // More iterations generally yield better results but increase computation time.\n    int num_iterations = 100000; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        // Pick a random cell (r, c) to potentially change its rotation\n        int r = cell_dist(rng);\n        int c = cell_dist(rng);\n        int original_rotation = current_rotations_grid[r][c];\n\n        // Explore all 4 possible rotations for the chosen cell (r, c).\n        // For each, evaluate the total score. Keep track of the rotation that yields the maximum score locally.\n        long long max_local_score = -1; // Initialize with a value lower than any possible score\n        int best_local_r = original_rotation; // Default to keeping the original rotation if no improvement found\n\n        for (int test_r = 0; test_r < 4; ++test_r) {\n            current_rotations_grid[r][c] = test_r; // Temporarily set this rotation\n            long long score = evaluate_all_loops(); // Evaluate the score for this configuration\n            \n            if (score > max_local_score) {\n                max_local_score = score;\n                best_local_r = test_r;\n            }\n        }\n        \n        // After trying all 4 rotations, commit the best one found for this cell (r, c).\n        // This is a greedy step: always move to a state that improves the local score.\n        current_rotations_grid[r][c] = best_local_r;\n\n        // Update the global best score and configuration if the current configuration is better\n        if (max_local_score > best_score) {\n            best_score = max_local_score;\n            best_rotations = current_rotations_grid; // Save the rotations that achieved this best score\n        }\n    }\n\n    // Output the resulting rotations as a single string of 900 digits.\n    string result_string = \"\";\n    result_string.reserve(GRID_SIZE * GRID_SIZE); // Reserve space for efficiency\n    for (int i = 0; i < GRID_SIZE; ++i) {\n        for (int j = 0; j < GRID_SIZE; ++j) {\n            result_string += to_string(best_rotations[i][j]);\n        }\n    }\n    cout << result_string << endl;\n\n    return 0;\n}","ahc011":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue> // Not strictly needed for IDA*, but useful for initial heuristic calculation\n#include <unordered_map> // For comparing states within DLS path history\n#include <algorithm>\n#include <cmath>\n#include <functional> // Not used directly in IDA* main loop, but kept for structure\n#include <map> // For target_pos_map\n\nusing namespace std;\n\nint N;\nint T_limit;\n\n// Use a flattened board representation (vector<int> of size N*N) for efficiency.\nusing BoardFlat = vector<int>;\n\nvector<int> initial_board_flat; // The initial state of the board.\npair<int, int> initial_empty_pos; // Coordinates of the initial empty square.\n\n// Target configuration: a flattened N x N grid graph with the empty square at (N-1, N-1).\nvector<int> canonical_board_flat;\n// Precomputed map: tile value -> its target index in the flattened canonical board.\nmap<int, int> target_pos_map;\n\n// Custom hash function for StateKey (vector<int>) to be used with unordered_map.\nstruct VectorHasher {\n    size_t operator()(const vector<int>& v) const {\n        hash<int> hasher;\n        size_t seed = 0;\n        for (int i : v) {\n            seed ^= hasher(i) + 0x9e3779b9 + (seed << 6) + (seed >> 2);\n        }\n        return seed;\n    }\n};\n\n// --- Board coordinate conversion helpers ---\ninline int to_index(int r, int c) { return r * N + c; }\ninline pair<int, int> to_coords(int index) { return {index / N, index % N}; }\n\n// --- Heuristic function (same as before) ---\nint calculate_heuristic(const BoardFlat& board, int empty_r, int empty_c) {\n    int heuristic = 0;\n    // Max penalty for unmapped tiles. Should be larger than any possible path length.\n    // T_limit is approx 2*N^3. For N=10, T=2000. A path length of ~4000-5000 is a safe upper bound.\n    const int MAX_PENALTY = 10000; \n\n    for (int i = 0; i < N * N; ++i) {\n        int current_val = board[i];\n        if (current_val == 0) continue; // Skip empty tile\n        \n        int current_idx = i;\n        auto it = target_pos_map.find(current_val);\n        \n        if (it == target_pos_map.end()) {\n            heuristic += MAX_PENALTY; // Unmapped tile gets a large penalty\n        } else {\n            int target_idx = it->second; \n            pair<int, int> current_coords = to_coords(current_idx);\n            pair<int, int> target_coords = to_coords(target_idx);\n            heuristic += abs(current_coords.first - target_coords.first) + abs(current_coords.second - target_coords.second);\n        }\n    }\n    // Add heuristic for empty square's position\n    heuristic += abs(empty_r - (N - 1)) + abs(empty_c - (N - 1));\n    return heuristic;\n}\n\n// --- Global variables for IDA* ---\nstring best_path_found; // Stores the best path found so far\nint min_f_limit_for_next_iter; // Stores the minimum f-value > f_limit found in DLS\nbool solution_found; // Flag to indicate if a solution has been found\n\n// --- Helper to check if a state is the target ---\nbool is_target_state(const BoardFlat& board, int empty_r, int empty_c) {\n    if (empty_r != N - 1 || empty_c != N - 1) {\n        return false;\n    }\n    // Compare tiles with canonical configuration\n    for (int i = 0; i < N * N; ++i) {\n        if (i == to_index(N - 1, N - 1)) continue; // Skip empty square itself\n        if (board[i] != canonical_board_flat[i]) {\n            return false; // A tile is misplaced\n        }\n    }\n    return true;\n}\n\n// --- Depth-Limited Search (DLS) function for IDA* ---\n// Returns the minimum f-value encountered that exceeded the f_limit.\n// Modifies 'board' and 'current_path' in place, and backtracks.\nint dls(BoardFlat& board, int empty_r, int empty_c, int g_cost, int f_limit, string& current_path) {\n    \n    int h_cost = calculate_heuristic(board, empty_r, empty_c);\n    int f_cost = g_cost + h_cost;\n\n    // Pruning: If current state's f_cost exceeds the limit, update the minimum for the next iteration.\n    if (f_cost > f_limit) {\n        min_f_limit_for_next_iter = min(min_f_limit_for_next_iter, f_cost);\n        return f_cost; \n    }\n\n    // Goal Check\n    if (is_target_state(board, empty_r, empty_c)) {\n        solution_found = true;\n        best_path_found = current_path;\n        return f_cost; // Found solution, return its f_cost\n    }\n\n    // --- Explore neighbors ---\n    int dr[] = {-1, 1, 0, 0}; // U, D, L, R\n    int dc[] = {0, 0, -1, 1};\n    char move_chars[] = {'U', 'D', 'L', 'R'};\n\n    // To avoid immediate reverse moves and cycles within the DLS path:\n    // A simple check prevents moving a tile back immediately after it was moved.\n    // For more complex cycle detection, a map of visited states within the DLS path\n    // would be needed, but that increases memory usage and complexity, counteracting IDA*'s benefits.\n    // We rely on the f_limit and the heuristic to prune most unproductive branches.\n    \n    for (int i = 0; i < 4; ++i) { // Loop through all 4 possible moves\n        int nr = empty_r + dr[i];\n        int nc = empty_c + dc[i];\n\n        // Check if the move is within board boundaries\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n            \n            // Basic cycle detection: check if the current move is the direct opposite of the last move.\n            bool is_reverse_move = false;\n            if (!current_path.empty()) {\n                char last_move = current_path.back();\n                if ((dr[i] == -1 && last_move == 'D') || (dr[i] == 1 && last_move == 'U') ||\n                    (dc[i] == -1 && last_move == 'R') || (dc[i] == 1 && last_move == 'L')) {\n                    is_reverse_move = true;\n                }\n            }\n\n            // Only proceed if it's not an immediate reverse move.\n            if (!is_reverse_move) {\n                int current_idx = to_index(empty_r, empty_c);\n                int next_idx = to_index(nr, nc);\n                \n                // Perform the move\n                swap(board[current_idx], board[next_idx]);\n                current_path.push_back(move_chars[i]);\n                \n                // Recursive call for the next state\n                int result = dls(board, nr, nc, g_cost + 1, f_limit, current_path);\n                \n                // If solution found in recursive call, propagate it up\n                if (solution_found) return result; \n                \n                // Update the minimum f_limit for the next iteration if a deeper node was explored\n                min_f_limit_for_next_iter = min(min_f_limit_for_next_iter, result);\n\n                // Backtrack: undo the move\n                current_path.pop_back();\n                swap(board[current_idx], board[next_idx]); // Swap back\n            }\n        }\n    }\n    \n    // Return the minimum f_cost encountered that exceeded the limit.\n    // If no such node was found, it implies all explored nodes were within the limit or solution was found.\n    // If solution_found is false, this value helps set the next f_limit.\n    // If all branches were explored and none exceeded f_limit, it means all were solutions, which is unlikely\n    // unless f_limit was very high. If min_f_limit_for_next_iter wasn't updated, it means no node exceeded f_limit,\n    // but also no solution was found. In such cases, we might still need to increase f_limit.\n    // A robust approach is to ensure min_f_limit_for_next_iter is always updated by a value >= g_cost.\n    // The initial value of min_f_limit_for_next_iter should be high enough.\n    return min_f_limit_for_next_iter;\n}\n\nvoid solve_ida_star() {\n    // 1. Construct canonical board and target_pos_map (same as before)\n    canonical_board_flat.assign(N * N, 0);\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            int idx = to_index(r, c);\n            if (r == N - 1 && c == N - 1) {\n                canonical_board_flat[idx] = 0; // Empty square at its target.\n            } else {\n                int val = 0;\n                if (c < N - 1) val |= 4; // Right connection if cell to the right exists\n                if (c > 0) val |= 1;     // Left connection if cell to the left exists\n                if (r < N - 1) val |= 8; // Down connection if cell below exists\n                if (r > 0) val |= 2;     // Up connection if cell above exists\n                canonical_board_flat[idx] = val;\n            }\n        }\n    }\n    target_pos_map.clear();\n    for (int i = 0; i < N * N; ++i) {\n        target_pos_map[canonical_board_flat[i]] = i;\n    }\n\n    // --- Initial State ---\n    int initial_h = calculate_heuristic(initial_board_flat, initial_empty_pos.first, initial_empty_pos.second);\n    int current_f_limit = initial_h; // Start IDA* with f_limit = h(start)\n    \n    // Check if already solved\n    if (is_target_state(initial_board_flat, initial_empty_pos.first, initial_empty_pos.second)) {\n        cout << \"\" << endl;\n        return;\n    }\n\n    // --- IDA* Main Loop ---\n    solution_found = false;\n    best_path_found = \"\";\n    \n    // Limit iterations to prevent excessive runtime for very hard cases.\n    // These limits are heuristic and tuned based on N.\n    int max_iterations;\n    if (N <= 6) max_iterations = 1500; \n    else if (N == 7) max_iterations = 1200;\n    else if (N == 8) max_iterations = 1000;\n    else if (N == 9) max_iterations = 800;\n    else max_iterations = 600; // Tighter limit for N=10.\n\n    // A safe upper bound for f_cost, slightly more than T_limit + max possible heuristic for any tile.\n    // T_limit can be up to 2*N^3. For N=10, T=2000. Total heuristic can be large.\n    const int ABSOLUTE_F_LIMIT_MAX = 50000; // A very generous upper bound for f_cost.\n\n    for(int iter = 0; iter < max_iterations; ++iter) {\n        // Initialize min_f_limit_for_next_iter to a value larger than any possible f_cost.\n        // This ensures it gets updated by the first exceeding f_cost found in DLS.\n        min_f_limit_for_next_iter = ABSOLUTE_F_LIMIT_MAX; \n        string current_path = \"\";\n\n        // DLS needs a mutable board state.\n        BoardFlat current_board_state = initial_board_flat;\n        \n        // Call DLS. If solution is found, it will set solution_found and best_path_found.\n        dls(current_board_state, initial_empty_pos.first, initial_empty_pos.second, 0, current_f_limit, current_path);\n        \n        if (solution_found) {\n            cout << best_path_found << endl;\n            return;\n        }\n        \n        // If no solution found within current_f_limit, update f_limit for the next iteration.\n        // Use the minimum f_cost that exceeded the previous limit.\n        if (min_f_limit_for_next_iter == ABSOLUTE_F_LIMIT_MAX) {\n            // This case happens if DLS explored all reachable nodes within f_limit,\n            // but none exceeded it and no solution was found. This implies either\n            // the puzzle is unsolvable (not possible here), or the initial f_limit was too high,\n            // or all paths are solutions. For safety, just increment.\n             current_f_limit++; \n        } else {\n            current_f_limit = min_f_limit_for_next_iter;\n        }\n        \n        // Safety break: If f_limit becomes excessively large, stop.\n        if (current_f_limit > ABSOLUTE_F_LIMIT_MAX) { \n            break; // Stop if f_limit grows beyond a reasonable maximum.\n        }\n    }\n    \n    // If loop finishes without finding a solution (e.g., iteration limit reached or f_limit too high).\n    // Outputting empty string is a fallback.\n}\n\n// Helper function to convert a hexadecimal character ('0'-'9', 'a'-'f') to its integer value (0-15).\nint char_to_int(char c) {\n    if (c >= '0' && c <= '9') return c - '0';\n    return c - 'a' + 10;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> T_limit;\n\n    initial_board_flat.resize(N * N);\n    for (int i = 0; i < N; ++i) {\n        string row;\n        cin >> row;\n        for (int j = 0; j < N; ++j) {\n            int idx = to_index(i, j);\n            initial_board_flat[idx] = char_to_int(row[j]);\n            if (initial_board_flat[idx] == 0) {\n                initial_empty_pos = {i, j};\n            }\n        }\n    }\n\n    solve_ida_star();\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <iomanip>\n\nusing namespace std;\n\n// Use the maximum allowed coordinate value for defining line endpoints.\n// The problem statement allows coordinates up to 10^9.\nconst long long INF_COORD = 1e9; \n\nstruct Strawberry {\n    long long x, y;\n    int id;\n};\n\nstruct Line {\n    long long px, py, qx, qy;\n};\n\n// Helper function to select 'count' unique integer coordinates for lines.\n// This version adjusts the offset for outward search from midpoints to 1500.\nvector<long long> select_line_coords(int count, const set<long long>& occupied_coords) {\n    vector<long long> candidate_coords_pool;\n\n    // Define broad search ranges. Strawberry coords |x|,|y| < 10000.\n    long long internal_min = -16000, internal_max = 16000; \n    long long external_min = -20000, external_max = 20000;\n    \n    // Strategy 1: Add points from fixed, broad ranges.\n    for (long long val = internal_min; val <= internal_max; ++val) {\n        if (occupied_coords.find(val) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val);\n        }\n    }\n    // Add points further out if needed to ensure enough candidates.\n    for (long long offset = 1; offset <= 4; ++offset) { // Limited offsets\n        long long val_neg = internal_min - offset * 2000;\n        if (val_neg >= external_min && occupied_coords.find(val_neg) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val_neg);\n        }\n        long long val_pos = internal_max + offset * 2000;\n        if (val_pos <= external_max && occupied_coords.find(val_pos) == occupied_coords.end()) {\n            candidate_coords_pool.push_back(val_pos);\n        }\n    }\n\n    // Strategy 2: Generate candidates from midpoints between existing strawberry coordinates.\n    if (!occupied_coords.empty()) {\n        vector<long long> sorted_occupied(occupied_coords.begin(), occupied_coords.end());\n        \n        // Add sentinel points to define intervals covering the whole range.\n        if (sorted_occupied.front() > external_min) sorted_occupied.insert(sorted_occupied.begin(), external_min);\n        if (sorted_occupied.back() < external_max) sorted_occupied.push_back(external_max);\n        \n        sort(sorted_occupied.begin(), sorted_occupied.end());\n        sorted_occupied.erase(unique(sorted_occupied.begin(), sorted_occupied.end()), sorted_occupied.end());\n\n        // Iterate through adjacent pairs of occupied coordinates.\n        for (size_t i = 0; i < sorted_occupied.size() - 1; ++i) {\n            long long c1 = sorted_occupied[i];\n            long long c2 = sorted_occupied[i+1];\n            \n            double mid_double = (static_cast<double>(c1) + c2) / 2.0;\n            long long mid_rounded = round(mid_double);\n\n            // Add the midpoint if it's valid and within the gap.\n            if (mid_rounded > c1 && mid_rounded < c2 && occupied_coords.find(mid_rounded) == occupied_coords.end()) {\n                candidate_coords_pool.push_back(mid_rounded);\n            }\n            \n            // Search outwards from the midpoint with a reduced offset limit.\n            // Changed offset limit from 3000 to 1500.\n            for (long long offset = 1; offset < 1500; ++offset) { \n                long long cand_pos = mid_rounded + offset;\n                // Ensure candidate is strictly within interval [c1, c2] and not occupied.\n                if (cand_pos > c1 && cand_pos < c2 && occupied_coords.find(cand_pos) == occupied_coords.end()) {\n                    candidate_coords_pool.push_back(cand_pos);\n                }\n                if (cand_pos > c2) break; // Stop if we cross the next boundary.\n\n                long long cand_neg = mid_rounded - offset;\n                if (cand_neg > c1 && cand_neg < c2 && occupied_coords.find(cand_neg) == occupied_coords.end()) {\n                    candidate_coords_pool.push_back(cand_neg);\n                }\n                if (cand_neg < c1) break; // Stop if we cross the previous boundary.\n            }\n        }\n    }\n\n    // Sort the entire pool of candidates and remove duplicates.\n    sort(candidate_coords_pool.begin(), candidate_coords_pool.end());\n    candidate_coords_pool.erase(unique(candidate_coords_pool.begin(), candidate_coords_pool.end()), candidate_coords_pool.end());\n    \n    vector<long long> selected_coords;\n    \n    // Select 'count' coordinates from the pool such that the selected coordinates are themselves well-spaced.\n    if (!candidate_coords_pool.empty() && count > 0) {\n        // If the pool is larger than 'count', pick evenly spaced indices from the pool.\n        if (candidate_coords_pool.size() > static_cast<size_t>(count)) {\n            // Calculate an approximate spacing factor for indices in the pool.\n            double spacing_factor = static_cast<double>(candidate_coords_pool.size()) / count;\n            for (int i = 0; i < count; ++i) {\n                // Calculate the index in the candidate pool.\n                size_t pool_idx = static_cast<size_t>(round(i * spacing_factor));\n                // Clamp index to ensure it's within bounds.\n                pool_idx = min(pool_idx, candidate_coords_pool.size() - 1);\n                selected_coords.push_back(candidate_coords_pool[pool_idx]);\n            }\n        } else {\n            // If pool is smaller than 'count', take all unique candidates from the pool.\n            selected_coords = candidate_coords_pool;\n        }\n    }\n\n    // Final fallback: Ensure we have exactly 'count' coordinates.\n    // If the above selection yielded fewer than 'count' coordinates, fill the remainder.\n    // Use broad fixed ranges for fallback, ensuring to avoid occupied and already selected values.\n    long long current_fallback_val = external_min;\n    while (selected_coords.size() < count) {\n        // Check if the current fallback value is not occupied and not already selected.\n        if (occupied_coords.find(current_fallback_val) == occupied_coords.end()) {\n            bool already_selected = false;\n            for(long long sel_val : selected_coords) {\n                if(sel_val == current_fallback_val) {\n                    already_selected = true;\n                    break;\n                }\n            }\n            if(!already_selected) {\n                selected_coords.push_back(current_fallback_val);\n            }\n        }\n        current_fallback_val++;\n        // Wrap around to avoid infinite loop if the range is exhaustively checked and still short.\n        if (current_fallback_val > external_max) {\n            current_fallback_val = external_min;\n        }\n    }\n\n    // Sort the final selection to ensure deterministic output and correct interval definition.\n    sort(selected_coords.begin(), selected_coords.end());\n    // Remove any duplicates that might have been introduced by fallback logic or overlapping candidates.\n    selected_coords.erase(unique(selected_coords.begin(), selected_coords.end()), selected_coords.end());\n\n    // Truncate if by some rare chance we ended up with more than 'count'.\n    if (selected_coords.size() > static_cast<size_t>(count)) {\n        selected_coords.resize(count);\n    }\n\n    return selected_coords;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    int k; // Maximum number of cuts\n    cin >> n >> k;\n\n    vector<int> a(11); // a[d] is the number of attendees for d years\n    for (int d = 1; d <= 10; ++d) {\n        cin >> a[d];\n    }\n\n    vector<Strawberry> strawberries(n);\n    set<long long> sx_set, sy_set; // Sets to store unique strawberry x and y coordinates for efficient lookup.\n    for (int i = 0; i < n; ++i) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n        strawberries[i].id = i;\n        sx_set.insert(strawberries[i].x);\n        sy_set.insert(strawberries[i].y);\n    }\n\n    // Strategy: Divide the K cuts into vertical and horizontal lines.\n    // A balanced split (k/2 vertical, k-k/2 horizontal) creates a grid of regions.\n    int num_v_lines = k / 2;\n    int num_h_lines = k - num_v_lines;\n\n    // Select coordinates for the vertical and horizontal lines using the improved strategy.\n    vector<long long> v_line_values = select_line_coords(num_v_lines, sx_set);\n    vector<long long> h_line_values = select_line_coords(num_h_lines, sy_set);\n\n    // Sort line coordinates to define intervals correctly.\n    sort(v_line_values.begin(), v_line_values.end());\n    sort(h_line_values.begin(), h_line_values.end());\n\n    // Define interval boundaries for regions.\n    // These boundaries are the selected line coordinates plus sentinels far outside the strawberry range.\n    vector<long long> x_intervals = {-20000LL}; // Lower sentinel\n    x_intervals.insert(x_intervals.end(), v_line_values.begin(), v_line_values.end());\n    x_intervals.push_back(20000LL); // Upper sentinel\n    sort(x_intervals.begin(), x_intervals.end());\n    x_intervals.erase(unique(x_intervals.begin(), x_intervals.end()), x_intervals.end());\n\n    vector<long long> y_intervals = {-20000LL}; // Lower sentinel\n    y_intervals.insert(y_intervals.end(), h_line_values.begin(), h_line_values.end());\n    y_intervals.push_back(20000LL); // Upper sentinel\n    sort(y_intervals.begin(), y_intervals.end());\n    y_intervals.erase(unique(y_intervals.begin(), y_intervals.end()), y_intervals.end());\n\n    // Group regions by the number of strawberries they contain.\n    map<int, vector<int>> regions_by_count;\n    \n    int region_flat_idx_counter = 0; // Unique ID for each distinct rectangular region.\n\n    // Iterate through all created rectangular regions defined by the intervals.\n    for (size_t j = 0; j < x_intervals.size() - 1; ++j) {\n        for (size_t l = 0; l < y_intervals.size() - 1; ++l) {\n            long long min_x = x_intervals[j];\n            long long max_x = x_intervals[j+1];\n            long long min_y = y_intervals[l];\n            long long max_y = y_intervals[l+1];\n\n            // Count strawberries strictly within this open rectangular region.\n            int count = 0;\n            for (const auto& straw : strawberries) {\n                if (straw.x > min_x && straw.x < max_x &&\n                    straw.y > min_y && straw.y < max_y) {\n                    count++;\n                }\n            }\n            \n            // If a region contains strawberries, record it.\n            if (count > 0) {\n                regions_by_count[count].push_back(region_flat_idx_counter);\n                region_flat_idx_counter++;\n            }\n        }\n    }\n    \n    // Assignment phase: Greedily assign available regions to satisfy attendee demands.\n    set<int> used_region_flat_indices; // Track used regions.\n\n    // Iterate through each strawberry count demand (d from 1 to 10).\n    for (int d = 1; d <= 10; ++d) {\n        if (a[d] > 0) { // If there's a demand for 'd' strawberries.\n            // Check if we have any regions that contain exactly 'd' strawberries.\n            if (regions_by_count.count(d)) {\n                const vector<int>& available_regions_for_d = regions_by_count.at(d); \n                \n                int assigned_for_this_d = 0; // Counter for pieces of size 'd' assigned for current demand 'a[d]'.\n                \n                // Iterate through all regions known to contain exactly 'd' strawberries.\n                for (int region_flat_idx : available_regions_for_d) {\n                    // Check if this specific region has already been assigned.\n                    if (used_region_flat_indices.find(region_flat_idx) == used_region_flat_indices.end()) {\n                        // This region is available. Assign it.\n                        used_region_flat_indices.insert(region_flat_idx); // Mark as used.\n                        assigned_for_this_d++;\n                        \n                        // If we have satisfied all $a_d$ demands for this count 'd', stop looking for this 'd'.\n                        if (assigned_for_this_d == a[d]) {\n                            break; \n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // Prepare the output cuts.\n    vector<Line> cuts;\n    // For each selected vertical line coordinate `val`, create a line segment.\n    for (long long val : v_line_values) {\n        cuts.push_back({val, -INF_COORD, val, INF_COORD});\n    }\n    // For each selected horizontal line coordinate `val`, create a line segment.\n    for (long long val : h_line_values) {\n        cuts.push_back({-INF_COORD, val, INF_COORD, val});\n    }\n\n    // Output the total number of cuts and the coordinates defining each cut line.\n    cout << cuts.size() << endl;\n    for (const auto& line : cuts) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << endl;\n    }\n\n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <set>\n#include <algorithm>\n#include <map>\n#include <tuple>\n\nusing namespace std;\n\n// Maximum number of operations to perform.\n// A limit is needed to prevent infinite loops and control execution time.\nconst int MAX_OPS = 5000; \n\n// Structure to represent a grid point.\nstruct Point {\n    int x, y;\n\n    // For use in std::set and std::map.\n    // Lexicographical comparison.\n    bool operator<(const Point& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n\n    // For equality checks.\n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\n// Global variables for grid dimensions, center, and total weight.\nlong long N_val; // Grid size (N x N). Renamed from N to avoid conflict.\nPoint center; // Center of the grid for weight calculation.\nlong long total_weight_sum_val; // Sum of weights of all points with dots. Renamed to avoid conflict.\n\n// Data structures for storing drawn segments to check for overlaps.\n// For axis-aligned segments:\n// h_segments_by_y[y] stores a set of pairs {min_x, max_x} for horizontal segments on line y.\n// v_segments_by_x[x] stores a set of pairs {min_y, max_y} for vertical segments on line x.\nmap<int, set<pair<int, int>>> h_segments_by_y;\nmap<int, set<pair<int, int>>> v_segments_by_x;\n\n// For 45-degree segments, we use transformed coordinates:\n// u = x + y\n// v = x - y\n// A segment with dx=dy becomes horizontal in (u,v) space (v is constant).\n//   Stored in uv_v_segments_by_v: key is the constant v, value is the range of u {min_u, max_u}.\n// A segment with dx=-dy becomes vertical in (u,v) space (u is constant).\n//   Stored in uv_h_segments_by_u: key is the constant u, value is the range of v {min_v, max_v}.\nmap<int, set<pair<int, int>>> uv_h_segments_by_u; // Stores vertical segments in (u,v) plane\nmap<int, set<pair<int, int>>> uv_v_segments_by_v; // Stores horizontal segments in (u,v) plane\n\n// Calculates the weight of a grid point based on its distance from the center.\nlong long weight(Point p) {\n    long long dx = p.x - center.x;\n    long long dy = p.y - center.y;\n    return dx * dx + dy * dy + 1;\n}\n\n// Adds a new segment (defined by two points) to the appropriate segment tracking maps.\nvoid add_segment(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        v_segments_by_x[p1.x].insert({min_y, max_y});\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        h_segments_by_y[p1.y].insert({min_x, max_x});\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // For 45-degree segments, |dx| must equal |dy|.\n        // This check is defensive; it should not be necessary if rectangle shape is correctly validated.\n        if (abs(dx) != abs(dy)) {\n             return; \n        }\n\n        int u1 = p1.x + p1.y;\n        int v1 = p1.x - p1.y;\n        int u2 = p2.x + p2.y;\n        int v2 = p2.x - p2.y;\n\n        if (dx == dy) { // Segment is horizontal in (u,v) space (v is constant).\n            int v_const = v1; // v1 == v2 for dx=dy.\n            // Store in uv_v_segments_by_v, keyed by the constant v. Range is of u.\n            uv_v_segments_by_v[v_const].insert({min(u1, u2), max(u1, u2)});\n        } else { // dx == -dy. Segment is vertical in (u,v) space (u is constant).\n            int u_const = u1; // u1 == u2 for dx=-dy.\n            // Store in uv_h_segments_by_u, keyed by the constant u. Range is of v.\n            uv_h_segments_by_u[u_const].insert({min(v1, v2), max(v1, v2)});\n        }\n    }\n}\n\n// Checks if a new segment defined by p1 and p2 overlaps with any previously drawn segment.\nbool check_segment_overlap(Point p1, Point p2) {\n    if (p1.x == p2.x) { // Vertical axis-aligned segment\n        int min_y = min(p1.y, p2.y);\n        int max_y = max(p1.y, p2.y);\n        \n        auto it_map = v_segments_by_x.find(p1.x); // Look for segments on the same vertical line.\n        if (it_map != v_segments_by_x.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_y, max_y}.\n            \n            // Efficiently find potentially overlapping segments.\n            // Find the first segment whose max_y is greater than or equal to our min_y.\n            // A segment [seg_min_y, seg_max_y] overlaps with [min_y, max_y] if seg_max_y >= min_y AND seg_min_y <= max_y.\n            // We search for segments whose 'first' element (seg_min_y) is <= max_y.\n            // `upper_bound({max_y, -1})` finds the first element strictly greater than {max_y, -1}.\n            // Decrementing it gives the first element that might overlap (its start is <= max_y).\n            auto it = segments.upper_bound({max_y, -1}); \n            if (it != segments.begin()) {\n                --it; // Move to the first segment that could overlap.\n                do {\n                    // Check for overlap: existing segment [it->first, it->second] vs new segment [min_y, max_y].\n                    if (it->second >= min_y && it->first <= max_y) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break; // Stop if we reached the beginning.\n                    --it; // Move to the next potential overlapping segment.\n                } while (it->first >= min_y); // Optimization: If an existing segment starts before our new segment, further preceding segments cannot overlap.\n            }\n        }\n    } else if (p1.y == p2.y) { // Horizontal axis-aligned segment\n        int min_x = min(p1.x, p2.x);\n        int max_x = max(p1.x, p2.x);\n        \n        auto it_map = h_segments_by_y.find(p1.y); // Look for segments on the same horizontal line.\n        if (it_map != h_segments_by_y.end()) {\n            const auto& segments = it_map->second; // These are stored as {min_x, max_x}.\n            \n            auto it = segments.upper_bound({max_x, -1});\n            if (it != segments.begin()) {\n                --it;\n                do {\n                    // Existing segment [it->first, it->second] vs new segment [min_x, max_x].\n                    if (it->second >= min_x && it->first <= max_x) {\n                        return true; // Overlap found.\n                    }\n                    if (it == segments.begin()) break;\n                    --it;\n                } while (it->first >= min_x);\n            }\n        }\n    } else { // 45-degree segment\n        int dx = p2.x - p1.x;\n        int dy = p2.y - p1.y;\n\n        // This branch is for 45-degree segments, where |dx| == |dy|.\n        if (abs(dx) != abs(dy)) return false; // Should not happen if shape is valid.\n\n        // Calculate transformed coordinates for the new segment.\n        int u1_new = p1.x + p1.y;\n        int v1_new = p1.x - p1.y;\n        int u2_new = p2.x + p2.y;\n        int v2_new = p2.x - p2.y;\n\n        if (dx == dy) { // New segment is horizontal in (u,v) space (v is constant).\n            int v_const_new = v1_new; // v1_new == v2_new.\n            int min_u_new = min(u1_new, u2_new);\n            int max_u_new = max(u1_new, u2_new);\n\n            auto it_map = uv_v_segments_by_v.find(v_const_new); // Map stores horizontal segments in (u,v).\n            if (it_map != uv_v_segments_by_v.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_u, max_u}.\n                \n                auto it = segments.upper_bound({max_u_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_u_new, max_u_new].\n                        if (it->second >= min_u_new && it->first <= max_u_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_u_new);\n                }\n            }\n        } else { // dx == -dy. New segment is vertical in (u,v) space (u is constant).\n            int u_const_new = u1_new; // u1_new == u2_new.\n            int min_v_new = min(v1_new, v2_new);\n            int max_v_new = max(v1_new, v2_new);\n\n            auto it_map = uv_h_segments_by_u.find(u_const_new); // Map stores vertical segments in (u,v).\n            if (it_map != uv_h_segments_by_u.end()) {\n                const auto& segments = it_map->second; // These are stored as {min_v, max_v}.\n                \n                auto it = segments.upper_bound({max_v_new, -1});\n                if (it != segments.begin()) {\n                    --it;\n                    do {\n                        // Existing segment [it->first, it->second] vs new segment [min_v_new, max_v_new].\n                        if (it->second >= min_v_new && it->first <= max_v_new) {\n                            return true; // Overlap found.\n                        }\n                        if (it == segments.begin()) break;\n                        --it;\n                    } while (it->first >= min_v_new);\n                }\n            }\n        }\n    }\n    return false; // No overlap found.\n}\n\n\n// Checks if a point 'test_p' lies strictly on the line segment defined by 'seg_p1' and 'seg_p2',\n// excluding the endpoints.\nbool is_point_on_segment_exclusive(Point test_p, Point seg_p1, Point seg_p2) {\n    if (seg_p1 == seg_p2) return false; // Degenerate segment.\n\n    // Check collinearity using the cross product.\n    // (test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) == (test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y)\n    long long cross_product = (long long)(test_p.y - seg_p1.y) * (seg_p2.x - seg_p1.x) - (long long)(test_p.x - seg_p1.x) * (seg_p2.y - seg_p1.y);\n    if (cross_product != 0) return false; // Not collinear.\n\n    // Check if the point lies within the bounding box of the segment.\n    bool on_x = (test_p.x >= min(seg_p1.x, seg_p2.x) && test_p.x <= max(seg_p1.x, seg_p2.x));\n    bool on_y = (test_p.y >= min(seg_p1.y, seg_p2.y) && test_p.y <= max(seg_p1.y, seg_p2.y));\n\n    if (!on_x || !on_y) return false; // Collinear but outside the segment's bounds.\n\n    // Point is collinear and within the bounding box. Now check if it's strictly between the endpoints.\n    // It's strictly between if it's not equal to either endpoint.\n    bool is_endpoint1 = (test_p.x == seg_p1.x && test_p.y == seg_p1.y);\n    bool is_endpoint2 = (test_p.x == seg_p2.x && test_p.y == seg_p2.y);\n    \n    return !(is_endpoint1 || is_endpoint2);\n}\n\n// Checks Condition 2: No dots (other than the rectangle's corners) lie on the perimeter of the proposed rectangle.\n// p1_new is the point where the new dot will be placed.\n// p2_old, p3_old, p4_old are the three existing points that form the rectangle with p1_new.\nbool check_perimeter_dots(Point p1_new, Point p2_old, Point p3_old, Point p4_old, const set<Point>& current_dots) {\n    // Define the four segments of the rectangle.\n    Point segments[4][2] = {{p1_new, p2_old}, {p2_old, p3_old}, {p3_old, p4_old}, {p4_old, p1_new}};\n    \n    // The dots that are allowed to be on the perimeter are the existing corners of the rectangle.\n    set<Point> allowed_on_perimeter = {p2_old, p3_old, p4_old};\n\n    for (auto& seg : segments) {\n        Point seg_p1 = seg[0];\n        Point seg_p2 = seg[1];\n\n        if (seg_p1 == seg_p2) continue; // Skip degenerate segments.\n\n        // Iterate through all currently placed dots.\n        for (const auto& dot : current_dots) {\n            // If the dot is one of the allowed corners, it's fine.\n            if (allowed_on_perimeter.count(dot)) continue;\n            \n            // Check if this dot lies strictly on the current segment.\n            if (is_point_on_segment_exclusive(dot, seg_p1, seg_p2)) {\n                return false; // Found a forbidden dot on the perimeter.\n            }\n        }\n    }\n    return true; // No forbidden dots found on any segment.\n}\n\n// Checks if four points (p1, p2, p3, p4) in order form a valid rectangle.\n// p1 is the potential new dot, and p2, p3, p4 are existing dots.\nbool check_rectangle_shape_and_order(Point p1, Point p2, Point p3, Point p4) {\n    // Calculate vectors for each side.\n    long long dx1 = p2.x - p1.x; // Vector p1->p2\n    long long dy1 = p2.y - p1.y;\n    long long dx2 = p3.x - p2.x; // Vector p2->p3\n    long long dy2 = p3.y - p2.y;\n    long long dx3 = p4.x - p3.x; // Vector p3->p4\n    long long dy3 = p4.y - p3.y;\n    long long dx4 = p1.x - p4.x; // Vector p4->p1\n    long long dy4 = p1.y - p4.y;\n\n    // A rectangle is a parallelogram with perpendicular adjacent sides.\n    // Check if opposite sides are parallel and equal in length:\n    // Vector p1->p2 should be the negation of p3->p4 (or p4->p3).\n    bool side1_matches_side3 = (dx1 == -dx3) && (dy1 == -dy3);\n    // Vector p2->p3 should be the negation of p4->p1 (or p1->p4).\n    bool side2_matches_side4 = (dx2 == -dx4) && (dy2 == -dy4);\n\n    if (!side1_matches_side3 || !side2_matches_side4) {\n        return false; // Not a parallelogram.\n    }\n    \n    // Check if adjacent sides are perpendicular using the dot product.\n    // Dot product of vector p1->p2 and vector p2->p3 must be zero.\n    long long dot_product_12_23 = dx1 * dx2 + dy1 * dy2;\n    \n    if (dot_product_12_23 != 0) {\n        return false; // Adjacent sides are not perpendicular.\n    }\n\n    // All conditions met: it's a rectangle.\n    return true;\n}\n\n// Structure to represent a candidate move (placing a new dot).\nstruct CandidateMove {\n    Point p1_new; // The new dot's coordinates.\n    Point p2_old, p3_old, p4_old; // The three existing dots used to form the rectangle.\n    long long weight_val; // The weight of the new dot (p1_new).\n\n    // For sorting candidates: we want the move that adds the point with the highest weight.\n    bool operator<(const CandidateMove& other) const {\n        return weight_val < other.weight_val; // Ascending for std::sort, so we sort reversed later.\n    }\n};\n\n// Finds all possible valid moves (rectangles that can be drawn).\nvector<CandidateMove> find_candidate_moves(const set<Point>& current_dots) {\n    vector<CandidateMove> candidates;\n    // Convert the set of dots to a vector for easier iteration.\n    vector<Point> dots_vec(current_dots.begin(), current_dots.end());\n\n    // Strategy: Iterate through pairs of existing dots (pa, pb) and check if they can be part of a rectangle.\n\n    // --- Generate Axis-Aligned Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point pa = dots_vec[i];\n            Point pb = dots_vec[j];\n\n            // Case 1: pa and pb share the same y-coordinate (form a horizontal segment).\n            if (pa.y == pb.y) {\n                int y_base = pa.y;\n                int x1 = min(pa.x, pb.x);\n                int x2 = max(pa.x, pb.x);\n                \n                // Search for points on parallel lines y_new = y_base + dy and y_new = y_base - dy.\n                // We search symmetrically outwards from the base segment.\n                for (int dy = 1; ; ++dy) {\n                    // If both upward and downward searches go out of bounds, stop.\n                    if (y_base + dy >= N_val && y_base - dy < 0) break; \n\n                    bool found_upper = false;\n                    Point pc_upper = {-1, -1}, pd_upper = {-1, -1}; // Placeholder for potential points.\n                    // Check for points on the line y_base + dy.\n                    if (y_base + dy < N_val) {\n                        pc_upper = {x1, y_base + dy};\n                        pd_upper = {x2, y_base + dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_upper) && current_dots.count(pd_upper)) {\n                            found_upper = true;\n                        }\n                    }\n\n                    bool found_lower = false;\n                    Point pc_lower = {-1, -1}, pd_lower = {-1, -1};\n                    // Check for points on the line y_base - dy.\n                    if (y_base - dy >= 0) {\n                        pc_lower = {x1, y_base - dy};\n                        pd_lower = {x2, y_base - dy};\n                        // If both potential points exist in current_dots.\n                        if (current_dots.count(pc_lower) && current_dots.count(pd_lower)) {\n                            found_lower = true;\n                        }\n                    }\n\n                    // If no points were found in either direction at this distance 'dy',\n                    // and 'dy' has exceeded a reasonable limit (e.g., grid size), stop searching in this direction.\n                    if (!found_upper && !found_lower) {\n                        if (dy > N_val) break; // Heuristic limit to prevent excessive search.\n                        continue; // Continue to the next 'dy' if not out of bounds.\n                    }\n                    \n                    // If we found two points on the upper line (pc_upper, pd_upper):\n                    if (found_upper) {\n                        // Potential rectangle vertices are: (x1, y_base), (x2, y_base), pc_upper, pd_upper.\n                        // We need to find a NEW dot (p_new) and three OLD dots (p2_old, p3_old, p4_old).\n                        // If pc_upper is empty, it can be p_new. The existing dots are pd_upper, pa, pb.\n                        Point p_new = pc_upper;\n                        if (!current_dots.count(p_new)) {\n                            // Try forming the rectangle with p_new and the three existing dots.\n                            // The existing dots for this case are pd_upper, pa, pb.\n                            // Vertices are (x1, y_base), (x2, y_base), (x2, y_base+dy), (x1, y_base+dy).\n                            // Possible pairings for (p2_old, p3_old, p4_old) to form a rectangle with p_new=(x1, y_base+dy):\n                            // 1. (p_new, (x1, y_base), (x2, y_base), (x2, y_base+dy))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_upper)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_upper, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // 2. (p_new, pd_upper, pb, pa) - this order tries to form a rectangle (x1,y_up), (x2,y_up), (x2,y_base), (x1,y_base)\n                            if (current_dots.count(pd_upper) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_upper, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_upper) &&\n                                        !check_segment_overlap(pd_upper, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_upper, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_upper, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_upper is empty, it can be p_new. Existing dots: pc_upper, pa, pb.\n                        p_new = pd_upper;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_upper, pa, pb) -> ((x2, y_base+dy), (x1, y_base+dy), (x1, y_base), (x2, y_base))\n                            if (current_dots.count(pc_upper) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_upper, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_upper, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_upper, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pb, pa, pc_upper) -> ((x2, y_base+dy), (x2, y_base), (x1, y_base), (x1, y_base+dy))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_upper)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_upper)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_upper) &&\n                                        !check_segment_overlap(pc_upper, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_upper, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_upper, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    // If both upper and lower lines had pairs of points, we don't need to search further for this pa, pb pair in 'dy' direction.\n                    if (found_upper && found_lower) break; \n                    // If neither direction yielded points, further 'dy' won't find them either.\n                    if (!found_upper && !found_lower) break;\n                }\n            }\n\n            // Case 2: pa and pb share the same x-coordinate (form a vertical segment).\n            if (pa.x == pb.x) {\n                int x_base = pa.x;\n                int y1 = min(pa.y, pb.y);\n                int y2 = max(pa.y, pb.y);\n\n                // Search for points on parallel lines x_new = x_base + dx and x_new = x_base - dx.\n                for (int dx = 1; ; ++dx) {\n                    if (x_base + dx >= N_val && x_base - dx < 0) break;\n\n                    bool found_right = false;\n                    Point pc_right = {-1, -1}, pd_right = {-1, -1};\n                    // Check for points on the line x_base + dx.\n                    if (x_base + dx < N_val) {\n                        pc_right = {x_base + dx, y1};\n                        pd_right = {x_base + dx, y2};\n                        if (current_dots.count(pc_right) && current_dots.count(pd_right)) {\n                            found_right = true;\n                        }\n                    }\n\n                    bool found_left = false;\n                    Point pc_left = {-1, -1}, pd_left = {-1, -1};\n                    // Check for points on the line x_base - dx.\n                    if (x_base - dx >= 0) {\n                        pc_left = {x_base - dx, y1};\n                        pd_left = {x_base - dx, y2};\n                        if (current_dots.count(pc_left) && current_dots.count(pd_left)) {\n                            found_left = true;\n                        }\n                    }\n\n                    if (!found_right && !found_left) {\n                        if (dx > N_val) break;\n                        continue;\n                    }\n\n                    // If we found two points on the right line (pc_right, pd_right):\n                    if (found_right) {\n                        // Potential rectangle vertices: (x_base, y1), (x_base, y2), pc_right, pd_right.\n                        // Try placing new dot at pc_right. Existing dots are pd_right, pa, pb.\n                        Point p_new = pc_right;\n                        if (!current_dots.count(p_new)) {\n                            // Try (p_new, pa, pb, pd_right) -> ((x_base+dx, y1), (x_base, y1), (x_base, y2), (x_base+dx, y2))\n                            if (current_dots.count(pa) && current_dots.count(pb) && current_dots.count(pd_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pa, pb, pd_right)) {\n                                    if (!check_segment_overlap(p_new, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, pd_right) &&\n                                        !check_segment_overlap(pd_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pa, pb, pd_right, current_dots)) {\n                                             candidates.push_back({p_new, pa, pb, pd_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Try (p_new, pd_right, pb, pa) -> ((x_base+dx, y1), (x_base+dx, y2), (x_base, y2), (x_base, y1))\n                             if (current_dots.count(pd_right) && current_dots.count(pb) && current_dots.count(pa)) {\n                                if (check_rectangle_shape_and_order(p_new, pd_right, pb, pa)) {\n                                    if (!check_segment_overlap(p_new, pd_right) &&\n                                        !check_segment_overlap(pd_right, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, p_new)) {\n                                        if (check_perimeter_dots(p_new, pd_right, pb, pa, current_dots)) {\n                                             candidates.push_back({p_new, pd_right, pb, pa, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                        // Similarly, if pd_right is empty, it can be p_new. Existing dots: pc_right, pa, pb.\n                        p_new = pd_right;\n                         if (!current_dots.count(p_new)) {\n                            // Try (p_new, pc_right, pa, pb) -> ((x_base+dx, y2), (x_base+dx, y1), (x_base, y1), (x_base, y2))\n                            if (current_dots.count(pc_right) && current_dots.count(pa) && current_dots.count(pb)) {\n                                if (check_rectangle_shape_and_order(p_new, pc_right, pa, pb)) {\n                                    if (!check_segment_overlap(p_new, pc_right) &&\n                                        !check_segment_overlap(pc_right, pa) &&\n                                        !check_segment_overlap(pa, pb) &&\n                                        !check_segment_overlap(pb, p_new)) {\n                                        if (check_perimeter_dots(p_new, pc_right, pa, pb, current_dots)) {\n                                             candidates.push_back({p_new, pc_right, pa, pb, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                             // Try (p_new, pb, pa, pc_right) -> ((x_base+dx, y2), (x_base, y2), (x_base, y1), (x_base+dx, y1))\n                            if (current_dots.count(pb) && current_dots.count(pa) && current_dots.count(pc_right)) {\n                                if (check_rectangle_shape_and_order(p_new, pb, pa, pc_right)) {\n                                    if (!check_segment_overlap(p_new, pb) &&\n                                        !check_segment_overlap(pb, pa) &&\n                                        !check_segment_overlap(pa, pc_right) &&\n                                        !check_segment_overlap(pc_right, p_new)) {\n                                        if (check_perimeter_dots(p_new, pb, pa, pc_right, current_dots)) {\n                                             candidates.push_back({p_new, pb, pa, pc_right, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if (found_right && found_left) break;\n                    if (!found_right && !found_left) break;\n                }\n            }\n        }\n    }\n\n    // --- Generate 45-degree Rectangle Candidates ---\n    // Iterate through all unique pairs of existing dots.\n    for (size_t i = 0; i < dots_vec.size(); ++i) {\n        for (size_t j = i + 1; j < dots_vec.size(); ++j) {\n            Point p_a = dots_vec[i];\n            Point p_b = dots_vec[j];\n\n            long long dx_ab = p_b.x - p_a.x;\n            long long dy_ab = p_b.y - p_a.y;\n\n            // Check if p_a and p_b could be adjacent vertices of a 45-degree rectangle.\n            // This implies their difference vector (dx_ab, dy_ab) must have |dx_ab| == |dy_ab| and not be zero.\n            if (abs(dx_ab) == abs(dy_ab) && dx_ab != 0) {\n                // The vector for the next side must be perpendicular and have the same length.\n                // Two possibilities for the next vector: (-dy_ab, dx_ab) and (dy_ab, -dx_ab).\n                int possible_v[2][2] = {{- (int)dy_ab, (int)dx_ab}, {(int)dy_ab, - (int)dx_ab}};\n\n                for (int k = 0; k < 2; ++k) {\n                    long long next_dx = possible_v[k][0];\n                    long long next_dy = possible_v[k][1];\n\n                    // Calculate the coordinates of the other two potential vertices of the rectangle.\n                    Point p_c = {p_b.x + (int)next_dx, p_b.y + (int)next_dy}; // p_c = p_b + next_vector\n                    Point p_d = {p_a.x + (int)next_dx, p_a.y + (int)next_dy}; // p_d = p_a + next_vector\n\n                    // Check if these potential points are within grid bounds.\n                    if (p_c.x >= 0 && p_c.x < N_val && p_c.y >= 0 && p_c.y < N_val &&\n                        p_d.x >= 0 && p_d.x < N_val && p_d.y >= 0 && p_d.y < N_val) {\n                        \n                        // If both p_c and p_d already exist as dots:\n                        if (current_dots.count(p_c) && current_dots.count(p_d)) {\n                            // We've found a rectangle formed by p_a, p_b, p_c, p_d.\n                            // A new dot can be placed at any of these vertices if it's currently empty.\n                            // We need to find an empty point (p_new) and three existing points (p2, p3, p4).\n\n                            // Case 1: p_a is the new dot (p_new). p_b, p_c, p_d must be existing dots.\n                            Point p_new = p_a;\n                            if (!current_dots.count(p_new)) { // Check if p_a is empty.\n                                // Order: (p_new, p_b, p_c, p_d) where p_b is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_b, p_c, p_d)) {\n                                    // Check for segment overlaps and perimeter dots.\n                                    if (!check_segment_overlap(p_new, p_b) &&\n                                        !check_segment_overlap(p_b, p_c) &&\n                                        !check_segment_overlap(p_c, p_d) &&\n                                        !check_segment_overlap(p_d, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_b, p_c, p_d, current_dots)) {\n                                            candidates.push_back({p_new, p_b, p_c, p_d, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 2: p_b is the new dot (p_new). p_a, p_c, p_d must be existing dots.\n                            p_new = p_b;\n                            if (!current_dots.count(p_new)) { // Check if p_b is empty.\n                                // Order: (p_new, p_a, p_d, p_c) where p_a is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_a, p_d, p_c)) {\n                                    if (!check_segment_overlap(p_new, p_a) &&\n                                        !check_segment_overlap(p_a, p_d) &&\n                                        !check_segment_overlap(p_d, p_c) &&\n                                        !check_segment_overlap(p_c, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_a, p_d, p_c, current_dots)) {\n                                            candidates.push_back({p_new, p_a, p_d, p_c, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 3: p_c is the new dot (p_new). p_a, p_b, p_d must be existing dots.\n                            p_new = p_c;\n                            if (!current_dots.count(p_new)) { // Check if p_c is empty.\n                                // Order: (p_new, p_d, p_a, p_b) where p_d is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_d, p_a, p_b)) {\n                                    if (!check_segment_overlap(p_new, p_d) &&\n                                        !check_segment_overlap(p_d, p_a) &&\n                                        !check_segment_overlap(p_a, p_b) &&\n                                        !check_segment_overlap(p_b, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_d, p_a, p_b, current_dots)) {\n                                            candidates.push_back({p_new, p_d, p_a, p_b, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                            // Case 4: p_d is the new dot (p_new). p_a, p_b, p_c must be existing dots.\n                            p_new = p_d;\n                            if (!current_dots.count(p_new)) { // Check if p_d is empty.\n                                // Order: (p_new, p_c, p_b, p_a) where p_c is adjacent to p_new.\n                                if (check_rectangle_shape_and_order(p_new, p_c, p_b, p_a)) {\n                                    if (!check_segment_overlap(p_new, p_c) &&\n                                        !check_segment_overlap(p_c, p_b) &&\n                                        !check_segment_overlap(p_b, p_a) &&\n                                        !check_segment_overlap(p_a, p_new)) {\n                                        if (check_perimeter_dots(p_new, p_c, p_b, p_a, current_dots)) {\n                                            candidates.push_back({p_new, p_c, p_b, p_a, weight(p_new)});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    return candidates;\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int M; // Number of initially placed dots.\n    cin >> N_val >> M;\n\n    // Calculate grid center coordinates. N is always odd.\n    center = {(int)(N_val - 1) / 2, (int)(N_val - 1) / 2};\n    total_weight_sum_val = 0; // Initialize total weight sum.\n\n    // Store the initial dots.\n    set<Point> current_dots;\n    for (int i = 0; i < M; ++i) {\n        int x, y;\n        cin >> x >> y;\n        current_dots.insert({x, y});\n        total_weight_sum_val += weight({x, y}); // Add weight of initial dots.\n    }\n\n    // Store the operations performed.\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    int ops_count = 0;\n    // Game loop: continue as long as possible and within the operation limit.\n    while (ops_count < MAX_OPS) {\n        // Find all possible moves.\n        vector<CandidateMove> candidates = find_candidate_moves(current_dots);\n\n        // If no more moves can be made, break the loop.\n        if (candidates.empty()) {\n            break; \n        }\n\n        // Sort candidates in descending order of weight (using reverse iterators on ascending sort).\n        sort(candidates.rbegin(), candidates.rend());\n\n        // Select the best move: the one with the highest weight for the new dot.\n        const auto& best_move = candidates[0];\n\n        // Apply the best move: add the new dot and update total weight.\n        current_dots.insert(best_move.p1_new);\n        total_weight_sum_val += best_move.weight_val;\n        ops_count++;\n\n        // Record the operation details.\n        operations.emplace_back(best_move.p1_new.x, best_move.p1_new.y,\n                                best_move.p2_old.x, best_move.p2_old.y,\n                                best_move.p3_old.x, best_move.p3_old.y,\n                                best_move.p4_old.x, best_move.p4_old.y);\n\n        // Add the segments of the newly drawn rectangle to the tracking maps.\n        add_segment(best_move.p1_new, best_move.p2_old);\n        add_segment(best_move.p2_old, best_move.p3_old);\n        add_segment(best_move.p3_old, best_move.p4_old);\n        add_segment(best_move.p4_old, best_move.p1_new);\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output the details of each operation.\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) << endl;\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath>\n#include <tuple>       // For std::tuple and std::tie\n#include <array>       // For std::array\n#include <queue>       // Not used, but common for grid problems\n\nusing namespace std;\n\nconst int SIZE = 10;\n// Maximum possible Manhattan distance in a 10x10 grid (e.g., from (0,0) to (9,9)).\nconst int MAX_DIST = (SIZE - 1) + (SIZE - 1); \n\n// Global board state. Using std::array for better C++ integration and compatibility with std::tuple.\n// 0 means empty, 1, 2, 3 represent the flavors.\nstd::array<std::array<int, SIZE>, SIZE> board;\n\n// Stores the predefined sequence of candy flavors (f_1, f_2, ..., f_100)\nint f_sequence[101];\n\n// Helper function to find the p_t-th empty cell.\n// Cells are numbered 1 to (101-t) based on row-major order.\n// Returns a pair {row, col} of the cell's coordinates.\npair<int, int> get_pt_empty_cell(int p_t) {\n    int empty_count = 0; // Counter for empty cells found so far\n    // Iterate through the grid row by row, then column by column\n    for (int r = 0; r < SIZE; ++r) {\n        for (int c = 0; c < SIZE; ++c) {\n            // If the current cell is empty\n            if (board[r][c] == 0) {\n                empty_count++; // Increment the count of empty cells\n                // If this is the p_t-th empty cell, return its coordinates\n                if (empty_count == p_t) {\n                    return {r, c};\n                }\n            }\n        }\n    }\n    // This part should ideally not be reached in a valid game state\n    // as p_t is guaranteed to be within the range of available empty cells.\n    return {-1, -1};\n}\n\n// Applies a tilt operation to the global 'board'.\n// This function modifies the actual game state.\nvoid apply_actual_tilt(char dir) {\n    // Create a temporary copy of the current board state.\n    // This is necessary because the tilt operation affects all candies simultaneously,\n    // and we need to know the state *before* any candy has moved to correctly update others.\n    std::array<std::array<int, SIZE>, SIZE> temp_board_state = board;\n\n    // Handle each tilt direction\n    if (dir == 'F') { // Tilt Forward (candies move towards larger row indices, i.e., down)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col; // Stores flavors in this column in their original order\n            // Collect all flavors in the current column from top to bottom from the *copied* state\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the column in the global board (preparing to repopulate)\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            // Repopulate the column from the bottom, packing candies\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[SIZE - 1 - (k - 1 - i)][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'B') { // Tilt Backward (candies move towards smaller row indices, i.e., up)\n        for (int col = 0; col < SIZE; ++col) { // Process column by column\n            vector<int> flavors_in_col;\n            for (int row = 0; row < SIZE; ++row) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_col.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the column in the global board\n            for (int row = 0; row < SIZE; ++row) {\n                board[row][col] = 0;\n            }\n            // Repopulate the column from the top, packing candies\n            int k = flavors_in_col.size();\n            for (int i = 0; i < k; ++i) {\n                board[i][col] = flavors_in_col[i];\n            }\n        }\n    } else if (dir == 'R') { // Tilt Right (candies move towards larger column indices, i.e., right)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the row in the global board\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            // Repopulate the row from the right, packing candies\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][SIZE - 1 - (k - 1 - i)] = flavors_in_row[i];\n            }\n        }\n    } else { // dir == 'L', Tilt Left (candies move towards smaller column indices, i.e., left)\n        for (int row = 0; row < SIZE; ++row) { // Process row by row\n            vector<int> flavors_in_row;\n            for (int col = 0; col < SIZE; ++col) {\n                if (temp_board_state[row][col] != 0) {\n                    flavors_in_row.push_back(temp_board_state[row][col]);\n                }\n            }\n            // Clear the row in the global board\n            for (int col = 0; col < SIZE; ++col) {\n                board[row][col] = 0;\n            }\n            // Repopulate the row from the left, packing candies\n            int k = flavors_in_row.size();\n            for (int i = 0; i < k; ++i) {\n                board[row][i] = flavors_in_row[i];\n            }\n        }\n    }\n}\n\n// Simulates a tilt on a copy of the current board state.\n// Returns:\n// 1. The final row of the *newly placed* candy.\n// 2. The final column of the *newly placed* candy.\n// 3. The resulting board state after the tilt.\n// Uses std::array for the board state to enable proper tuple inclusion.\n// The original position (original_r, original_c) of the new candy is required to track its movement.\nstd::tuple<int, int, std::array<std::array<int, SIZE>, SIZE>> simulate_tilt_and_get_new_candy_pos(char dir, int original_r, int original_c) {\n    // This array will hold the board state after the simulated tilt.\n    std::array<std::array<int, SIZE>, SIZE> sim_board_state = board; // Copy current global board\n\n    int sim_r_final = -1, sim_c_final = -1; // Will store the final position of the *newly placed* candy\n\n    // Apply tilt logic to sim_board_state\n    if (dir == 'F') { // Move down\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor} in the column\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) { // Read from the copied state\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end()); // Sort by original row to determine packing order\n\n        int k = occupied_in_col.size();\n        // Clear the column in the simulated board before repopulating\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from bottom\n        for (int i = 0; i < k; ++i) {\n            int original_row_in_col = occupied_in_col[i].first; // Row index *before* clearing column\n            int new_row = SIZE - 1 - (k - 1 - i); // Packed to the bottom\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            // Check if this is the candy we are tracking by comparing its original row index\n            if (original_row_in_col == original_r) { \n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'B') { // Move up\n        vector<pair<int, int>> occupied_in_col; // Stores {original_row, flavor}\n        for (int row = 0; row < SIZE; ++row) {\n            if (sim_board_state[row][original_c] != 0) {\n                occupied_in_col.push_back({row, sim_board_state[row][original_c]});\n            }\n        }\n        sort(occupied_in_col.begin(), occupied_in_col.end());\n\n        int k = occupied_in_col.size();\n        for(int row=0; row<SIZE; ++row) sim_board_state[row][original_c] = 0;\n\n        // Repopulate column from top\n        for (int i = 0; i < k; ++i) {\n            int original_row_in_col = occupied_in_col[i].first;\n            int new_row = i; // Packed to the top\n            sim_board_state[new_row][original_c] = occupied_in_col[i].second;\n            if (original_row_in_col == original_r) {\n                sim_r_final = new_row;\n                sim_c_final = original_c;\n            }\n        }\n    } else if (dir == 'R') { // Move right\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from right\n        for (int i = 0; i < k; ++i) {\n            int original_col_in_row = occupied_in_row[i].first;\n            int new_col = SIZE - 1 - (k - 1 - i); // Packed to the right\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col_in_row == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    } else { // dir == 'L', Move left\n        vector<pair<int, int>> occupied_in_row; // Stores {original_col, flavor}\n        for (int col = 0; col < SIZE; ++col) {\n            if (sim_board_state[original_r][col] != 0) {\n                occupied_in_row.push_back({col, sim_board_state[original_r][col]});\n            }\n        }\n        sort(occupied_in_row.begin(), occupied_in_row.end());\n\n        int k = occupied_in_row.size();\n        for(int col=0; col<SIZE; ++col) sim_board_state[original_r][col] = 0;\n\n        // Repopulate row from left\n        for (int i = 0; i < k; ++i) {\n            int original_col_in_row = occupied_in_row[i].first;\n            int new_col = i; // Packed to the left\n            sim_board_state[original_r][new_col] = occupied_in_row[i].second;\n            if (original_col_in_row == original_c) {\n                sim_r_final = original_r;\n                sim_c_final = new_col;\n            }\n        }\n    }\n    // Return the final position of the new candy and the simulated board state\n    return {sim_r_final, sim_c_final, sim_board_state};\n}\n\n// Calculates metrics for a given simulated board state and new candy position.\n// Returns:\n// 1. Number of neighbors within Manhattan distance D=2.\n// 2. Minimum Manhattan distance to any neighbor of the same flavor.\n//    If no neighbors exist, this is MAX_DIST.\npair<int, int> get_neighbor_metrics(int r, int c, int flavor, const std::array<std::array<int, SIZE>, SIZE>& sim_board) {\n    int num_neighbors_close = 0;\n    int min_dist_to_any_neighbor = MAX_DIST; // Initialize with a value indicating no neighbor found yet\n    const int CLOSE_DIST_THRESHOLD = 2; // Manhattan distance threshold for \"close\" neighbors\n\n    for (int r_other = 0; r_other < SIZE; ++r_other) {\n        for (int c_other = 0; c_other < SIZE; ++c_other) {\n            // Check if it's a candy of the same flavor AND it's NOT the new candy itself.\n            if (sim_board[r_other][c_other] == flavor && !(r_other == r && c_other == c)) {\n                int dist = abs(r - r_other) + abs(c - c_other);\n                \n                // Update minimum distance to any neighbor\n                min_dist_to_any_neighbor = min(min_dist_to_any_neighbor, dist);\n                \n                // Count neighbors within the close distance threshold\n                if (dist <= CLOSE_DIST_THRESHOLD) {\n                    num_neighbors_close++;\n                }\n            }\n        }\n    }\n    return {num_neighbors_close, min_dist_to_any_neighbor};\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the predefined sequence of candy flavors from input\n    for (int i = 1; i <= 100; ++i) {\n        cin >> f_sequence[i];\n    }\n\n    // Initialize the global board to be empty (all cells set to 0)\n    for (int i = 0; i < SIZE; ++i) {\n        for (int j = 0; j < SIZE; ++j) {\n            board[i][j] = 0;\n        }\n    }\n\n    // Main loop: Process each candy placement and make a tilt decision\n    // t is the current candy number being placed (1 to 100)\n    for (int t = 1; t <= 100; ++t) {\n        int p_t; // The index of the empty cell where the t-th candy will be placed.\n        cin >> p_t;\n\n        // Find the coordinates where the new candy is placed.\n        pair<int, int> cell = get_pt_empty_cell(p_t);\n        int current_r = cell.first;  // Original row of the new candy\n        int current_c = cell.second; // Original column of the new candy\n        int flavor_t = f_sequence[t]; // Flavor of the new candy\n        \n        // Place the candy in the actual board FIRST.\n        // The simulation functions will then read from this updated 'board'.\n        board[current_r][current_c] = flavor_t;\n\n        // For the 100th candy, no tilt is performed or output is required.\n        if (t == 100) {\n            continue; // Skip the rest of the loop for t=100\n        }\n\n        // Heuristic variables to track the best tilt choice.\n        // We want to:\n        // 1. Maximize number of close neighbors (dist <= 2).\n        // 2. Then, minimize distance to nearest neighbor.\n        // 3. Tie-break using lexicographical order of directions ('F' < 'B' < 'L' < 'R').\n        \n        int best_num_close_neighbors = -1; // Maximize this. Initialized to a value less than any possible count (which is >= 0).\n        int best_min_dist_to_any = MAX_DIST + 1; // Minimize this. Initialized to a value greater than any possible distance.\n        char best_tilt = 'F'; // Default best tilt for tie-breaking and initial assignment.\n\n        char possible_tilts[] = {'F', 'B', 'L', 'R'};\n\n        // Evaluate each possible tilt direction\n        for (char tilt_dir : possible_tilts) {\n            int sim_r_final, sim_c_final; // Final position of the new candy after simulated tilt\n            std::array<std::array<int, SIZE>, SIZE> temp_board_state; // Board state after simulated tilt\n\n            // Simulate the tilt and get the resulting state and the new candy's final position.\n            tie(sim_r_final, sim_c_final, temp_board_state) = simulate_tilt_and_get_new_candy_pos(tilt_dir, current_r, current_c);\n\n            // Get the neighbor metrics (number of close neighbors and minimum distance to any neighbor).\n            pair<int, int> metrics = get_neighbor_metrics(sim_r_final, sim_c_final, flavor_t, temp_board_state);\n            int current_num_close = metrics.first;\n            int current_min_dist = metrics.second;\n\n            // Check if the current tilt resulted in finding any neighbors.\n            bool current_has_neighbors = (current_min_dist != MAX_DIST);\n            // Check if the best tilt found so far also resulted in neighbors.\n            bool best_has_neighbors = (best_min_dist_to_any != MAX_DIST + 1);\n\n            bool update_best = false; // Flag to indicate if the current tilt is better than the best found so far.\n\n            // Decision logic based on the heuristic priorities:\n            if (current_has_neighbors && !best_has_neighbors) {\n                // Case 1: Current tilt found neighbors, but previous best didn't. Current is strictly better.\n                update_best = true;\n            } else if (current_has_neighbors && best_has_neighbors) {\n                // Case 2: Both current and best tilt have neighbors. Compare based on priority.\n                if (current_num_close > best_num_close_neighbors) {\n                    // Priority 1: More close neighbors is better.\n                    update_best = true;\n                } else if (current_num_close == best_num_close_neighbors) {\n                    // Priority 2: If close neighbor counts are tied, minimize nearest neighbor distance.\n                    if (current_min_dist < best_min_dist_to_any) {\n                        update_best = true;\n                    }\n                    // If still tied (current_min_dist == best_min_dist_to_any), the loop order handles Priority 3 (lexicographical).\n                    // 'best_tilt' will not be updated, preserving the earlier (lexicographically smaller) direction.\n                }\n            } else if (!current_has_neighbors && !best_has_neighbors) {\n                // Case 3: Neither current nor best tilt found neighbors. It's a tie.\n                // The 'best_tilt' variable already holds the lexicographically smallest direction encountered so far among those with no neighbors.\n                // No update needed, as the loop order ensures 'F' would be picked first if all are equally bad.\n            } else { // !current_has_neighbors && best_has_neighbors\n                // Case 4: Current tilt has no neighbors, but the best tilt found so far had neighbors.\n                // The best tilt is still better. Do nothing.\n            }\n\n            // If the current tilt is determined to be better, update the best tracking variables.\n            if (update_best) {\n                best_num_close_neighbors = current_num_close;\n                best_min_dist_to_any = current_min_dist;\n                best_tilt = tilt_dir;\n            }\n        }\n\n        // After evaluating all possible tilts, apply the chosen 'best_tilt' to the actual game board.\n        apply_actual_tilt(best_tilt);\n\n        // Output the chosen tilt direction, followed by a newline.\n        cout << best_tilt << endl;\n        // Flush the output buffer to ensure the judge receives the output immediately.\n        cout << flush;\n    }\n\n    // Program finishes after processing all 100 candies and their corresponding tilts.\n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <cmath> // For std::abs, std::pow\n#include <random> // For std::mt19937 and std::shuffle\n\n// Function to compute the degree sequence of a graph from its bitstring representation.\n// The input string 's' represents edges (u,v) for 0 <= u < v <= N-1 in lexicographical order.\nstd::vector<int> get_degrees_from_string(int N, const std::string& s) {\n    std::vector<int> degrees(N, 0); // Initialize degrees for all vertices to 0\n    int k = 0; // Index for iterating through the bitstring\n    for (int i = 0; i < N; ++i) {\n        for (int j = i + 1; j < N; ++j) {\n            if (s[k] == '1') { // If an edge exists between vertex i and vertex j\n                degrees[i]++; // Increment degree of vertex i\n                degrees[j]++; // Increment degree of vertex j\n            }\n            k++; // Move to the next character in the bitstring\n        }\n    }\n    return degrees;\n}\n\nint main() {\n    // Fast I/O operations\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int M;\n    double epsilon;\n    std::cin >> M >> epsilon;\n\n    // --- Strategy: N=32, Ensemble of 4 Random Graphs per class, L2 Distance ---\n    // Analysis of previous results:\n    // - N=32 with 2 seeds and L2 distance was the best performing strategy.\n    // - Increasing ensemble members (seeds) is a logical next step to improve robustness.\n    //\n    // Strategy:\n    // 1. Fixed N: Use N=32 (proven optimal).\n    // 2. Ensemble of 4 seeds: Generate 4 random variations per class i, using seeds 0, 1, 2, 3.\n    //    This creates 4M candidate graphs in total.\n    // 3. L2 Distance for Decoding: Compare query graph H_k's degree sequence against all 4M\n    //    candidate degree sequences using L2 distance: sum((d_H - d_G)^2).\n    //    Predict the class i corresponding to the closest candidate.\n\n    const int N = 32; \n    \n    // Maximum possible edges in an N-vertex graph. For N=32, this is 32*31/2 = 496.\n    int max_possible_edges = N * (N - 1) / 2;\n\n    // Store precomputed degree sequences for G_0, ..., G_{M-1}.\n    // Four versions per class i, using seeds 0, 1, 2, 3.\n    std::vector<std::vector<std::vector<int>>> precomputed_degrees(M, std::vector<std::vector<int>>(4, std::vector<int>(N)));\n    \n    // Define random number generators with different seeds.\n    std::mt19937 rng0(0); \n    std::mt19937 rng1(1); \n    std::mt19937 rng2(2); \n    std::mt19937 rng3(3); \n    \n    // Store generators in a vector for easier iteration.\n    std::vector<std::mt19937*> rngs = {&rng0, &rng1, &rng2, &rng3};\n\n    // Pre-calculate all possible edge indices in the string representation (u < v).\n    // The string index for edge (u,v) is computed by summing the number of edges in\n    // rows 0 to u-1, plus the position of v within row u.\n    std::vector<int> all_string_indices(max_possible_edges);\n    int current_edge_idx_in_list = 0;\n    for (int u = 0; u < N; ++u) {\n        // Offset for edges starting with vertex u: sum of edges in rows 0 to u-1.\n        // Formula: u * (2*N - u - 1) / 2\n        long long offset_u = static_cast<long long>(u) * (2 * N - u - 1) / 2;\n        for (int v = u + 1; v < N; ++v) {\n            // Index of edge (u,v) in the string (u < v)\n            // = offset_u + (v - (u+1))\n            all_string_indices[current_edge_idx_in_list++] = static_cast<int>(offset_u + (v - (u + 1)));\n        }\n    }\n\n    // Generate M distinct graphs (four versions per class).\n    for (int i = 0; i < M; ++i) {\n        // Calculate the target number of edges for graph G_i using linear interpolation.\n        // This spreads the edge counts across the full range [0, max_possible_edges].\n        int target_edges = static_cast<int>(static_cast<long long>(i) * max_possible_edges / (M - 1));\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n\n        // Generate graph for each seed in the ensemble.\n        for (int seed_idx = 0; seed_idx < 4; ++seed_idx) {\n            std::string current_graph_str(max_possible_edges, '0');\n            // Shuffle indices for this specific generation.\n            std::shuffle(all_string_indices.begin(), all_string_indices.end(), *rngs[seed_idx]);\n            for (int edge_pos = 0; edge_pos < target_edges; ++edge_pos) {\n                current_graph_str[all_string_indices[edge_pos]] = '1';\n            }\n            precomputed_degrees[i][seed_idx] = get_degrees_from_string(N, current_graph_str);\n        }\n    }\n\n    // Output N and the M graph strings. We use seed 0 for the output strings\n    // to ensure consistency with previous runs and for simplicity.\n    std::cout << N << std::endl;\n    std::mt19937 rng_output(0); // Use seed 0 for output strings\n    std::vector<int> current_string_indices(max_possible_edges); // Temporary copy for shuffling\n    for (int i = 0; i < M; ++i) {\n        int target_edges = static_cast<int>(static_cast<long long>(i) * max_possible_edges / (M - 1));\n        target_edges = std::min(target_edges, max_possible_edges);\n        target_edges = std::max(target_edges, 0);\n        \n        std::string current_graph_str(max_possible_edges, '0');\n        // Shuffle indices for this specific output graph string using the output seed.\n        std::copy(all_string_indices.begin(), all_string_indices.end(), current_string_indices.begin());\n        std::shuffle(current_string_indices.begin(), current_string_indices.end(), rng_output);\n        for (int edge_pos = 0; edge_pos < target_edges; ++edge_pos) {\n            current_graph_str[current_string_indices[edge_pos]] = '1';\n        }\n        std::cout << current_graph_str << std::endl;\n    }\n    // Flush the output buffer to ensure all generated graph data is sent to the judge.\n    std::cout << std::flush; \n\n    // Process the 100 queries.\n    for (int k = 0; k < 100; ++k) {\n        std::string H_str; // The graph string received for the current query H_k.\n        std::cin >> H_str;\n\n        // Compute the degree sequence of the received graph H_k.\n        std::vector<int> degrees_H = get_degrees_from_string(N, H_str);\n\n        int best_match_idx = -1; // Stores the index of the best matching G_i found so far.\n        // Initialize min_overall_dist_sq to a value larger than any possible L2 distance.\n        // For N=32, max deg=31. Max L2 distance can be ~ N * (max_deg)^2 = 32 * 31^2 = 31232.\n        // Use long long to be safe. -1 sentinel for first assignment.\n        long long min_overall_dist_sq = -1; \n\n        // Find which precomputed graph (from any of the 4 seeds) is closest to H_k's degree sequence.\n        for (int i = 0; i < M; ++i) { // Iterate through each class i\n            // For class i, find the minimum L2 distance among its 4 variations.\n            long long min_dist_sq_for_i = -1;\n\n            for (int seed_idx = 0; seed_idx < 4; ++seed_idx) { // Check each of the 4 seeds for class i\n                long long current_dist_sq = 0;\n                for (int j = 0; j < N; ++j) { // Calculate L2 distance\n                    long long diff = static_cast<long long>(degrees_H[j]) - precomputed_degrees[i][seed_idx][j];\n                    current_dist_sq += diff * diff;\n                }\n                \n                // Update min_dist_sq_for_i if this variation is better\n                if (min_dist_sq_for_i == -1 || current_dist_sq < min_dist_sq_for_i) {\n                    min_dist_sq_for_i = current_dist_sq;\n                }\n            }\n\n            // Update the overall best match if class 'i' (with its best candidate) is closer\n            // than the current overall best match.\n            if (best_match_idx == -1 || min_dist_sq_for_i < min_overall_dist_sq) {\n                min_overall_dist_sq = min_dist_sq_for_i;\n                best_match_idx = i;\n            }\n        }\n        \n        // Output the predicted index t_k.\n        std::cout << best_match_idx << std::endl;\n        // Flush the output buffer to ensure the prediction is sent immediately.\n        std::cout << std::flush; \n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Use a large value for infinity, greater than any possible shortest path sum.\n// Max path length can be approximately N * max_w = 1000 * 10^6 = 10^9.\n// The problem uses 10^9 for unreachable distances. Our internal INF must be larger\n// to correctly identify unreachable nodes in Dijkstra's algorithm.\nconst long long INF = 4e15; \n\n// Structure to represent an edge in the graph.\nstruct Edge {\n    int u, v, w, id;       // Endpoints, weight, and original index of the edge.\n    long long dist_uv;     // Shortest path distance between u and v in the original graph.\n    long long endpoint_path_sum; // Sum of shortest paths from all nodes to u and v.\n    int assignment;        // The day this edge is scheduled for repair.\n};\n\n// Structure for Dijkstra's priority queue: stores distance and vertex.\nstruct State {\n    long long dist;\n    int vertex;\n\n    // For priority_queue: sort by distance (min-heap).\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\n// Dijkstra's algorithm to find shortest paths from a single source vertex.\n// It returns a vector containing the shortest distance from start_node to every other node.\n// Time complexity: O(M log N) or O(M + N log N) depending on priority queue implementation.\nvector<long long> dijkstra(int start_node, int n, const vector<vector<pair<int, int>>>& adj) {\n    vector<long long> dist(n + 1, INF); // Initialize distances to infinity.\n    dist[start_node] = 0;               // Distance from source to itself is 0.\n    priority_queue<State, vector<State>, greater<State>> pq;\n    pq.push({0, start_node});\n\n    while (!pq.empty()) {\n        State current = pq.top();\n        pq.pop();\n\n        long long d = current.dist;\n        int v = current.vertex;\n\n        // If we found a shorter path to 'v' already, skip this one.\n        if (d > dist[v]) {\n            continue;\n        }\n\n        // Explore neighbors of vertex 'v'.\n        for (auto& edge_info : adj[v]) {\n            int neighbor = edge_info.first;\n            int weight = edge_info.second;\n            \n            // Relaxation step: If a shorter path to 'neighbor' is found through 'v'.\n            // Check for overflow before addition. If dist[v] is INF, dist[v] + weight will be larger than any finite path or INF, so this condition handles INF correctly.\n            if (dist[v] != INF && dist[v] + weight < dist[neighbor]) {\n                dist[neighbor] = dist[v] + weight;\n                pq.push({dist[neighbor], neighbor});\n            }\n        }\n    }\n    return dist;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, m, d_days, k_limit;\n    cin >> n >> m >> d_days >> k_limit;\n\n    // Adjacency list for graph: vector of vectors of pairs {neighbor, weight}.\n    // Vertices are 1-indexed in input, so we use size n+1 for 1-based indexing.\n    vector<vector<pair<int, int>>> adj(n + 1);\n    vector<Edge> edges;\n    edges.reserve(m); // Pre-allocate memory for edges.\n\n    // Read edges and build the adjacency list.\n    for (int i = 0; i < m; ++i) {\n        int u, v, w;\n        cin >> u >> v >> w;\n        adj[u].push_back({v, w});\n        adj[v].push_back({u, w}); // Graph is undirected.\n        // Store edge details including its original index 'i' (0 to m-1).\n        edges.push_back({u, v, w, i, 0, 0, 0}); // Initialize endpoint_path_sum to 0\n    }\n\n    // Step 1: Compute all-pairs shortest paths (APSP).\n    // This is done by running Dijkstra from each vertex.\n    // For N=1000, M=3000, complexity O(N*(M+N log N)) is feasible.\n    vector<vector<long long>> dist_matrix(n + 1);\n    for (int i = 1; i <= n; ++i) {\n        dist_matrix[i] = dijkstra(i, n, adj);\n    }\n\n    // Step 2: Precompute sum of shortest path distances from all nodes to each node.\n    // sum_dist_to[j] will store sum(dist_matrix[i][j] for i = 1 to N).\n    vector<long long> sum_dist_to(n + 1, 0);\n    for (int i = 1; i <= n; ++i) { // Source node\n        for (int j = 1; j <= n; ++j) { // Destination node\n            // Only add finite distances. The graph is guaranteed to be connected.\n            if (dist_matrix[i][j] != INF) {\n                sum_dist_to[j] += dist_matrix[i][j];\n            }\n        }\n    }\n\n    // Step 3: For each edge, populate dist_uv and endpoint_path_sum.\n    for (auto& edge : edges) {\n        edge.dist_uv = dist_matrix[edge.u][edge.v];\n        \n        // Calculate sum of shortest paths involving endpoints for this edge.\n        // This heuristic tries to capture how \"central\" the edge's endpoints are.\n        // Use long long to avoid overflow for sums.\n        edge.endpoint_path_sum = sum_dist_to[edge.u] + sum_dist_to[edge.v];\n    }\n\n    // Step 4: Sort edges based on a refined heuristic.\n    // Heuristic:\n    // 1. Prioritize edges that are direct shortest paths (i.e., edge.w == edge.dist_uv).\n    // 2. Among those, prioritize edges connecting vertices with high 'centrality' (large endpoint_path_sum).\n    // 3. If ties persist, prioritize edges connecting vertices that are far apart (large edge.dist_uv).\n    // 4. If ties persist, prioritize heavier edges (large edge.w).\n    sort(edges.begin(), edges.end(), [](const Edge& a, const Edge& b) {\n        bool is_direct_shortest_a = (a.dist_uv == a.w);\n        bool is_direct_shortest_b = (b.dist_uv == b.w);\n\n        if (is_direct_shortest_a != is_direct_shortest_b) {\n            // Prioritize edges that are direct shortest paths. 'true' (1) > 'false' (0).\n            return is_direct_shortest_a > is_direct_shortest_b; \n        }\n        \n        // If both are direct shortest paths OR both are not:\n        if (a.endpoint_path_sum != b.endpoint_path_sum) {\n            // Prioritize edges whose endpoints are more central (higher sum of path lengths).\n            return a.endpoint_path_sum > b.endpoint_path_sum;\n        }\n\n        if (a.dist_uv != b.dist_uv) {\n            // Prioritize edges connecting vertices that are farther apart.\n            return a.dist_uv > b.dist_uv; \n        }\n        \n        // If all previous criteria are equal:\n        // Prioritize heavier edges.\n        return a.w > b.w; \n    });\n\n    // Step 5: Assign edges to days using a round-robin approach for better balance.\n    // This ensures that the top-ranked (most critical) edges are spread out over all D days.\n    // The constraint K > ceil(M/D) guarantees that each day will receive at most ceil(M/D) edges, which is <= K.\n    vector<int> assignments(m); // To store the day assignment for each edge, indexed by its original ID.\n    \n    for (int i = 0; i < m; ++i) {\n        // Assign the i-th edge in the sorted list to day (i % d_days) + 1.\n        int assigned_day = (i % d_days) + 1;\n        edges[i].assignment = assigned_day;\n        assignments[edges[i].id] = assigned_day;\n    }\n\n    // Step 6: Output the assignments for each edge in the order they appeared in the input.\n    for (int i = 0; i < m; ++i) {\n        cout << assignments[i] << (i == m - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <map>\n#include <set>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\n// Grid index helpers\n#define GRID_IDX(x, y, z, D) ((x) * (D) * (D) + (y) * (D) + (z))\n\n// Grid access macros\n#define GRID_GET(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n#define GRID_WRITE(grid, x, y, z, D) grid[GRID_IDX(x, y, z, D)]\n\n// Polycube representation\nstruct Polycube {\n    vector<tuple<int, int, int>> cells; // Stores cells in grid coordinates (x, y, z)\n\n    // Custom comparison for Polycube, used for std::map keys.\n    // Sorts cells lexicographically.\n    bool operator<(const Polycube& other) const {\n        return cells < other.cells;\n    }\n    bool operator==(const Polycube& other) const {\n        return cells == other.cells;\n    }\n    int volume() const { return cells.size(); }\n};\n\n// Global parameters\nint D;\nvector<string> f1_str, r1_str, f2_str, r2_str;\nvector<bool> G1_grid, G2_grid; // G1_grid[idx] is true if cell can be occupied for obj1\n\n// --- ID and Shape Management ---\n// Counter for unique block IDs to be used in the output grid.\n// Each DISTINCT CONNECTED COMPONENT placed gets a unique ID.\nint next_component_output_id_counter; \n\n// Map: canonical_shape -> score_id.\n// A score_id is assigned to each distinct SHAPE. This is used for scoring.\nmap<Polycube, int> shape_to_score_id;\n// Counter for assigning new score_ids to new shapes.\nint next_score_id_counter; \n\n// Store assignments for each object.\nstruct BlockAssignment {\n    int output_id;       // Unique ID for this specific connected component in the output grid.\n    int score_id;        // ID representing its canonical shape for scoring purposes.\n    Polycube shape_grid_coords; // The actual polycube in grid coordinates.\n};\nvector<BlockAssignment> assignments1, assignments2;\n\n// Library of basic polycubes (shapes to generate orientations from)\nvector<Polycube> base_library_shapes;\n\n// Pre-generated orientations for library shapes.\n// Stores {volume, list_of_normalized_orientations}\nvector<pair<int, vector<Polycube>>> precomputed_library_orientations;\n\n// Helper to create a 3D grid vector\ntemplate<typename T>\nvector<T> create_grid_vec(size_t size, T default_val) {\n    return vector<T>(size, default_val);\n}\n\n// Convert string silhouettes to boolean grids representing valid cell locations\nvoid setup_grids() {\n    G1_grid.assign(D * D * D, false);\n    G2_grid.assign(D * D * D, false);\n\n    // For object 1, a cell (x,y,z) can be occupied if f1(z,x)=1 and r1(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int x = 0; x < D; ++x) {\n            if (f1_str[z][x] == '1') {\n                for (int y = 0; y < D; ++y) {\n                    if (r1_str[z][y] == '1') {\n                        GRID_GET(G1_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // For object 2, a cell (x,y,z) can be occupied if f2(z,x)=1 and r2(z,y)=1\n    for (int z = 0; z < D; ++z) {\n        for (int y = 0; y < D; ++y) {\n            if (r2_str[z][y] == '1') {\n                for (int x = 0; x < D; ++x) {\n                    if (f2_str[z][x] == '1') {\n                        GRID_GET(G2_grid, x, y, z, D) = true;\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Normalize a polycube: translate its cells so the minimum coordinate is (0,0,0)\n// and sort the cells lexicographically. This gives a canonical representation for translation.\nPolycube normalize(const Polycube& poly) {\n    if (poly.cells.empty()) return poly;\n    \n    int min_x = get<0>(poly.cells[0]);\n    int min_y = get<1>(poly.cells[0]);\n    int min_z = get<2>(poly.cells[0]);\n    for (const auto& cell : poly.cells) {\n        min_x = min(min_x, get<0>(cell));\n        min_y = min(min_y, get<1>(cell));\n        min_z = min(min_z, get<2>(cell));\n    }\n    \n    Polycube normalized_poly;\n    normalized_poly.cells.reserve(poly.cells.size());\n    for (const auto& cell : poly.cells) {\n        normalized_poly.cells.emplace_back(get<0>(cell) - min_x, get<1>(cell) - min_y, get<2>(cell) - min_z);\n    }\n    sort(normalized_poly.cells.begin(), normalized_poly.cells.end());\n    return normalized_poly;\n}\n\n// Generate all unique orientations (rotations) of a polycube.\n// Returns a vector of normalized Polycubes.\nvector<Polycube> get_orientations(const Polycube& poly) {\n    set<Polycube> unique_orientations;\n    vector<tuple<int,int,int>> current_cells = poly.cells;\n\n    // Apply rotations around X, Y, Z axes\n    for (int rotx = 0; rotx < 4; ++rotx) { // Rotations around X-axis\n        vector<tuple<int,int,int>> current_cells_y = current_cells;\n        for (int roty = 0; roty < 4; ++roty) { // Rotations around Y-axis\n            vector<tuple<int,int,int>> current_cells_z = current_cells_y;\n            for (int rotz = 0; rotz < 4; ++rotz) { // Rotations around Z-axis\n                Polycube oriented_poly;\n                oriented_poly.cells = current_cells_z;\n                unique_orientations.insert(normalize(oriented_poly));\n                \n                // Rotate around Z: (x, y, z) -> (-y, x, z)\n                vector<tuple<int,int,int>> next_z;\n                next_z.reserve(current_cells_z.size());\n                for(const auto& cell : current_cells_z) next_z.emplace_back(-get<1>(cell), get<0>(cell), get<2>(cell));\n                current_cells_z = next_z;\n            }\n            // Rotate around Y: (x, y, z) -> (z, y, -x)\n            vector<tuple<int,int,int>> next_y;\n            next_y.reserve(current_cells_y.size());\n            for(const auto& cell : current_cells_y) next_y.emplace_back(get<2>(cell), get<1>(cell), -get<0>(cell));\n            current_cells_y = next_y;\n        }\n        // Rotate around X: (x, y, z) -> (x, -z, y)\n        vector<tuple<int,int,int>> next_x;\n        next_x.reserve(current_cells.size());\n        for(const auto& cell : current_cells) next_x.emplace_back(get<0>(cell), -get<2>(cell), get<1>(cell));\n        current_cells = next_x;\n    }\n\n    vector<Polycube> orientations;\n    orientations.reserve(unique_orientations.size());\n    for (const auto& p : unique_orientations) orientations.push_back(p);\n    return orientations;\n}\n\n// Initialize the library of polycubes with all their orientations\nvoid initialize_library() {\n    // Define a set of 'base' polycubes to generate orientations from.\n    base_library_shapes.push_back({{{0,0,0}}}); // Monomino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}}}); // Domino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}}}); // L-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}}}); // I-tromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {0,1,0}, {1,1,0}}}); // Square tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {3,0,0}}}); // I-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {0,2,0}, {0,3,0}}}); // I-tetromino (vertical)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {1,1,0}}}); // T-tetromino\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {1,1,0}, {2,1,0}}}); // Skew tetromino (S)\n    base_library_shapes.push_back({{{0,0,0}, {0,1,0}, {1,1,0}, {1,2,0}}}); // Skew tetromino (Z)\n    base_library_shapes.push_back({{{0,0,0}, {1,0,0}, {2,0,0}, {2,1,0}}}); // L-tetromino\n    // Add more shapes if needed for better scores.\n\n    // Use a map to group orientations by their canonical form.\n    map<Polycube, vector<Polycube>> unique_canonical_shapes;\n\n    for(const auto& base_shape : base_library_shapes) {\n        vector<Polycube> orientations = get_orientations(base_shape); // These are already normalized\n        \n        // The first orientation in the list represents the canonical form.\n        Polycube canonical_form = orientations[0]; \n        \n        // If this canonical form is already in our map, skip.\n        if (unique_canonical_shapes.find(canonical_form) == unique_canonical_shapes.end()) {\n            unique_canonical_shapes[canonical_form] = orientations;\n        }\n    }\n    \n    // Populate precomputed_library_orientations from the map.\n    for(auto const& [canonical_shape, orientations_list] : unique_canonical_shapes) {\n        precomputed_library_orientations.push_back({(int)orientations_list[0].cells.size(), orientations_list});\n    }\n\n    // Sort library by volume descending to prioritize larger blocks.\n    sort(precomputed_library_orientations.rbegin(), precomputed_library_orientations.rend());\n}\n\n// Utility to check if a cell coordinate is within the DxD D grid bounds\nbool is_valid(int x, int y, int z) {\n    return x >= 0 && x < D && y >= 0 && y < D && z >= 0 && z < D;\n}\n    \n// Attempt to place a given normalized block_shape (from the library) such that it covers the target cell.\n// Returns true if a valid placement is found, false otherwise.\n// If true, 'placed_block_out_grid_coords' will contain the actual polycube in grid coordinates.\nbool try_place(const Polycube& normalized_library_shape, // A normalized orientation from the library\n               int target_x, int target_y, int target_z, // The cell we MUST cover\n               const vector<bool>& G, // Grid indicating valid cell locations for the object\n               const vector<bool>& covered, // Grid indicating already occupied cells\n               Polycube& placed_block_out_grid_coords) { // Output: the placed polycube in grid coordinates\n\n    // Iterate through each cell of the normalized_library_shape to try aligning it with the target cell.\n    for (const auto& cell_in_shape : normalized_library_shape.cells) {\n        int shape_cell_x, shape_cell_y, shape_cell_z;\n        tie(shape_cell_x, shape_cell_y, shape_cell_z) = cell_in_shape;\n\n        // Calculate the potential origin (top-left-front corner) of the block in grid coordinates.\n        int origin_x = target_x - shape_cell_x;\n        int origin_y = target_y - shape_cell_y;\n        int origin_z = target_z - shape_cell_z;\n\n        Polycube current_placement_grid_coords; // To store cells of the potential placement\n        bool possible = true;\n\n        // Check if all cells of the block, when placed at this origin, are valid.\n        for (const auto& cell_in_shape_ : normalized_library_shape.cells) {\n            int cx, cy, cz;\n            tie(cx, cy, cz) = cell_in_shape_;\n            \n            // Calculate actual grid coordinates for this cell of the block.\n            int px = origin_x + cx;\n            int py = origin_y + cy;\n            int pz = origin_z + cz;\n\n            // Check boundaries, if cell is allowed by G, and if it's not already covered.\n            if (!is_valid(px, py, pz) || !GRID_GET(G, px, py, pz, D) || GRID_GET(covered, px, py, pz, D)) {\n                possible = false;\n                break;\n            }\n            current_placement_grid_coords.cells.emplace_back(px, py, pz);\n        }\n\n        if (possible) {\n            // Found a valid placement that covers (target_x, target_y, target_z) and respects constraints.\n            placed_block_out_grid_coords = current_placement_grid_coords;\n            return true;\n        }\n    }\n    return false; // No valid placement found for this library block shape to cover the target cell.\n}\n\n// Greedy fill function\nvoid fill_object(const vector<bool>& G,\n                 vector<bool>& covered,\n                 vector<BlockAssignment>& assignments,\n                 bool is_object1) {\n\n    // Iterate through all cells of the grid.\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 this cell must be filled (according to G) and is not yet covered by any block:\n                if (GRID_GET(G, x, y, z, D) && !GRID_GET(covered, x, y, z, D)) {\n                    // This cell (x,y,z) must be part of a NEW, CONNECTED block instance.\n                    \n                    bool block_placed_in_this_step = false;\n                    Polycube best_placed_block_grid_coords; // Stores the best found block instance in grid coordinates.\n                    int best_block_score_id = -1;             // The score_id associated with this shape.\n                    int max_volume_found = -1;                // To prioritize larger blocks.\n\n                    // --- Attempt to fit the largest possible library block first ---\n                    for (const auto& lib_item : precomputed_library_orientations) {\n                        int current_vol = lib_item.first;\n                        const vector<Polycube>& orientations = lib_item.second; // list of normalized orientations\n\n                        // Optimization: If we already found a block and the current library block is not larger, skip.\n                        if (block_placed_in_this_step && current_vol <= max_volume_found) continue;\n\n                        // Try each orientation of the current library shape.\n                        for (const auto& oriented_shape_normalized : orientations) { \n                            Polycube current_placed_block_grid_coords; // To store the resulting polycube in grid coords\n                            \n                            // try_place will find an alignment that covers (x,y,z) and forms a valid, connected polycube.\n                            if (try_place(oriented_shape_normalized, x, y, z, G, covered, current_placed_block_grid_coords)) {\n                                // Success! 'current_placed_block_grid_coords' is a single, connected polycube.\n                                \n                                // Get its canonical form to determine its score_id.\n                                Polycube canonical_form = normalize(current_placed_block_grid_coords);\n                                \n                                int current_score_id;\n                                // Find or assign a score_id for this canonical shape.\n                                if (shape_to_score_id.count(canonical_form)) {\n                                    // This shape has been seen before, reuse its score_id.\n                                    current_score_id = shape_to_score_id[canonical_form];\n                                } else {\n                                    // New shape, assign a new score_id.\n                                    current_score_id = next_score_id_counter++;\n                                    shape_to_score_id[canonical_form] = current_score_id;\n                                }\n                                \n                                // We found a candidate block. If it's larger than the previous best for this cell, update.\n                                if (!block_placed_in_this_step || current_vol > max_volume_found) {\n                                    best_placed_block_grid_coords = current_placed_block_grid_coords; // Store the actual placed polycube\n                                    best_block_score_id = current_score_id;\n                                    max_volume_found = current_vol;\n                                    block_placed_in_this_step = true;\n                                }\n                            }\n                        }\n                    }\n                    \n                    // --- Assignment ---\n                    if (block_placed_in_this_step) {\n                        // Assign a NEW, UNIQUE output ID to this specific connected component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        // Add the assignment, linking the output ID, score ID, and the placed block.\n                        assignments.push_back({current_component_output_id, best_block_score_id, best_placed_block_grid_coords});\n                        \n                        // Mark all cells of this specific block instance as covered.\n                        for (const auto& cell : best_placed_block_grid_coords.cells) {\n                            GRID_GET(covered, get<0>(cell), get<1>(cell), get<2>(cell), D) = true;\n                        }\n                    } else {\n                        // Fallback: No library block could be placed starting from (x,y,z).\n                        // Place a 1x1x1 unit block at (x,y,z).\n                        Polycube unit_block_cell_grid_coords = {{{x, y, z}}}; // The single cell at its grid position\n                        Polycube canonical_unit = normalize(unit_block_cell_grid_coords); // Canonical is {{{0,0,0}}}\n\n                        int current_score_id;\n                        // Get or assign score_id for the unit block shape.\n                        if (shape_to_score_id.count(canonical_unit)) {\n                            current_score_id = shape_to_score_id[canonical_unit];\n                        } else {\n                            current_score_id = next_score_id_counter++;\n                            shape_to_score_id[canonical_unit] = current_score_id;\n                        }\n                        \n                        // Assign a NEW, UNIQUE output ID to this unit block component.\n                        int current_component_output_id = next_component_output_id_counter++;\n                        assignments.push_back({current_component_output_id, current_score_id, unit_block_cell_grid_coords});\n                        GRID_GET(covered, x, y, z, D) = true; // Mark this cell as covered.\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input D (dimension of the grid)\n    cin >> D;\n    \n    // Resize input strings for silhouettes\n    f1_str.resize(D); r1_str.resize(D);\n    f2_str.resize(D); r2_str.resize(D);\n\n    // Read the four silhouette images\n    for (int i = 0; i < D; ++i) cin >> f1_str[i];\n    for (int i = 0; i < D; ++i) cin >> r1_str[i];\n    for (int i = 0; i < D; ++i) cin >> f2_str[i];\n    for (int i = 0; i < D; ++i) cin >> r2_str[i];\n\n    // Initialize the grids that define where cells can be occupied\n    setup_grids();\n    // Initialize the library of shapes and their orientations\n    initialize_library();\n\n    // Initialize counters.\n    // next_component_output_id_counter ensures each placed component gets a unique ID for the output grid.\n    next_component_output_id_counter = 1; \n    // next_score_id_counter ensures each distinct shape gets a unique score_id for scoring.\n    next_score_id_counter = 1;          \n    shape_to_score_id.clear();          // Clear for object 1.\n    assignments1.clear();               \n    vector<bool> covered1(D * D * D, false);\n    fill_object(G1_grid, covered1, assignments1, true); // Fill object 1\n\n    // Process object 2.\n    // IMPORTANT: Counters are NOT reset for shapes. This allows sharing score_ids for identical shapes.\n    // HOWEVER, next_component_output_id_counter must NOT be reset if we want output IDs to be global and unique across both objects.\n    // Based on problem statement and example, total 'n' blocks means total unique components.\n    assignments2.clear();               \n    vector<bool> covered2(D * D * D, false);\n    fill_object(G2_grid, covered2, assignments2, false); // Fill object 2\n\n    // --- Output ---\n    // The total number of blocks 'n' is the maximum output ID used.\n    cout << next_component_output_id_counter - 1 << endl;\n\n    // Output for object 1: Use the unique output_id for each component.\n    vector<int> b1_output(D * D * D, 0);\n    for (const auto& assign : assignments1) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b1_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b1_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    // Output for object 2: Use the unique output_id for each component.\n    vector<int> b2_output(D * D * D, 0);\n    for (const auto& assign : assignments2) {\n        for (const auto& cell : assign.shape_grid_coords.cells) {\n            GRID_WRITE(b2_output, get<0>(cell), get<1>(cell), get<2>(cell), D) = assign.output_id;\n        }\n    }\n    for (int i = 0; i < D * D * D; ++i) {\n        cout << b2_output[i] << (i == D * D * D - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <map>\n\n// Use long double for precision in distance calculations\nusing ftype = long double;\n\nstruct Point {\n    long long x, y;\n};\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nstruct Resident {\n    int id;\n    Point pos;\n};\n\nint N_stations_global, M_edges_global, K_residents_global;\nstd::vector<Point> station_pos_global;\nstd::vector<Edge> edges_global; // Store edges with original IDs and weights\nstd::vector<Resident> residents_global;\n\n// Precomputed distances: dists_global[i][k] is distance from station i to resident k\nstd::vector<std::vector<ftype>> dists_global;\n\n// Function to calculate Euclidean distance\nftype dist(Point p1, Point p2) {\n    ftype dx = static_cast<ftype>(p1.x) - p2.x;\n    ftype dy = static_cast<ftype>(p1.y) - p2.y;\n    return std::sqrt(dx * dx + dy * dy);\n}\n\n// Calculate total cost\nlong long calculate_total_cost(const std::vector<int>& P, const std::vector<int>& B) {\n    long long edge_cost = 0;\n    for (int j = 0; j < M_edges_global; ++j) {\n        if (B[j]) {\n            edge_cost += edges_global[j].w;\n        }\n    }\n    long long station_cost = 0;\n    for (int i = 0; i < N_stations_global; ++i) {\n        station_cost += static_cast<long long>(P[i]) * P[i];\n    }\n    return station_cost + edge_cost;\n}\n\n// Helper to compute reachable vertices from station 0\nstd::vector<int> get_reachable_stations(int N, const std::vector<int>& B_current, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> reachable_indices;\n    std::vector<std::vector<int>> adj(N);\n    \n    // Rebuild adjacency list from active edges (B_current)\n    for(const auto& edge : all_edges_indexed) {\n        if (B_current[edge.id]) { // Use edge.id to check B_current\n            adj[edge.u].push_back(edge.v);\n            adj[edge.v].push_back(edge.u);\n        }\n    }\n\n    std::queue<int> q;\n    if (N > 0) { // Station 0 is always source\n        q.push(0);\n        reachable_indices.push_back(0);\n    }\n    \n    std::vector<bool> visited(N, false);\n    if (N > 0) visited[0] = true;\n    \n    while(!q.empty()) {\n        int u = q.front();\n        q.pop();\n        for(int v : adj[u]) {\n            if (!visited[v]) {\n                visited[v] = true;\n                q.push(v);\n                reachable_indices.push_back(v);\n            }\n        }\n    }\n    return reachable_indices;\n}\n\n\n// --- Optimized P Assignment using Priority Queue ---\n\n// Struct to hold state for PQ in solve_P_greedy_marginal_cost\nstruct StationUpgradeState {\n    long long marginal_cost; // Cost to cover the *next* uncovered resident for this station\n    int station_idx;\n\n    bool operator>(const StationUpgradeState& other) const {\n        // Primary sort by cost, secondary by station index for deterministic behavior\n        if (marginal_cost != other.marginal_cost) {\n            return marginal_cost > other.marginal_cost; // Min-heap\n        }\n        return station_idx > other.station_idx;\n    }\n};\n\n// Global structures for the PQ-based solver\nstd::vector<std::vector<std::pair<ftype, int>>> residents_by_dist_global; // For each station, residents sorted by distance {distance, resident_id}\nstd::vector<int> next_uncovered_resident_idx_global; // For each station, index into residents_by_dist_global\nstd::vector<bool> global_resident_covered_global;\nint current_uncovered_count_global;\n\n// Function to update coverage status and push next upgrade to PQ\nvoid update_coverage_and_pq(int station_idx, std::vector<int>& P, \n                            std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>>& pq) {\n    \n    if (station_idx >= N_stations_global || residents_by_dist_global[station_idx].empty()) return;\n\n    // Find the first resident for this station that is not yet covered and reachable by current P[station_idx]\n    int current_k_idx_in_list = next_uncovered_resident_idx_global[station_idx];\n    \n    while(current_k_idx_in_list < residents_by_dist_global[station_idx].size()) {\n        auto& resident_entry = residents_by_dist_global[station_idx][current_k_idx_in_list];\n        int k_id = resident_entry.second;\n        ftype dist_to_k = resident_entry.first;\n\n        // If resident is too far even with max P, skip it.\n        if (dist_to_k > 5000.0 + 1e-9) { \n            current_k_idx_in_list++;\n            continue;\n        }\n        // If resident is already covered OR cannot be covered by current P[station_idx]\n        if (global_resident_covered_global[k_id] || dist_to_k > P[station_idx] + 1e-9) {\n            current_k_idx_in_list++;\n            continue;\n        }\n        // Found an uncovered resident that is reachable by current P[station_idx]. Break to process it.\n        break;\n    }\n    next_uncovered_resident_idx_global[station_idx] = current_k_idx_in_list;\n\n    // If we've advanced past all residents for this station that can be covered by current P, return.\n    if (next_uncovered_resident_idx_global[station_idx] >= residents_by_dist_global[station_idx].size()) {\n        return;\n    }\n\n    // Now, process the found resident `k_id` which requires an increase in P.\n    auto& resident_entry = residents_by_dist_global[station_idx][next_uncovered_resident_idx_global[station_idx]];\n    int k_id = resident_entry.second;\n    ftype dist_to_k = resident_entry.first;\n\n    // Calculate the required P to cover this specific resident.\n    int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n    // The new P value must be at least the current P and at least the required P.\n    int new_p_val = std::max(P[station_idx], required_p_int);\n    \n    // Calculate the actual marginal cost for this specific upgrade step.\n    long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[station_idx]) * P[station_idx];\n    \n    // Push this potential upgrade to the PQ.\n    pq.push({actual_marginal_cost, station_idx});\n}\n\n\nstd::vector<int> solve_P_greedy_marginal_cost_pq(const std::vector<int>& V_prime_indices, const std::vector<Edge>& all_edges_indexed) {\n    std::vector<int> P(N_stations_global, 0);\n    \n    if (K_residents_global == 0) return P; // No residents, no cost.\n\n    // If V_prime is empty and K > 0, coverage is impossible. Return zeros.\n    if (V_prime_indices.empty()) {\n        return P; \n    }\n\n    // Initialize global structures for PQ solver\n    residents_by_dist_global.assign(N_stations_global, std::vector<std::pair<ftype, int>>());\n    next_uncovered_resident_idx_global.assign(N_stations_global, 0);\n    global_resident_covered_global.assign(K_residents_global, false);\n    current_uncovered_count_global = K_residents_global;\n    \n    // Populate residents_by_dist_global and sort for stations in V_prime\n    for (int station_idx : V_prime_indices) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            // Only consider residents potentially coverable within max P (5000)\n            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { \n                residents_by_dist_global[station_idx].push_back({dists_global[station_idx][k], k});\n            }\n        }\n        // Sort residents by distance for this station\n        std::sort(residents_by_dist_global[station_idx].begin(), residents_by_dist_global[station_idx].end());\n        // Initialize next_uncovered_resident_idx_global for this station\n        next_uncovered_resident_idx_global[station_idx] = 0; \n    }\n\n    // Priority queue for upgrades\n    std::priority_queue<StationUpgradeState, std::vector<StationUpgradeState>, std::greater<StationUpgradeState>> pq;\n\n    // Initial population of PQ: For each station, find the first resident it needs to cover\n    for (int station_idx : V_prime_indices) {\n        update_coverage_and_pq(station_idx, P, pq); \n    }\n\n    // Greedy loop: While there are uncovered residents and potential upgrades\n    while (current_uncovered_count_global > 0 && !pq.empty()) {\n        StationUpgradeState current_upgrade = pq.top();\n        pq.pop();\n\n        int s = current_upgrade.station_idx;\n        \n        // Re-evaluate: The PQ entry might be stale.\n        // Update the station's state to find the *actual* next resident to cover and push to PQ if needed.\n        update_coverage_and_pq(s, P, pq); \n\n        // Now, check if the *popped* element `current_upgrade` is still relevant.\n        // It is relevant if `next_uncovered_resident_idx_global[s]` points to an uncovered resident that needs an upgrade.\n        if (next_uncovered_resident_idx_global[s] < residents_by_dist_global[s].size()) {\n            auto& resident_entry = residents_by_dist_global[s][next_uncovered_resident_idx_global[s]];\n            int k_id = resident_entry.second;\n            ftype dist_to_k = resident_entry.first;\n            \n            // If the resident is covered OR already reachable by current P[s], this popped element is stale for this specific resident.\n            if (global_resident_covered_global[k_id] || dist_to_k > P[s] + 1e-9) {\n                // This means the station `s` either doesn't need to upgrade for this resident, or this resident is already covered.\n                // `update_coverage_and_pq` would have handled re-pushing if a new upgrade is needed.\n                continue; // Skip processing this stale entry.\n            }\n\n            // If we reach here, the popped entry is relevant for covering the resident at `next_uncovered_resident_idx_global[s]`.\n            // Recalculate the required P and marginal cost based on the current P[s] (which might have increased if this station was updated before).\n            int required_p_int = static_cast<int>(std::ceil(dist_to_k));\n            int new_p_val = std::max(P[s], required_p_int);\n            long long actual_marginal_cost = static_cast<long long>(new_p_val) * new_p_val - static_cast<long long>(P[s]) * P[s];\n\n            // Apply the upgrade\n            P[s] = new_p_val;\n\n            // Update coverage for all residents potentially covered by the new P[s] starting from this resident.\n            int initial_next_idx = next_uncovered_resident_idx_global[s]; // Start from current target\n            for (int i = initial_next_idx; i < residents_by_dist_global[s].size(); ++i) {\n                auto& current_resident_entry = residents_by_dist_global[s][i];\n                int resident_k_id = current_resident_entry.second;\n                ftype dist_to_resident_k = current_resident_entry.first;\n\n                if (dist_to_resident_k > P[s] + 1e-9) { // Stop if distance exceeds new P[s]\n                    break; \n                }\n\n                if (!global_resident_covered_global[resident_k_id]) {\n                    global_resident_covered_global[resident_k_id] = true;\n                    current_uncovered_count_global--;\n                }\n                // Update the index to the next potential resident for this station\n                next_uncovered_resident_idx_global[s] = i + 1;\n            }\n            \n            // After covering residents, re-populate PQ for station `s` in case it needs further upgrades.\n            update_coverage_and_pq(s, P, pq);\n        }\n    }\n\n    // Fallback for any remaining uncovered residents if PQ becomes empty but count > 0.\n    // This typically means coverage is impossible or requires very high P.\n    // Set P to 5000 for the closest station in V_prime that can cover it.\n    if (current_uncovered_count_global > 0) {\n        for(int k=0; k<K_residents_global; ++k) {\n            if (!global_resident_covered_global[k]) {\n                ftype min_d = 5001.0;\n                int best_station_idx = -1;\n                for (int station_idx : V_prime_indices) { // Use original V_prime_indices for this fallback\n                    ftype d = dists_global[station_idx][k];\n                    if (d <= 5000.0 + 1e-9) { // Can cover within max radius\n                        if (d < min_d) {\n                            min_d = d;\n                            best_station_idx = station_idx;\n                        }\n                    }\n                }\n                if (best_station_idx != -1) {\n                    // Force coverage by setting P to 5000.\n                    if (P[best_station_idx] < 5000) {\n                        P[best_station_idx] = 5000;\n                    }\n                }\n            }\n        }\n    }\n\n    return P;\n}\n\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> N_stations_global >> M_edges_global >> K_residents_global;\n\n    station_pos_global.resize(N_stations_global);\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cin >> station_pos_global[i].x >> station_pos_global[i].y;\n    }\n\n    edges_global.resize(M_edges_global);\n    for (int i = 0; i < M_edges_global; ++i) {\n        edges_global[i].id = i;\n        std::cin >> edges_global[i].u >> edges_global[i].v >> edges_global[i].w;\n        edges_global[i].u--; // 0-indexed\n        edges_global[i].v--; // 0-indexed\n    }\n\n    residents_global.resize(K_residents_global);\n    for (int i = 0; i < K_residents_global; ++i) {\n        residents_global[i].id = i;\n        std::cin >> residents_global[i].pos.x >> residents_global[i].pos.y;\n    }\n\n    // 1. Precompute all distances\n    dists_global.resize(N_stations_global, std::vector<ftype>(K_residents_global));\n    for (int i = 0; i < N_stations_global; ++i) {\n        for (int k = 0; k < K_residents_global; ++k) {\n            dists_global[i][k] = dist(station_pos_global[i], residents_global[k].pos);\n        }\n    }\n\n    // Sort edges by weight for MST and pruning\n    std::vector<Edge> sorted_edges = edges_global;\n    std::sort(sorted_edges.begin(), sorted_edges.end(), [](const Edge& a, const Edge& b) {\n        return a.w < b.w;\n    });\n\n    // 2. Initial Connectivity using MST\n    std::vector<int> parent(N_stations_global);\n    std::iota(parent.begin(), parent.end(), 0);\n    auto find_set = [&](auto self, int v) -> int {\n        if (v == parent[v]) return v;\n        return parent[v] = self(self, parent[v]);\n    };\n    auto unite_sets = [&](int a, int b) -> bool {\n        a = find_set(find_set, a);\n        b = find_set(find_set, b);\n        if (a != b) {\n            parent[b] = a;\n            return true;\n        }\n        return false;\n    };\n\n    std::vector<int> B(M_edges_global, 0); // B[j] = 1 if edge j is ON, 0 otherwise\n    int edges_count = 0;\n    if (N_stations_global > 1) { // MST only needed if more than 1 station\n        for (const auto& edge : sorted_edges) {\n            if (unite_sets(edge.u, edge.v)) {\n                B[edge.id] = 1;\n                edges_count++;\n                if (edges_count == N_stations_global - 1) break;\n            }\n        }\n    } \n\n    // 3. Edge Pruning (Iterative Improvement)\n    // This pruning strategy checks if coverage is *feasible* after edge removal.\n    // It does not enforce full connectivity between all N stations.\n    for (const auto& edge_to_consider : sorted_edges) {\n        int edge_id = edge_to_consider.id;\n        if (B[edge_id] == 0) continue; // Edge is already OFF\n\n        // Temporarily remove the edge\n        B[edge_id] = 0;\n\n        // Determine the set of stations reachable from station 0 with the current B\n        std::vector<int> temp_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Check if coverage is feasible with the new V_prime.\n        bool coverage_feasible_after_prune = true;\n        if (K_residents_global > 0) {\n            if (temp_V_prime_indices.empty()) {\n                coverage_feasible_after_prune = false; // Cannot cover if no stations are reachable\n            } else {\n                for (int k = 0; k < K_residents_global; ++k) {\n                    bool resident_k_can_be_covered = false;\n                    for (int station_idx : temp_V_prime_indices) {\n                        if (dists_global[station_idx][k] <= 5000.0 + 1e-9) { // Max possible coverage radius\n                            resident_k_can_be_covered = true;\n                            break;\n                        }\n                    }\n                    if (!resident_k_can_be_covered) {\n                        coverage_feasible_after_prune = false;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // If coverage is not feasible, restore the edge.\n        if (!coverage_feasible_after_prune) {\n            B[edge_id] = 1; // Restore the edge\n        }\n        // If coverage is feasible, we tentatively keep the edge removed.\n    }\n\n    // 4. Determine the final V_prime set after pruning and assign P values\n    std::vector<int> final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n\n    // Ensure V_prime is not empty if K > 0 by adding the cheapest edge if necessary.\n    if (K_residents_global > 0 && final_V_prime_indices.empty() && N_stations_global > 0) {\n        for (const auto& edge_to_add : sorted_edges) {\n            if (B[edge_to_add.id] == 0) { // If edge is OFF\n                B[edge_to_add.id] = 1; // Turn it ON\n                final_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n                break; // Added one edge, sufficient for now.\n            }\n        }\n    }\n    \n    // Assign P values using the optimized PQ solver\n    std::vector<int> P = solve_P_greedy_marginal_cost_pq(final_V_prime_indices, edges_global);\n\n    // 5. Local Search / Iterative Refinement\n    // Increased iterations slightly to allow more exploration.\n    const int LOCAL_SEARCH_ITER = 1000; // Increased from 750\n    std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());\n\n    for(int iter = 0; iter < LOCAL_SEARCH_ITER; ++iter) {\n        bool improved = false;\n\n        // --- Edge Removal ---\n        // Create a shuffled list of edges to try removing. This allows exploring different paths in the search space.\n        std::vector<Edge> edges_to_try_removing = sorted_edges; \n        std::shuffle(edges_to_try_removing.begin(), edges_to_try_removing.end(), rng);\n\n        for (const auto& edge_to_consider : edges_to_try_removing) {\n            int edge_id = edge_to_consider.id;\n            if (B[edge_id] == 0) continue; // Already OFF\n\n            // Temporarily remove edge\n            B[edge_id] = 0;\n\n            // Determine new V_prime\n            std::vector<int> next_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n            \n            // Check if coverage is still feasible with the new V_prime.\n            bool coverage_feasible = true;\n            if (K_residents_global > 0) {\n                if (next_V_prime_indices.empty()) {\n                    coverage_feasible = false;\n                } else {\n                    for (int k = 0; k < K_residents_global; ++k) {\n                        bool resident_k_can_be_covered = false;\n                        for (int station_idx : next_V_prime_indices) {\n                            if (dists_global[station_idx][k] <= 5000.0 + 1e-9) {\n                                resident_k_can_be_covered = true;\n                                break;\n                            }\n                        }\n                        if (!resident_k_can_be_covered) {\n                            coverage_feasible = false;\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if (!coverage_feasible) {\n                B[edge_id] = 1; // Revert edge removal\n                continue;\n            }\n\n            // Re-solve P values for the new V_prime\n            std::vector<int> next_P = solve_P_greedy_marginal_cost_pq(next_V_prime_indices, edges_global);\n            \n            // Verify actual coverage with next_P and next_V_prime_indices\n            bool actual_coverage_ok = true;\n            if (K_residents_global > 0) {\n                int covered_count = 0;\n                for(int k=0; k<K_residents_global; ++k) {\n                    bool k_covered = false;\n                    for(int st_idx_check : next_V_prime_indices) {\n                        if (next_P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= next_P[st_idx_check]) {\n                            k_covered = true;\n                            break;\n                        }\n                    }\n                    if(k_covered) covered_count++;\n                }\n                if (covered_count < K_residents_global) actual_coverage_ok = false;\n            }\n\n            if (actual_coverage_ok) {\n                // Calculate costs: Compare cost *before* removal vs *after* removal.\n                // Cost BEFORE removal: Current P, B with edge_id restored to 1.\n                std::vector<int> B_before_removal = B; // B has edge_id=0\n                B_before_removal[edge_id] = 1; // Temporarily restore edge for cost calc\n                long long cost_before_removal = calculate_total_cost(P, B_before_removal);\n                \n                // Cost AFTER removal: next_P, B with edge_id=0\n                long long cost_after_removal = calculate_total_cost(next_P, B); \n                \n                if (cost_after_removal < cost_before_removal) {\n                    P = next_P; // Update P values\n                    // B is already updated (edge_id is 0)\n                    improved = true;\n                } else {\n                    // Revert the change\n                    B[edge_id] = 1;\n                }\n            } else {\n                // Revert the change if actual coverage is lost\n                B[edge_id] = 1;\n            }\n        }\n        \n        // --- P Value Adjustment ---\n        // Re-calculate current V_prime based on current B state\n        std::vector<int> current_V_prime_indices = get_reachable_stations(N_stations_global, B, edges_global);\n        \n        // Only attempt P adjustment if V_prime is not empty OR if there are no residents to cover.\n        if (!current_V_prime_indices.empty() || K_residents_global == 0) {\n            \n            // Try decreasing P of a random station in V_prime that has P > 0\n            int station_to_adjust = -1;\n            if (!current_V_prime_indices.empty()) {\n                std::vector<int> stations_with_p_greater_than_zero;\n                for (int s_idx : current_V_prime_indices) {\n                    if (P[s_idx] > 0) {\n                        stations_with_p_greater_than_zero.push_back(s_idx);\n                    }\n                }\n\n                if (!stations_with_p_greater_than_zero.empty()) {\n                    // Pick one randomly from those with P > 0\n                    station_to_adjust = stations_with_p_greater_than_zero[std::uniform_int_distribution<int>(0, stations_with_p_greater_than_zero.size() - 1)(rng)];\n                }\n            }\n\n            if (station_to_adjust != -1) {\n                int original_P = P[station_to_adjust];\n                P[station_to_adjust]--; // Try decreasing P by 1\n                \n                // Check coverage with the decreased P\n                bool coverage_ok = true;\n                if (K_residents_global > 0) {\n                    int covered_count = 0;\n                    for(int k=0; k<K_residents_global; ++k) {\n                        bool k_covered = false;\n                        for(int st_idx_check : current_V_prime_indices) { // Use the current V_prime\n                            if (P[st_idx_check] > 0 && dists_global[st_idx_check][k] <= P[st_idx_check]) {\n                                k_covered = true;\n                                break;\n                            }\n                        }\n                        if(k_covered) covered_count++;\n                    }\n                    if (covered_count < K_residents_global) coverage_ok = false;\n                }\n                \n                if (coverage_ok) {\n                    // Cost decreased (since P decreased)\n                    improved = true;\n                } else {\n                    // Revert if coverage lost\n                    P[station_to_adjust] = original_P;\n                }\n            }\n        }\n\n        if (!improved) {\n             // If no improvement in an entire iteration, break.\n             break; \n        }\n    }\n\n    // Output final P values and B values\n    for (int i = 0; i < N_stations_global; ++i) {\n        std::cout << P[i] << (i == N_stations_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n    for (int j = 0; j < M_edges_global; ++j) {\n        std::cout << B[j] << (j == M_edges_global - 1 ? \"\" : \" \");\n    }\n    std::cout << \"\\n\";\n\n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <numeric>\n#include <map>\n#include <tuple> // For tie-breaking if needed, though struct comparison is sufficient\n\n// Maximum number of tiers\nconst int N = 30;\n// Total number of balls\nconst int M = N * (N + 1) / 2; // M = 465\n\n// Structure to represent coordinates (tier x, position y)\nstruct Coord {\n    int x, y;\n\n    // Operator overloading for map keys and comparisons.\n    // Required for std::map and for determining lexicographical order.\n    bool operator<(const Coord& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Coord& other) const {\n        return x == other.x && y == other.y;\n    }\n    // Useful for tie-breaking in lexicographical order.\n    bool operator>(const Coord& other) const {\n        if (x != other.x) return x > other.x;\n        return y > other.y;\n    }\n};\n\n// Convert pyramid coordinates (x, y) to a linear index.\n// This index serves as the \"target position\" for a ball with a value equal to this index.\n// For example, ball with value 0 should be at (0,0), value 1 at (1,0), value 2 at (1,1), etc.\ninline int get_idx_from_coord(int x, int y) {\n    return x * (x + 1) / 2 + y;\n}\n\n// Define relative coordinates for the 6 possible adjacent moves.\n// These correspond to the adjacency rules given in the problem statement.\n// Order:\n// (dx[0], dy[0]) = (1, 0) : (x+1, y)   (Down-Left)\n// (dx[1], dy[1]) = (1, 1) : (x+1, y+1) (Down-Right)\n// (dx[2], dy[2]) = (0, 1) : (x, y+1)   (Right)\n// (dx[3], dy[3]) = (0,-1) : (x, y-1)   (Left)\n// (dx[4], dy[4]) = (-1,0) : (x-1, y)   (Up-Left)\n// (dx[5], dy[5]) = (-1,1) : (x-1, y+1) (Up-Right)\nint dx[] = {1, 1, 0, 0, -1, -1}; // change in x\nint dy[] = {0, 1, 1, -1, 0, 1}; // change in y\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Map to store the current value of the ball at a given coordinate.\n    // Key: Coord, Value: ball_value\n    std::map<Coord, int> current_values_map;\n    \n    // Vector to store all valid coordinates in the pyramid.\n    // Populated in order: (0,0), (1,0), (1,1), (2,0), (2,1), (2,2), ...\n    // This order ensures deterministic iteration through all cells and facilitates tie-breaking.\n    std::vector<Coord> all_coords;\n    all_coords.reserve(M);\n\n    // Read input and populate the initial state of the pyramid.\n    for (int x = 0; x < N; ++x) {\n        for (int y = 0; y <= x; ++y) {\n            Coord c = {x, y};\n            all_coords.push_back(c);\n            int value;\n            std::cin >> value;\n            current_values_map[c] = value;\n        }\n    }\n\n    // Store the sequence of performed swaps.\n    // Each swap is a pair of adjacent coordinates.\n    std::vector<std::pair<Coord, Coord>> swaps;\n    const int MAX_SWAPS = 10000; // Maximum allowed operations.\n\n    // Heuristic strategy:\n    // This problem is NP-hard, so we employ a greedy heuristic.\n    // The target configuration is one where each ball with value `v` is located at\n    // coordinate `c` such that `get_idx_from_coord(c.x, c.y) == v`.\n    // This configuration guarantees the condition V(x,y) < V(x+1,y) and V(x,y) < V(x+1,y+1).\n    //\n    // In each step (up to MAX_SWAPS operations), we find the single best adjacent swap.\n    // The \"best\" swap is defined as one that maximizes the reduction in the total absolute error.\n    // The total absolute error is the sum of |target_index - current_value| for all balls.\n    // A swap is only considered if it moves a ball with a larger value to a position\n    // that should ideally hold a larger index (i.e., resolves an inversion where idx1 < idx2 but val1 > val2).\n    // If multiple swaps yield the same maximum benefit, we choose the one that is\n    // lexicographically smallest in terms of the coordinate pair (c1, c2), where c1 is\n    // the \"left/up\" ball and c2 is the \"right/down\" ball (idx(c1) < idx(c2)).\n\n    for (int k = 0; k < MAX_SWAPS; ++k) {\n        // Variables to track the best swap found in this iteration.\n        // Initialize max_benefit to a very small number. We are interested in non-negative benefits.\n        long long max_benefit = -2e18; \n        Coord best_c1 = {-1, -1}, best_c2 = {-1, -1}; // Initialize to invalid coordinates.\n\n        // Iterate through all balls (c1) and their potential neighbors (c2).\n        // `all_coords` is iterated in lexicographical order.\n        for (const auto& c1 : all_coords) { \n            int val1 = current_values_map.at(c1);\n            int idx1 = get_idx_from_coord(c1.x, c1.y);\n\n            // Check each of the 6 possible adjacent neighbors of c1.\n            for (int i = 0; i < 6; ++i) {\n                Coord c2 = {c1.x + dx[i], c1.y + dy[i]};\n\n                // Validate if the neighbor coordinate c2 is within the pyramid boundaries.\n                if (c2.x < 0 || c2.x >= N || c2.y < 0 || c2.y > c2.x) {\n                    continue; // c2 is outside the pyramid.\n                }\n\n                int val2 = current_values_map.at(c2);\n                int idx2 = get_idx_from_coord(c2.x, c2.y);\n\n                // We are only interested in swaps that fix an \"inversion\" according to the target index.\n                // An inversion exists if c1 should have a smaller index than c2 (idx1 < idx2),\n                // but c1 currently holds a larger value than c2 (val1 > val2).\n                // Swapping these would move a smaller value towards a smaller index, and a larger value\n                // towards a larger index, thus reducing the total absolute error.\n                if (idx1 < idx2 && val1 > val2) {\n                    // Calculate the benefit of swapping c1 and c2.\n                    // Benefit is defined as the reduction in the sum of absolute errors:\n                    // Total Error = Sum over all balls v of | target_idx(pos[v]) - v |\n                    // current_error_sum = |idx1 - val1| + |idx2 - val2|\n                    // new_error_sum     = |idx1 - val2| + |idx2 - val1|  (after swapping val1 and val2)\n                    // benefit           = current_error_sum - new_error_sum\n                    long long current_error_sum = std::abs((long long)idx1 - val1) + std::abs((long long)idx2 - val2);\n                    long long new_error_sum = std::abs((long long)idx1 - val2) + std::abs((long long)idx2 - val1);\n                    long long benefit = current_error_sum - new_error_sum;\n\n                    // Update `best_c1`, `best_c2`, and `max_benefit` if this swap is better.\n                    // Selection criteria:\n                    // 1. Maximize the benefit. We require `benefit >= 0`. A benefit of 0 means\n                    //    the total error sum doesn't decrease, but the swap might still resolve\n                    //    an inversion and potentially reduce direct violations (E), or help reach MAX_SWAPS.\n                    // 2. If benefits are equal, choose the lexicographically smaller coordinate pair (c1, c2).\n                    //    The iteration order ensures that the first encountered pair for a given\n                    //    benefit is the lexicographically smallest. Thus, we update only if the current\n                    //    pair (c1, c2) is strictly smaller than the current `(best_c1, best_c2)`.\n                    \n                    if (benefit > max_benefit) {\n                        max_benefit = benefit;\n                        best_c1 = c1;\n                        best_c2 = c2;\n                    } else if (benefit == max_benefit) {\n                        // Tie-breaking: select the lexicographically smaller coordinate pair (c1, c2).\n                        if (c1 < best_c1 || (c1 == best_c1 && c2 < best_c2)) {\n                             best_c1 = c1;\n                             best_c2 = c2;\n                        }\n                    }\n                }\n            }\n        }\n\n        // If a beneficial swap was found (best_c1 is valid and max_benefit >= 0),\n        // and we haven't reached the maximum allowed number of swaps:\n        if (best_c1.x != -1 && max_benefit >= 0) {\n            // Apply the selected best swap.\n            std::swap(current_values_map.at(best_c1), current_values_map.at(best_c2));\n            // Record the swap operation.\n            swaps.push_back({best_c1, best_c2});\n        } else {\n            // No swap found with non-negative benefit, or we have already performed MAX_SWAPS (implicit in k loop condition).\n            // In this case, we cannot improve further with this greedy strategy, so we stop.\n            break;\n        }\n    }\n\n    // Output the total number of operations performed.\n    std::cout << swaps.size() << std::endl;\n    // Output each swap operation in the specified format.\n    for (const auto& sw : swaps) {\n        std::cout << sw.first.x << \" \" << sw.first.y << \" \" << sw.second.x << \" \" << sw.second.y << std::endl;\n    }\n\n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Grid dimensions and properties\nconst int MAX_D = 9; // D is fixed at 9 for all test cases\nint D;\nbool is_obstacle[MAX_D][MAX_D];\nint dist[MAX_D][MAX_D];\npair<int, int> entrance;\n\n// Directions for BFS: North, East, South, West\n// These correspond to changes in (row, column) coordinates.\nint dr[] = {-1, 0, 1, 0};\nint dc[] = {0, 1, 0, -1};\n\n// Structure to hold cell information: row, column, and its shortest distance from the entrance.\n// This is used for sorting storage locations.\nstruct CellInfo {\n    int r, c, d;\n\n    // Custom comparison operator for sorting:\n    // 1. Primarily by distance (ascending).\n    // 2. Secondarily by row index (ascending).\n    // 3. Tertiarily by column index (ascending).\n    bool operator<(const CellInfo& other) const {\n        if (d != other.d) {\n            return d < other.d;\n        }\n        if (r != other.r) {\n            return r < other.r;\n        }\n        return c < other.c;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming performance.\n    // `ios_base::sync_with_stdio(false)` unties C++ streams from C stdio.\n    // `cin.tie(NULL)` unties cin from cout, meaning cin operations do not force cout to flush.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N; // Number of obstacles\n    cin >> D >> N;\n\n    // Set entrance coordinates (0-indexed). D is always 9, so (D-1)/2 is 4.\n    entrance = {0, (D - 1) / 2};\n\n    // Initialize grid properties: mark all cells as not an obstacle and unreachable initially.\n    for (int i = 0; i < D; ++i) {\n        for (int j = 0; j < D; ++j) {\n            is_obstacle[i][j] = false;\n            dist[i][j] = -1; // -1 indicates unreachable or unvisited\n        }\n    }\n\n    // Read and mark obstacle locations.\n    for (int i = 0; i < N; ++i) {\n        int r, c;\n        cin >> r >> c;\n        is_obstacle[r][c] = true;\n    }\n\n    // --- BFS to calculate shortest distances ---\n    // We perform a Breadth-First Search starting from the entrance to find the shortest\n    // path distance to all reachable non-obstacle cells.\n    queue<pair<int, int>> q;\n\n    // The entrance is guaranteed not to be an obstacle.\n    dist[entrance.first][entrance.second] = 0;\n    q.push(entrance);\n\n    // This vector will store information about all reachable cells (including the entrance)\n    // along with their distances.\n    vector<CellInfo> all_reachable_cells;\n\n    while (!q.empty()) {\n        pair<int, int> curr = q.front();\n        q.pop();\n        int r = curr.first;\n        int c = curr.second;\n\n        // Add the current cell to our list of reachable cells.\n        all_reachable_cells.push_back({r, c, dist[r][c]});\n\n        // Explore neighbors in all four directions.\n        for (int i = 0; i < 4; ++i) {\n            int nr = r + dr[i];\n            int nc = c + dc[i];\n\n            // Check if the neighbor is within grid bounds, is not an obstacle, and has not been visited yet.\n            if (nr >= 0 && nr < D && nc >= 0 && nc < D && !is_obstacle[nr][nc] && dist[nr][nc] == -1) {\n                dist[nr][nc] = dist[r][c] + 1; // Distance is one more than the current cell's distance.\n                q.push({nr, nc}); // Add the neighbor to the queue for exploration.\n            }\n        }\n    }\n\n    // --- Sorting Storage Locations ---\n    // The problem states that containers are stored in squares other than the entrance and obstacles.\n    // The total number of containers is M = D*D - 1 - N. These will occupy M storage locations.\n    // We need to sort these storage locations based on their proximity to the entrance to establish an order.\n    vector<CellInfo> sorted_storage_locs;\n    for (const auto& cell : all_reachable_cells) {\n        // The entrance cell itself is not a storage location, so we skip it.\n        if (cell.r == entrance.first && cell.c == entrance.second) {\n            continue;\n        }\n        sorted_storage_locs.push_back(cell);\n    }\n\n    // Sort the storage locations using the custom comparison operator defined in CellInfo.\n    // This ensures they are ordered by distance, then row, then column.\n    sort(sorted_storage_locs.begin(), sorted_storage_locs.end());\n\n    // Calculate the total number of containers to be stored.\n    int num_containers = D * D - 1 - N;\n\n    // --- Container Placement Phase ---\n    // This phase handles the arrival of containers one by one.\n    // For each arriving container, we decide where to store it.\n    // Our strategy: The d-th container to arrive (with ID t_d) is placed in the d-th location\n    // from our sorted list of storage locations (`sorted_storage_locs`). This greedy approach aims\n    // to keep containers with smaller target retrieval IDs in \"closer\" or more accessible locations.\n    \n    // We need to record the arrival order for each container ID.\n    // `container_arrival_idx[container_id]` will store the index `d` (0 to num_containers-1)\n    // representing the order in which `container_id` arrived and was placed.\n    vector<int> container_arrival_idx(num_containers); \n\n    for (int d = 0; d < num_containers; ++d) {\n        int container_id; // The ID of the container arriving at step d.\n        cin >> container_id;\n\n        // The d-th arriving container is placed at the d-th location in our sorted list.\n        CellInfo current_storage_loc = sorted_storage_locs[d];\n        pair<int, int> pos = {current_storage_loc.r, current_storage_loc.c};\n        \n        // Output the chosen storage location (row and column) for this container.\n        cout << pos.first << \" \" << pos.second << endl;\n        // `endl` typically flushes the output buffer in C++ streams, which is required.\n        \n        // Record that `container_id` arrived at step `d` and was assigned to `sorted_storage_locs[d]`.\n        // This means container_id is stored at the d-th closest available slot.\n        container_arrival_idx[container_id] = d; \n    }\n\n    // --- Container Retrieval Phase ---\n    // After all containers are stored, we need to determine the order in which they are transported out.\n    // The goal is to minimize the number of inversions in the retrieval sequence `b_0, b_1, ..., b_{M-1}`.\n    // This is achieved by aiming for the sorted sequence `0, 1, ..., M-1`.\n    // Our placement strategy (d-th arrival at d-th closest slot) allows for this.\n    // Container `k` is placed at `sorted_storage_locs[container_arrival_idx[k]]`.\n    // By retrieving containers in increasing order of their IDs (0, 1, 2, ...), we can achieve minimal inversions.\n    // Container `k` can be retrieved at step `k` because its location is guaranteed to be reachable.\n    // All containers `0, ..., k-1` are retrieved before container `k`, making their locations empty.\n    // The entire storage area is connected to the entrance, ensuring reachability.\n    \n    for (int k = 0; k < num_containers; ++k) {\n        // We want to retrieve container with ID `k` at step `k` of the retrieval sequence.\n        // Find out which storage slot `d` this container `k` was assigned to based on its arrival order.\n        int d = container_arrival_idx[k]; \n        \n        // The location of container `k` is the d-th sorted storage location.\n        CellInfo retrieved_cell = sorted_storage_locs[d];\n        pair<int, int> pos = {retrieved_cell.r, retrieved_cell.c};\n        \n        // Output the coordinates of the container to be transported out at this step.\n        cout << pos.first << \" \" << pos.second << endl;\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint n, m;\nvector<vector<int>> initial_grid;\nvector<vector<int>> output_grid; // -1: unassigned, 0..m: assigned color\nvector<vector<bool>> adj;\nvector<pair<int, int>> dx = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};\n\n// Checks if assigning color 'color_to_assign' to a cell is valid\n// given the colors of its already assigned neighbors.\n// 'neighbor_colors' is a set of colors of already assigned neighbors of the cell.\nbool is_valid(int color_to_assign, const set<int>& neighbor_colors) {\n    for (int neighbor_color : neighbor_colors) {\n        if (color_to_assign != neighbor_color) {\n            if (!adj[min(color_to_assign, neighbor_color)][max(color_to_assign, neighbor_color)]) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> n >> m;\n\n    initial_grid.resize(n, vector<int>(n));\n    output_grid.resize(n, vector<int>(n, -1)); // Initialize all cells as unassigned (-1)\n\n    // Store first occurrence of each color (1 to m) as a seed\n    vector<pair<int, int>> seeds(m + 1, {-1, -1});\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cin >> initial_grid[i][j];\n            if (initial_grid[i][j] >= 1 && initial_grid[i][j] <= m) {\n                if (seeds[initial_grid[i][j]].first == -1) {\n                    seeds[initial_grid[i][j]] = {i, j};\n                }\n            }\n        }\n    }\n\n    // Compute adjacency matrix for colors 0 to m\n    adj.resize(m + 1, vector<bool>(m + 1, false));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            int c1 = initial_grid[i][j];\n            if (c1 != 0) { // Only check adjacencies for non-zero colors in the input\n                for (auto& move : dx) {\n                    int ni = i + move.first;\n                    int nj = j + move.second;\n                    if (ni >= 0 && ni < n && nj >= 0 && nj < n) {\n                        int c2 = initial_grid[ni][nj];\n                        if (c1 != c2) {\n                            adj[min(c1, c2)][max(c1, c2)] = true;\n                        }\n                    } else { // Neighbor is outside the grid, which means it's adjacent to color 0\n                        adj[min(c1, 0)][max(c1, 0)] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    // BFS queue stores cells to process. We prioritize processing non-zero colors.\n    queue<pair<int, int>> q;\n\n    // Seed the grid with initial colors and add them to the queue\n    // Priority is given to non-zero colors.\n    for (int k = 1; k <= m; ++k) {\n        if (seeds[k].first != -1) {\n            int r = seeds[k].first;\n            int c = seeds[k].second;\n            if (output_grid[r][c] == -1) { // If cell is unassigned\n                output_grid[r][c] = k;\n                q.push({r, c});\n            }\n        }\n    }\n\n    // Initialize color 0 for cells that are initially 0 and on the border,\n    // or if the input color was 0. These ensure color 0 connectivity.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (initial_grid[i][j] == 0) {\n                if (output_grid[i][j] == -1) { // If unassigned and input was 0\n                    output_grid[i][j] = 0;\n                    // We don't push color 0 to the queue because color 0 expansion is implicit\n                    // and doesn't drive the assignment of non-zero colors.\n                    // However, if 0 is the *only* color assigned initially (e.g. all 0s input),\n                    // we might need to seed it if it's a border cell.\n                }\n            }\n        }\n    }\n    // Ensure border cells that are unassigned default to 0.\n    for (int i = 0; i < n; ++i) {\n        if (output_grid[i][0] == -1) { output_grid[i][0] = 0; }\n        if (output_grid[i][n-1] == -1) { output_grid[i][n-1] = 0; }\n    }\n    for (int j = 0; j < n; ++j) {\n        if (output_grid[0][j] == -1) { output_grid[0][j] = 0; }\n        if (output_grid[n-1][j] == -1) { output_grid[n-1][j] = 0; }\n    }\n\n\n    // BFS to fill the grid\n    // The queue `q` primarily contains seeds of non-zero colors.\n    // When a non-zero cell expands, it decides the color of its unassigned neighbors.\n    while (!q.empty()) {\n        pair<int, int> current_cell = q.front();\n        q.pop();\n        int r = current_cell.first;\n        int c = current_cell.second;\n        int current_color = output_grid[r][c];\n\n        for (auto& move : dx) {\n            int nr = r + move.first;\n            int nc = c + move.second;\n\n            if (nr >= 0 && nr < n && nc >= 0 && nc < n) {\n                if (output_grid[nr][nc] == -1) { // If neighbor is unassigned\n                    // Collect colors of already assigned neighbors of (nr, nc)\n                    set<int> neighbor_colors;\n                    for (auto& next_move : dx) {\n                        int nnr = nr + next_move.first;\n                        int nnc = nc + next_move.second;\n                        if (nnr >= 0 && nnr < n && nnc >= 0 && nnc < n) {\n                            if (output_grid[nnr][nnc] != -1) { // Collect colors of assigned neighbors\n                                neighbor_colors.insert(output_grid[nnr][nnc]);\n                            }\n                        }\n                    }\n\n                    int color_to_assign = -1;\n\n                    // Strategy:\n                    // 1. Try to assign color 0 if it's valid.\n                    // 2. If 0 is not valid, try to assign a non-zero color K.\n                    //    - Prioritize K if it's required by `current_color` (i.e., `adj[current_color][K]` is true).\n                    //    - If multiple such K exist, pick the smallest.\n                    //    - If no prioritized K is found, pick the smallest valid K.\n\n                    bool can_be_zero = is_valid(0, neighbor_colors);\n\n                    if (can_be_zero) {\n                        // Color 0 is valid. We prefer it to maximize score.\n                        // Assigning 0 means it remains 0 (since output_grid[nr][nc] was -1, and now becomes 0).\n                        // We do not push 0 to the queue as its expansion is implicit.\n                        color_to_assign = 0;\n                    } else {\n                        // Color 0 is NOT valid. We MUST assign a non-zero color.\n                        int best_k = -1;\n\n                        // First, try to find a K required by current_color\n                        if (current_color != 0) { // current_color is non-zero, check its adjacencies\n                            for (int k = 1; k <= m; ++k) {\n                                if (adj[min(current_color, k)][max(current_color, k)]) { // k is required by current_color\n                                    if (is_valid(k, neighbor_colors)) { // k is valid for this cell\n                                        best_k = k; // Found a candidate K\n                                        break; // Prioritize first such K\n                                    }\n                                }\n                            }\n                        }\n\n                        // If no prioritized K was found, find any valid non-zero color K\n                        if (best_k == -1) {\n                            for (int k = 1; k <= m; ++k) {\n                                if (is_valid(k, neighbor_colors)) {\n                                    best_k = k;\n                                    break; // Found first valid non-zero color K\n                                }\n                            }\n                        }\n                        color_to_assign = best_k;\n                    }\n\n                    // Assign the determined color and enqueue if it's non-zero.\n                    if (color_to_assign != -1) {\n                        output_grid[nr][nc] = color_to_assign;\n                        if (color_to_assign != 0) { // Only push non-zero colors to the queue\n                            q.push({nr, nc});\n                        }\n                    } else {\n                        // This case implies that no color (0 or 1..m) could be validly assigned.\n                        // This could happen if the problem constraints are impossible for this heuristic,\n                        // or if the seeding/expansion order leads to a dead end.\n                        // For a contest, leaving it as -1 and filling later might be an option,\n                        // but the problem implies a solution exists. We assume best_k is found if !can_be_zero.\n                        // As a fallback, we might assign 0 if it was valid but not preferred, or if problem implies any solution is fine.\n                        // However, the logic implies if !can_be_zero, then best_k MUST be found.\n                        // If it's not found, the strategy fails.\n                        // Given the scoring and heuristic nature, this state is unlikely if adjacencies are feasible.\n                    }\n                }\n            }\n        }\n    }\n\n    // Final pass: Fill any remaining unassigned cells (-1) with color 0.\n    // This ensures connectivity of color 0 and maximizes the score.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (output_grid[i][j] == -1) {\n                output_grid[i][j] = 0;\n            }\n        }\n    }\n\n    // Print the output grid\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            cout << output_grid[i][j] << (j == n - 1 ? \"\" : \" \");\n        }\n        cout << \"\\n\";\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <iomanip>\n\nusing namespace std;\n\n// Use a large value for infinity in distance calculations.\n// Given N <= 100, a path length is at most N-1. Max difference per step is 1.\n// So N+5 should be sufficiently large for INF.\nconst long long INF = 1e18; \n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n, d, q;\n    cin >> n >> d >> q;\n\n    // Stores the result of pairwise comparisons:\n    // comparison[i][j] = 1 if w_i < w_j\n    // comparison[i][j] = -1 if w_i > w_j\n    // comparison[i][j] = 0 if w_i = w_j\n    // comparison[i][j] = 2 if unknown\n    vector<vector<int>> comparison(n, vector<int>(n, 2));\n\n    int queries_budget = q;\n    int current_queries = 0;\n\n    // Phase 1: Prioritize comparisons between items with small index differences.\n    // This helps establish local relationships and might reveal structured weight distributions.\n    // We check differences from 1 up to a certain limit. The limit is capped by N/2\n    // to avoid redundant checks (e.g., diff=1 queries (0,1), (1,2), ..., (N-1,0). diff=N-1 queries (0,N-1), etc. which are inverse of diff=1).\n    // Also, cap the number of differences to check to not exceed Q.\n    int max_diff_to_check = min(10, n / 2); \n\n    for (int diff = 1; diff <= max_diff_to_check; ++diff) {\n        if (current_queries >= queries_budget) break;\n        for (int i = 0; i < n; ++i) {\n            if (current_queries >= queries_budget) break;\n            int j = (i + diff) % n; // Circular index difference\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1; // Symmetric relation\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1; // Symmetric relation\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0; // Symmetric relation\n                }\n            }\n        }\n    }\n    \n    // Phase 2: If budget remains, query arbitrary pairs (i, j) with i < j.\n    // This strategy aims to gather as many direct pairwise comparisons as possible.\n    for (int i = 0; i < n; ++i) {\n        if (current_queries >= queries_budget) break;\n        for (int j = i + 1; j < n; ++j) { // Iterate through unique pairs (i, j) with i < j\n            if (current_queries >= queries_budget) break;\n            \n            // Only query if the relationship is not yet known\n            if (comparison[i][j] == 2) { \n                cout << 1 << \" \" << 1 << \" \" << i << \" \" << j << endl;\n                current_queries++;\n                char result;\n                cin >> result;\n                \n                if (result == '<') {\n                    comparison[i][j] = 1;\n                    comparison[j][i] = -1;\n                } else if (result == '>') {\n                    comparison[i][j] = -1;\n                    comparison[j][i] = 1;\n                } else { // '='\n                    comparison[i][j] = 0;\n                    comparison[j][i] = 0;\n                }\n            }\n        }\n    }\n\n    // Initialize distance matrix for Floyd-Warshall algorithm.\n    // dist[i][j] will store the minimum possible value of (w_i - w_j).\n    // Weights w_i are positive integers (>= 1).\n    // If w_i < w_j, then w_i - w_j <= -1. The minimum possible difference is -1.\n    // If w_i > w_j, then w_i - w_j >= 1. The minimum possible difference is 1.\n    // If w_i = w_j, then w_i - w_j = 0.\n    vector<vector<long long>> dist(n, vector<long long>(n));\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            if (i == j) {\n                dist[i][j] = 0; // Distance to self is 0\n            } else if (comparison[i][j] == 1) { // w_i < w_j => w_i - w_j <= -1\n                dist[i][j] = -1;\n            } else if (comparison[i][j] == -1) { // w_i > w_j => w_i - w_j >= 1\n                dist[i][j] = 1;\n            } else if (comparison[i][j] == 0) { // w_i = w_j\n                dist[i][j] = 0;\n            } else { // Unknown relationship\n                dist[i][j] = INF; // Initialize with infinity\n            }\n        }\n    }\n\n    // Run Floyd-Warshall to compute all-pairs shortest paths (minimum differences).\n    // This step integrates all pairwise comparisons to infer transitive relationships.\n    for (int k = 0; k < n; ++k) { // Intermediate node\n        for (int i = 0; i < n; ++i) { // Source node\n            for (int j = 0; j < n; ++j) { // Destination node\n                // If paths through k are possible, update distance\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    // Estimate weights based on the computed differences.\n    // We use dist[0][i] which represents the minimum inferred difference w_0 - w_i.\n    // So, w_i = w_0 + dist[0][i].\n    // To get an estimate of w_i's magnitude, we can use -dist[0][i] as a proxy.\n    // If dist[0][i] is -5, it implies w_i is roughly 5 units heavier than w_0. So -dist[0][i] = 5.\n    // If dist[0][i] is 3, it implies w_i is roughly 3 units lighter than w_0. So -dist[0][i] = -3.\n    // This gives a relative ordering.\n    vector<pair<long long, int>> estimated_weights(n);\n    long long min_estimated_val = 0; // To find the minimum estimated value for shifting\n    \n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i] = {-dist[0][i], i}; // Use -dist[0][i] as estimated weight\n        min_estimated_val = min(min_estimated_val, estimated_weights[i].first);\n    }\n\n    // Shift the estimated weights so that the minimum weight is 1.\n    // This ensures all estimated weights are positive integers, respecting the problem's constraint.\n    for (int i = 0; i < n; ++i) {\n        estimated_weights[i].first = estimated_weights[i].first - min_estimated_val + 1;\n    }\n\n    // Sort items by their estimated weights in descending order.\n    // This is for the Largest Processing Time (LPT) heuristic, commonly used for multiway number partitioning.\n    sort(estimated_weights.rbegin(), estimated_weights.rend());\n\n    // Partitioning phase using the LPT heuristic.\n    // We want to assign items to 'd' bins such that the sum of weights in each bin is as equal as possible.\n    vector<long long> bin_sums(d, 0); // Stores the current total estimated weight for each bin\n    vector<int> assignment(n);       // Stores the final bin assignment for each item\n\n    for (const auto& item_pair : estimated_weights) {\n        long long weight = item_pair.first; // Estimated weight of the current item\n        int item_idx = item_pair.second;    // Original index of the item\n\n        // Find the bin with the minimum current sum of weights.\n        int best_bin = 0;\n        for (int b = 1; b < d; ++b) {\n            if (bin_sums[b] < bin_sums[best_bin]) {\n                best_bin = b;\n            }\n        }\n\n        // Assign the current item to the bin with the minimum sum.\n        assignment[item_idx] = best_bin;\n        bin_sums[best_bin] += weight; // Update the sum for this bin\n    }\n\n    // Output the final assignment of items to bins.\n    for (int i = 0; i < n; ++i) {\n        cout << assignment[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <deque> // Use deque for stacks for better performance and memory management\n\n// Structure to store box location: stack index and position within the stack.\nstruct BoxLocation {\n    int stack_idx;    // 0-indexed stack index\n    int pos_in_stack; // 0-indexed position from the bottom of the stack\n};\n\n// Global variables to store the state of the stacks and box locations.\nstd::vector<std::deque<int>> stacks;         // Stacks are implemented as deques of box IDs.\nstd::vector<BoxLocation> box_locations;      // Maps box ID (1 to n) to its location.\nint n_boxes, m_stacks;                       // Total number of boxes and stacks.\nint next_box_to_carry_id = 1;                // The ID of the next box to be carried out.\nstd::vector<std::pair<int, int>> operations; // Stores the sequence of operations: {box_id, destination_stack_id (1-based) or 0 for carry-out}.\n\n// Helper function to update the 'box_locations' array after a stack is modified.\n// It iterates through the given stack_content (a deque) and updates the location for each box.\nvoid update_box_locations_in_stack(int stack_idx, const std::deque<int>& stack_content) {\n    for (int i = 0; i < stack_content.size(); ++i) {\n        int box_id = stack_content[i];\n        box_locations[box_id] = {stack_idx, i}; // Update location: stack index and position.\n    }\n}\n\n// Function to perform Operation 1: moving a block of boxes.\n// 'v_initiator_id': The ID of the box that is at the bottom of the block being moved.\n//                   This box is chosen because it's the one directly above the target box\n//                   (or is the target box itself if it was the only one not carried out and we move it).\n// 'dest_stack_idx': The 0-indexed destination stack.\nvoid perform_move_operation(int v_initiator_id, int dest_stack_idx) {\n    int src_stack_idx = box_locations[v_initiator_id].stack_idx;\n    int initiator_pos_in_src_stack = box_locations[v_initiator_id].pos_in_stack;\n    \n    std::deque<int>& src_stack = stacks[src_stack_idx];\n\n    // The block to move starts from the initiator's position to the top of the source stack.\n    int start_move_pos = initiator_pos_in_src_stack;\n    \n    // Record the operation: (initiator_box_id, destination_stack_id + 1).\n    operations.push_back({v_initiator_id, dest_stack_idx + 1});\n\n    // Temporarily store the block of boxes to be moved.\n    // Using std::vector here for a contiguous block is efficient.\n    std::vector<int> block_to_move;\n    block_to_move.reserve(src_stack.size() - start_move_pos); // Reserve space to avoid reallocations.\n    for (int i = start_move_pos; i < src_stack.size(); ++i) {\n        block_to_move.push_back(src_stack[i]);\n    }\n    \n    // Store the current height of the destination stack. This is crucial for updating\n    // the positions of the moved boxes correctly.\n    int current_dest_height = stacks[dest_stack_idx].size();\n    \n    // Append the block of boxes to the destination stack.\n    // std::deque's push_back is efficient (amortized O(1)).\n    for (size_t i = 0; i < block_to_move.size(); ++i) {\n        int box_id = block_to_move[i];\n        stacks[dest_stack_idx].push_back(box_id);\n        // Update the location for the moved box. Its new position is based on the\n        // original height of the destination stack plus its index within the block.\n        box_locations[box_id] = {dest_stack_idx, current_dest_height + (int)i};\n    }\n\n    // Update the source stack: remove the moved block by resizing.\n    // std::deque's resize from the end is efficient.\n    src_stack.resize(start_move_pos);\n    \n    // After resizing the source stack, update the locations of the remaining boxes in it.\n    update_box_locations_in_stack(src_stack_idx, src_stack);\n}\n\n// Main function to solve the problem.\nvoid solve() {\n    // Optimize C++ standard streams for competitive programming.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    std::cin >> n_boxes >> m_stacks;\n\n    stacks.resize(m_stacks);\n    box_locations.resize(n_boxes + 1); // Resize for 1-based indexing of box IDs.\n\n    // Initialize stacks and record initial box locations.\n    for (int i = 0; i < m_stacks; ++i) {\n        int num_boxes_in_stack = n_boxes / m_stacks; // Constraint: N is divisible by M.\n        stacks[i].resize(num_boxes_in_stack); // Initialize deque with n/m elements.\n        for (int j = 0; j < num_boxes_in_stack; ++j) {\n            std::cin >> stacks[i][j];\n            box_locations[stacks[i][j]] = {i, j}; // Record location.\n        }\n    }\n\n    // Main loop: continue until all boxes are carried out.\n    while (next_box_to_carry_id <= n_boxes) {\n        int target_box_id = next_box_to_carry_id; // The box we are currently trying to carry out.\n        \n        // Get current location of the target box.\n        int src_stack_idx = box_locations[target_box_id].stack_idx;\n        int target_pos_in_stack = box_locations[target_box_id].pos_in_stack;\n        std::deque<int>& current_stack = stacks[src_stack_idx];\n\n        // Check if the target box is at the top of its stack.\n        if (target_pos_in_stack == current_stack.size() - 1) { \n            // Operation 2: Carry out the box (cost is 0).\n            operations.push_back({target_box_id, 0}); // 0 signifies carry-out.\n            current_stack.pop_back(); // Remove the box from the stack.\n            next_box_to_carry_id++; // Move to the next box in sequence.\n        } else { \n            // Target box is NOT at the top. We need to move boxes above it.\n            // The box directly above the target box will initiate the move.\n            // This box is at index 'target_pos_in_stack + 1'.\n            int box_above_target_id = current_stack[target_pos_in_stack + 1];\n\n            // Determine the best destination stack using the heuristic:\n            // 1. Prefer an empty stack with the smallest index.\n            // 2. If no empty stacks, prefer a non-empty stack with the minimum height.\n            //    If heights are tied, prefer the stack with the smallest index.\n            \n            int dest_stack_idx = -1;\n            int min_height = -1; \n            bool found_empty_stack = false;\n\n            for (int i = 0; i < m_stacks; ++i) {\n                if (i == src_stack_idx) continue; // Cannot move to the same stack.\n\n                if (stacks[i].empty()) {\n                    if (!found_empty_stack) { // Found the first empty stack (smallest index).\n                        dest_stack_idx = i;\n                        found_empty_stack = true;\n                    }\n                } else { // Stack `i` is not empty.\n                    if (!found_empty_stack) { // Only consider non-empty stacks if no empty ones were found.\n                        int current_height = stacks[i].size();\n                        if (min_height == -1 || current_height < min_height) {\n                            min_height = current_height;\n                            dest_stack_idx = i;\n                        } else if (current_height == min_height) {\n                            // Tie-breaking: prefer smaller index.\n                            if (i < dest_stack_idx) {\n                                dest_stack_idx = i;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Fallback for selecting destination stack if loop didn't assign one (should not happen if m_stacks > 1).\n            if (dest_stack_idx == -1) {\n                 for(int i = 0; i < m_stacks; ++i) {\n                     if (i != src_stack_idx) {\n                         dest_stack_idx = i;\n                         break;\n                     }\n                 }\n            }\n            \n            // Perform the move operation. The 'box_above_target_id' initiates the move,\n            // and it, along with boxes above it, are moved. The 'target_box_id' remains in place.\n            perform_move_operation(box_above_target_id, dest_stack_idx);\n            \n            // 'next_box_to_carry_id' does NOT increment because the target box has not been carried out yet.\n            // The loop will re-evaluate 'target_box_id' in the next iteration, and it will be\n            // one step closer to the top, or at the top if all boxes above it were removed.\n        }\n    }\n\n    // Output all recorded operations.\n    for (const auto& op : operations) {\n        std::cout << op.first << \" \" << op.second << \"\\n\";\n    }\n}\n\nint main() {\n    solve(); // Call the main solving function.\n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <vector>\n#include <queue>\n#include <cmath>\n#include <iomanip>\n#include <numeric>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\nint N;\nvector<string> h_walls, v_walls;\nvector<vector<int>> d;\n\n// Adjacency list for grid graph\n// Stores pairs of {neighbor_row, neighbor_col, move_char, wall_type}\n// wall_type: 0 for no wall, 1 for horizontal wall, 2 for vertical wall\n// This information is not strictly needed if we check walls dynamically,\n// but could be useful for pathfinding. For this problem, we check walls directly.\nvector<pair<int, int>> adj[40][40];\n\nint dr[] = {-1, 1, 0, 0}; // Up, Down, Left, Right\nint dc[] = {0, 0, -1, 1};\nchar moves[] = {'U', 'D', 'L', 'R'};\n\n// Check if a move from (r, c) to (nr, nc) is valid (no wall)\nbool is_valid_move(int r, int c, int nr, int nc) {\n    if (nr < 0 || nr >= N || nc < 0 || nc >= N) {\n        return false;\n    }\n    if (nr == r - 1) { // Moving Up\n        if (v_walls[r][c] == '1') return false;\n    } else if (nr == r + 1) { // Moving Down\n        if (h_walls[r][c] == '1') return false;\n    } else if (nc == c - 1) { // Moving Left\n        if (v_walls[r][c-1] == '1') return false;\n    } else if (nc == c + 1) { // Moving Right\n        if (v_walls[r][c] == '1') return false;\n    }\n    return true;\n}\n\n// DFS to generate an initial path that visits all nodes\nstring initial_path_str;\nbool visited_dfs[40][40];\nint initial_path_len = 0;\nmap<pair<int, int>, int> visit_counts_dfs;\n\nvoid dfs_generate(int r, int c) {\n    visited_dfs[r][c] = true;\n    visit_counts_dfs[{r, c}]++;\n\n    for (int i = 0; i < 4; ++i) {\n        int nr = r + dr[i];\n        int nc = c + dc[i];\n\n        if (nr >= 0 && nr < N && nc >= 0 && nc < N && !visited_dfs[nr][nc]) {\n            if (is_valid_move(r, c, nr, nc)) {\n                initial_path_str += moves[i];\n                initial_path_len++;\n                dfs_generate(nr, nc);\n                initial_path_str += moves[i ^ 1]; // Move back\n                initial_path_len++;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    h_walls.resize(N - 1);\n    for (int i = 0; i < N - 1; ++i) cin >> h_walls[i];\n    v_walls.resize(N);\n    for (int i = 0; i < N; ++i) cin >> v_walls[i];\n\n    d.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> d[i][j];\n        }\n    }\n\n    // Build adjacency list implicitly by checking walls in is_valid_move\n    // DFS to generate initial path\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            visited_dfs[i][j] = false;\n        }\n    }\n    dfs_generate(0, 0);\n    \n    // Ensure (0,0) is visited twice if DFS starts/ends there\n    // The DFS logic above adds return moves, so (0,0) is visited at start and end\n    // If initial_path_len is 0 (e.g. 1x1 grid, though N>=20), handle it.\n    if (N > 0 && initial_path_len == 0) { // For N=1, this might happen. But N>=20.\n        // If grid is just one cell (0,0), path is empty, length 0.\n        // But problem says N>=20. So DFS should generate a path.\n    }\n\n\n    // Target visit counts proportional to sqrt(d_i,j)\n    // Minimize sum( d_i,j / N_i,j^2 )\n    // Equivalent to maximizing sum( d_i,j / N_i,j^2 )\n    // For total visits V, N_i,j should be proportional to sqrt(d_i,j)\n    // N_i,j = C * sqrt(d_i,j)\n    // Sum(N_i,j) = V => C = V / Sum(sqrt(d_i,j))\n    // N_i,j = V * sqrt(d_i,j) / Sum(sqrt(d_k,m))\n\n    // Max path length is 100000.\n    // Initial path length L_dfs.\n    // Each additional visit can be achieved by a detour X->Y->X, adding 2 moves.\n    // Max number of extra visits K_max = (100000 - L_dfs) / 2\n    // Total max visits V_max = N*N + K_max\n\n    long double sum_sqrt_d = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            sum_sqrt_d += sqrt((long double)d[i][j]);\n        }\n    }\n\n    int max_total_visits = 100000; // Maximum allowed path length\n\n    vector<long long> target_N(N * N, 0);\n    long long current_total_visits = 0;\n\n    // Ensure each cell is visited at least once\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            target_N[i * N + j] = 1;\n            current_total_visits++;\n        }\n    }\n    \n    // Distribute remaining visits greedily based on sqrt(d_i,j)\n    // We have `max_total_visits - current_total_visits` visits to distribute.\n    // This number is an upper bound on the sum of ADDITIONAL visits beyond the first one for each cell.\n    // Let's use the objective function to guide distribution: maximize sum(d_i,j / N_i,j^2)\n    // This implies N_i,j should be proportional to sqrt(d_i,j).\n\n    // Strategy: calculate proportional counts for all cells, then scale and adjust.\n    vector<pair<long double, pair<int, int>>> proportional_visits;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            proportional_visits.push_back({sqrt((long double)d[i][j]), {i, j}});\n        }\n    }\n    sort(proportional_visits.rbegin(), proportional_visits.rend());\n\n    // Distribute visits until total path length constraint is met.\n    // We have `max_total_visits` moves. Each visit adds at least 1 move, often 2 (detour).\n    // Let's use the rule that each visit adds 2 moves (detour)\n    // Total visits V should satisfy L_dfs + 2 * (V - N*N) <= 100000\n    // 2 * (V - N*N) <= 100000 - L_dfs\n    // V - N*N <= (100000 - L_dfs) / 2\n    // V <= N*N + (100000 - L_dfs) / 2\n    int max_additional_visits = (100000 - initial_path_len) / 2;\n    if (max_additional_visits < 0) max_additional_visits = 0;\n\n    current_total_visits = N * N; // All cells visited once initially\n\n    // Greedily assign additional visits to cells with high sqrt(d_i,j)\n    vector<long long> N_final(N * N, 1); // Start with 1 visit for each cell\n    long long visits_added_count = 0;\n\n    // First, distribute visits to reach max_additional_visits for sqrt(d_i,j) based proportional counts\n    vector<pair<long double, pair<int,int>>> sqrt_d_sorted;\n    for(int i=0; i<N; ++i) for(int j=0; j<N; ++j) sqrt_d_sorted.push_back({sqrt((long double)d[i][j]), {i,j}});\n    sort(sqrt_d_sorted.rbegin(), sqrt_d_sorted.rend());\n    \n    for(const auto& p : sqrt_d_sorted) {\n        if (visits_added_count >= max_additional_visits) break;\n        int r = p.second.first;\n        int c = p.second.second;\n        N_final[r*N+c]++;\n        visits_added_count++;\n    }\n\n    // If we still have budget for more visits (e.g. if max_additional_visits was very large, and sum of sqrt(d_i,j) was small)\n    // we can add more visits to cells with highest d_i,j, using the priority queue logic.\n    // However, the proportional distribution up to max_additional_visits is likely optimal.\n\n    // If current_total_visits (N*N) + visits_added_count > 100000 (this check is redundant if max_additional_visits is calculated correctly)\n    // we need to cap it. But max_additional_visits ensures total length <= 100000.\n\n    // Current visit counts based on initial DFS and N_final assignment\n    map<pair<int, int>, int> current_N;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            current_N[{i, j}] = visit_counts_dfs.count({i, j}) ? visit_counts_dfs[{i, j}] : 0;\n        }\n    }\n\n    // Adjust initial DFS counts to match N_final targets\n    // The DFS path might visit cells more than once initially.\n    // We need to reach N_final counts.\n    vector<pair<long double, pair<int, int>>> pq_cells; // (priority, {r, c})\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (current_N[{i, j}] < N_final[i * N + j]) {\n                pq_cells.push_back({ (long double)d[i][j] / (long double)(current_N[{i, j}] * current_N[{i, j}]), {i, j} });\n            }\n        }\n    }\n    sort(pq_cells.rbegin(), pq_cells.rend());\n\n    vector<pair<int, int>> cells_to_visit_extra; // Cells to add extra visits to\n    vector<int> extra_visits_count(N*N, 0);\n\n    int current_extra_visits_total = 0;\n    for(const auto& p : pq_cells) {\n        int r = p.second.first;\n        int c = p.second.second;\n        int needed = N_final[r*N+c] - current_N[{r,c}];\n        for(int k=0; k<needed; ++k) {\n            if (current_extra_visits_total >= max_additional_visits) break;\n            cells_to_visit_extra.push_back({r, c});\n            extra_visits_count[r*N+c]++;\n            current_extra_visits_total++;\n        }\n        if (current_extra_visits_total >= max_additional_visits) break;\n    }\n    \n    // Construct final path by adding detours\n    string final_path = initial_path_str;\n    int current_path_len = initial_path_len;\n\n    // Store path as sequence of cells for easier detour insertion\n    vector<pair<int, int>> path_cells;\n    path_cells.push_back({0,0});\n    int cur_r = 0, cur_c = 0;\n    for(char move : initial_path_str) {\n        if (move == 'U') cur_r--;\n        else if (move == 'D') cur_r++;\n        else if (move == 'L') cur_c--;\n        else if (move == 'R') cur_c++;\n        path_cells.push_back({cur_r, cur_c});\n    }\n\n    // Add detours\n    for (int r_target = 0; r_target < N; ++r_target) {\n        for (int c_target = 0; c_target < N; ++c_target) {\n            int count_to_add = extra_visits_count[r_target * N + c_target];\n            if (count_to_add == 0) continue;\n\n            // For each cell, add `count_to_add` detours.\n            // Simple detour: find last visit to (r_target, c_target) and insert a minimal path to it.\n            // This is complicated. A simpler approach: append detours from the END of current path.\n            // Path: P_dfs, then for each (r,c) to visit K times: append path(current_pos, r, c), append path(r,c, current_pos)\n            \n            for(int k=0; k<count_to_add; ++k) {\n                 if (current_path_len + 2 > 100000) break; // Safety break\n\n                // Find current end of path\n                cur_r = path_cells.back().first;\n                cur_c = path_cells.back().second;\n                \n                // Find shortest path from (cur_r, cur_c) to (r_target, c_target)\n                queue<pair<int, int>> q;\n                q.push({cur_r, cur_c});\n                vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited(N, vector<bool>(N, false));\n                visited[cur_r][cur_c] = true;\n                bool found = false;\n\n                while (!q.empty()) {\n                    pair<int, int> curr = q.front();\n                    q.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == r_target && c_curr == c_target) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited[nr][nc]) {\n                            visited[nr][nc] = true;\n                            parent[nr][nc] = {r_curr, c_curr};\n                            q.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen as all cells are reachable */ continue; }\n\n                // Reconstruct path from (cur_r, cur_c) to (r_target, c_target)\n                vector<char> detour_fwd;\n                vector<pair<int, int>> detour_cells_fwd;\n                pair<int, int> trace = {r_target, c_target};\n                while (trace.first != cur_r || trace.second != cur_c) {\n                    pair<int, int> p_trace = parent[trace.first][trace.second];\n                    if (p_trace.first == -1) break; // Should not happen\n\n                    if (trace.first == p_trace.first - 1) detour_fwd.push_back('U');\n                    else if (trace.first == p_trace.first + 1) detour_fwd.push_back('D');\n                    else if (trace.second == p_trace.second - 1) detour_fwd.push_back('L');\n                    else if (trace.second == p_trace.second + 1) detour_fwd.push_back('R');\n                    \n                    detour_cells_fwd.push_back(trace);\n                    trace = p_trace;\n                }\n                reverse(detour_fwd.begin(), detour_fwd.end());\n                reverse(detour_cells_fwd.begin(), detour_cells_fwd.end());\n\n                // Add detour path to cells list\n                for(char move : detour_fwd) {\n                    path_cells.push_back({r_target,c_target}); // add target cell\n                    if (move == 'U') path_cells.push_back({path_cells.back().first - 1, path_cells.back().second});\n                    else if (move == 'D') path_cells.push_back({path_cells.back().first + 1, path_cells.back().second});\n                    else if (move == 'L') path_cells.push_back({path_cells.back().first, path_cells.back().second - 1});\n                    else if (move == 'R') path_cells.push_back({path_cells.back().first, path_cells.back().second + 1});\n                }\n                \n                // Add the final (r_target, c_target) cell itself\n                path_cells.push_back({r_target, c_target});\n                \n                // Now add path back to original current position (cur_r, cur_c)\n                // This is BFS from (r_target, c_target) to (cur_r, cur_c)\n                queue<pair<int, int>> q_ret;\n                q_ret.push({r_target, c_target});\n                vector<vector<pair<int, int>>> parent_ret(N, vector<pair<int, int>>(N, {-1, -1}));\n                vector<vector<bool>> visited_ret(N, vector<bool>(N, false));\n                visited_ret[r_target][c_target] = true;\n                found = false;\n\n                while (!q_ret.empty()) {\n                    pair<int, int> curr = q_ret.front();\n                    q_ret.pop();\n                    int r_curr = curr.first;\n                    int c_curr = curr.second;\n\n                    if (r_curr == cur_r && c_curr == cur_c) {\n                        found = true;\n                        break;\n                    }\n\n                    for (int i = 0; i < 4; ++i) {\n                        int nr = r_curr + dr[i];\n                        int nc = c_curr + dc[i];\n\n                        if (is_valid_move(r_curr, c_curr, nr, nc) && !visited_ret[nr][nc]) {\n                            visited_ret[nr][nc] = true;\n                            parent_ret[nr][nc] = {r_curr, c_curr};\n                            q_ret.push({nr, nc});\n                        }\n                    }\n                }\n                \n                if (!found) { /* Should not happen */ continue; }\n\n                // Reconstruct path back\n                trace = {cur_r, cur_c};\n                while(trace.first != r_target || trace.second != c_target) {\n                     pair<int, int> p_trace = parent_ret[trace.first][trace.second];\n                     if (p_trace.first == -1) break;\n\n                     if (trace.first == p_trace.first - 1) path_cells.push_back({p_trace.first - 1, p_trace.second});\n                     else if (trace.first == p_trace.first + 1) path_cells.push_back({p_trace.first + 1, p_trace.second});\n                     else if (trace.second == p_trace.second - 1) path_cells.push_back({p_trace.second - 1, p_trace.second});\n                     else if (trace.second == p_trace.second + 1) path_cells.push_back({p_trace.second + 1, p_trace.second});\n                     trace = p_trace;\n                }\n\n                // Update current path length and position\n                current_path_len = path_cells.size() - 1;\n                if (current_path_len > 100000) { // Cap path length\n                    path_cells.resize(100000 + 1); // Keep start and end for length 100000\n                    current_path_len = 100000;\n                }\n            }\n        }\n    }\n\n    // Convert path_cells back to moves string, truncated if necessary\n    final_path = \"\";\n    for (size_t i = 0; i < path_cells.size() - 1; ++i) {\n        if (final_path.length() >= 100000) break;\n\n        int r1 = path_cells[i].first;\n        int c1 = path_cells[i].second;\n        int r2 = path_cells[i+1].first;\n        int c2 = path_cells[i+1].second;\n\n        if (r2 == r1 - 1) final_path += 'U';\n        else if (r2 == r1 + 1) final_path += 'D';\n        else if (c2 == c1 - 1) final_path += 'L';\n        else if (c2 == c1 + 1) final_path += 'R';\n    }\n\n    cout << final_path << endl;\n\n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <map>\n\nusing namespace std;\n\nconst long long INF = 1e18;\nint N;\nchar grid[15][15];\nvector<string> t;\nint start_r, start_c;\n\n// For Dijkstra to find path for one string\n// dp[p][r][c]: min cost to type first p characters of target string, ending at (r,c)\n// where grid[r][c] matches the p-th character.\n// p from 1 to 5.\nlong long dp[6][15][15];\npair<int, int> pred[6][15][15]; // Stores previous coordinates to reconstruct path\n\n// Directions for BFS/Dijkstra\nint dr[] = {-1, 1, 0, 0};\nint dc[] = {0, 0, -1, 1};\n\nstruct State {\n    long long cost;\n    int r, c;\n\n    bool operator>(const State& other) const {\n        return cost > other.cost;\n    }\n};\n\n// Computes the minimum cost and path to type target_str starting from (sr, sc)\n// Returns {min_total_cost, end_r, end_c, sequence_of_operations}\ntuple<long long, int, int, vector<pair<int, int>>> compute_path(const string& target_str, int sr, int sc) {\n    for (int p = 0; p <= 5; ++p) {\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                dp[p][r][c] = INF;\n                pred[p][r][c] = {-1, -1};\n            }\n        }\n    }\n\n    char first_char = target_str[0];\n    \n    // Base case: p=1 (typing the first character)\n    // dp[1][r][c] = min cost to type first character (target_str[0]) ending at (r,c)\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (grid[r][c] == first_char) {\n                dp[1][r][c] = abs(r - sr) + abs(c - sc) + 1;\n                // pred[1][r][c] remains {-1, -1} to signify start\n            }\n        }\n    }\n\n    // Fill DP table for p = 2 to 5\n    for (int p = 2; p <= 5; ++p) {\n        char current_char_needed = target_str[p - 1];\n        \n        priority_queue<State, vector<State>, greater<State>> pq;\n        vector<vector<long long>> dist(N, vector<long long>(N, INF));\n        vector<vector<pair<int, int>>> layer_pred(N, vector<pair<int, int>>(N, {-1,-1}));\n\n        // Initialize Dijkstra PQ with costs from previous step (p-1)\n        // States in PQ are (cost_to_type_p-1_chars_ending_here, r, c)\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (dp[p - 1][r][c] != INF) {\n                    pq.push({dp[p - 1][r][c], r, c});\n                    dist[r][c] = dp[p - 1][r][c]; // dist here is min cost to reach (r,c) having typed p-1 chars\n                }\n            }\n        }\n\n        // Run Dijkstra\n        // We want to find min cost to reach any cell (nr, nc) for current_char_needed\n        // from any cell (r,c) which is a valid end for p-1 characters.\n        while (!pq.empty()) {\n            State current = pq.top();\n            pq.pop();\n\n            long long d = current.cost;\n            int r = current.r;\n            int c = current.c;\n\n            if (d > dist[r][c]) continue;\n\n            // Explore neighbors\n            for (int i = 0; i < 4; ++i) {\n                int nr = r + dr[i];\n                int nc = c + dc[i];\n\n                if (nr >= 0 && nr < N && nc >= 0 && nc < N) {\n                    // Cost to move from (r,c) to (nr,nc) AND append grid[nr][nc]\n                    long long move_cost = abs(nr - r) + abs(nc - c) + 1;\n                    \n                    // If the neighbor cell (nr, nc) has the character needed for the current step (p)\n                    if (grid[nr][nc] == current_char_needed) {\n                        if (dist[r][c] + move_cost < dist[nr][nc]) {\n                            dist[nr][nc] = dist[r][c] + move_cost;\n                            layer_pred[nr][nc] = {r, c}; // Store predecessor for path reconstruction\n                            pq.push({dist[nr][nc], nr, nc});\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Update DP table for step p\n        for (int r = 0; r < N; ++r) {\n            for (int c = 0; c < N; ++c) {\n                if (grid[r][c] == current_char_needed && dist[r][c] != INF) {\n                    dp[p][r][c] = dist[r][c];\n                    pred[p][r][c] = layer_pred[r][c]; // Store predecessor for path reconstruction\n                }\n            }\n        }\n    }\n\n    // Find the minimum cost to type the whole string (length 5)\n    long long min_total_cost = INF;\n    int final_r = -1, final_c = -1;\n\n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N; ++c) {\n            if (dp[5][r][c] < min_total_cost) {\n                min_total_cost = dp[5][r][c];\n                final_r = r;\n                final_c = c;\n            }\n        }\n    }\n\n    // Reconstruct path\n    vector<pair<int, int>> path_ops;\n    if (final_r != -1) {\n        int curr_r = final_r;\n        int curr_c = final_c;\n        for (int p = 5; p >= 1; --p) {\n            path_ops.push_back({curr_r, curr_c});\n            if (p > 1) { // For p=1, pred is {-1,-1}\n                pair<int, int> prev_pos = pred[p][curr_r][curr_c];\n                curr_r = prev_pos.first;\n                curr_c = prev_pos.second;\n            }\n        }\n        reverse(path_ops.begin(), path_ops.end());\n    }\n    \n    return {min_total_cost, final_r, final_c, path_ops};\n}\n\n// Helper to check if string 'needle' is a substring of 'haystack'\nbool contains(const string& haystack, const string& needle) {\n    return haystack.find(needle) != string::npos;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N >> M >> start_r >> start_c;\n    --start_r; --start_c; // 0-indexed\n\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> grid[i][j];\n        }\n    }\n\n    t.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> t[i];\n    }\n\n    vector<pair<int, int>> operations;\n    set<int> uncovered_indices;\n    for (int i = 0; i < M; ++i) {\n        uncovered_indices.insert(i);\n    }\n\n    int current_r = start_r;\n    int current_c = start_c;\n    long long total_cost = 0;\n    \n    // We can perform at most 5000 operations.\n    // Our strategy is to greedily type the cheapest full string that is not yet covered.\n    // Each typed string requires 5 operations.\n    // We continue this until we have typed 1000 strings (total 5000 operations)\n    // or until all strings are covered.\n\n    int max_strings_to_type = 1000; \n\n    for (int iter = 0; iter < max_strings_to_type; ++iter) {\n        if (uncovered_indices.empty()) break; // All strings are covered\n\n        long long min_iter_cost = INF;\n        int best_t_idx = -1;\n        int best_end_r = -1, best_end_c = -1;\n        vector<pair<int, int>> ops_for_best_t;\n\n        // Find the cheapest string to type among the currently uncovered ones\n        for (int idx : uncovered_indices) {\n            auto [cost, end_r, end_c, current_ops] = compute_path(t[idx], current_r, current_c);\n            \n            if (cost < min_iter_cost) {\n                min_iter_cost = cost;\n                best_t_idx = idx;\n                best_end_r = end_r;\n                best_end_c = end_c;\n                ops_for_best_t = current_ops;\n            }\n        }\n\n        // If no string can be typed (e.g., required chars not on grid, which is guaranteed not to happen)\n        if (best_t_idx == -1) { \n            break;\n        }\n\n        // Append operations for the chosen string\n        operations.insert(operations.end(), ops_for_best_t.begin(), ops_for_best_t.end());\n        current_r = best_end_r;\n        current_c = best_end_c;\n        total_cost += min_iter_cost;\n        \n        // Remove the typed string from the set of uncovered indices\n        uncovered_indices.erase(best_t_idx);\n    }\n\n    // Output the operations\n    cout << operations.size() << endl;\n    for (const auto& op : operations) {\n        cout << op.first + 1 << \" \" << op.second + 1 << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath> // Included for completeness, though not directly used in the final strategy.\n#include <iomanip> // Included for completeness, though not directly used in the final strategy.\n#include <utility> // Required for std::pair.\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // This can significantly speed up input/output operations, which is crucial\n    // for problems with large I/O or strict time limits.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n; // The size of the island grid (N x N). Constraints: 10 <= N <= 20.\n    int m; // The number of unexplored oil fields. Constraints: 2 <= M <= 20.\n    double epsilon; // The error parameter for the noisy divine query operation. Constraints: 0.01 <= epsilon <= 0.2.\n\n    // Read the initial problem parameters from standard input.\n    std::cin >> n >> m >> epsilon;\n\n    // Read the shapes of the M oil fields.\n    // Each shape is defined by its area (d) and a list of relative coordinates\n    // for the squares it occupies.\n    // For the chosen strategy (drilling every square), this information is not directly used.\n    // A more complex heuristic or optimization strategy might leverage these shapes\n    // to infer potential locations or prune search spaces.\n    for (int k = 0; k < m; ++k) {\n        int d; // The number of squares in the k-th oil field (area).\n        std::cin >> d;\n        for (int i = 0; i < d; ++i) {\n            int r, c; // Relative coordinates (row, column) of a square within the k-th oil field shape.\n            std::cin >> r >> c;\n            // The current strategy ignores these shapes.\n        }\n    }\n\n    // This vector will store the coordinates (row, column) of all squares\n    // that are found to contain oil reserves (i.e., v(i,j) > 0).\n    // This list will form the basis of our final \"guess\" operation.\n    std::vector<std::pair<int, int>> positive_oil_squares;\n\n    // --- Chosen Strategy: Drill every square on the island ---\n    //\n    // This is a deterministic, brute-force approach. It queries each of the N*N squares\n    // individually to reveal its exact oil reserve value v(i,j).\n    //\n    // Cost Analysis:\n    // - Operation Type: \"Drill\" (q 1 i j). Cost per operation: 1.\n    // - Total number of squares on the island: N*N.\n    // - Total cost for performing N*N drill operations: N*N.\n    //\n    // Operation Limit Analysis:\n    // - The problem statement allows a maximum of 2*N*N operations in total.\n    // - For the maximum island size N=20, N*N = 400 operations, and 2*N*N = 800 operations.\n    // - The N*N cost of this strategy is well within the allowed operation limit.\n    //\n    // Correctness Guarantee:\n    // - By drilling every square, we obtain the exact value of v(i,j) for every cell.\n    // - This guarantees that we can precisely identify *all* squares where v(i,j) > 0.\n    // - The final \"guess\" operation will therefore be 100% accurate, leading to a successful completion.\n    //\n    // Justification for ignoring the \"divine\" operation:\n    // - The \"divine\" operation (querying a set S of k squares) has a cost of 1/sqrt(k) but returns a noisy sum.\n    // - The noise (variance) increases with k, making it difficult to obtain precise information about individual v(i,j) values,\n    //   especially small values or distinguishing v(i,j)=0 from v(i,j)=1.\n    // - To guarantee identifying *all* squares with v(i,j) > 0, definitive information is required. Drilling provides this.\n    // - Given the small constraints on N (N <= 20), the total cost of N*N is sufficiently low. The guaranteed correctness\n    //   and simplicity of the drilling strategy make it a robust choice for achieving a high score. More complex strategies\n    //   involving divine queries might offer marginal benefits only for much larger grid sizes.\n    //\n    // Implementation Loop:\n    // - We iterate through each row 'i' from 0 to N-1.\n    // - Within each row, we iterate through each column 'j' from 0 to N-1.\n    // - For every square (i, j), we issue a \"drill\" query.\n    // - We then read the revealed oil reserves for that square.\n    // - If the reserves are positive, we record the square's coordinates.\n    for (int i = 0; i < n; ++i) {\n        for (int j = 0; j < n; ++j) {\n            // Output the drill query command: \"q 1 <row> <column>\"\n            // std::endl automatically flushes the output buffer.\n            std::cout << \"q 1 \" << i << \" \" << j << std::endl;\n\n            int reserves; // The value v(i, j) revealed for the current square.\n            std::cin >> reserves; // Read the result from standard input.\n\n            // If the square contains oil (reserves > 0), store its coordinates.\n            if (reserves > 0) {\n                positive_oil_squares.push_back({i, j});\n            }\n        }\n    }\n\n    // --- Output the Final Guess ---\n    //\n    // Once all squares have been drilled, the 'positive_oil_squares' vector contains\n    // the exact set of squares that have oil reserves. We now form the final \"guess\" operation.\n    //\n    // The format for the guess operation is: \"a <d> <i1> <j1> <i2> <j2> ...\"\n    // where 'd' is the total number of squares guessed to have oil.\n    std::cout << \"a \" << positive_oil_squares.size();\n    for (const auto& p : positive_oil_squares) {\n        std::cout << \" \" << p.first << \" \" << p.second;\n    }\n    std::cout << std::endl; // Flush the output buffer to ensure the guess is sent.\n\n    // --- Read Confirmation from Judge ---\n    //\n    // The judge will respond with '1' if our guess is correct and '0' if it is incorrect.\n    // Given the deterministic nature of the drilling strategy, we expect this to always be '1'.\n    int correct;\n    std::cin >> correct;\n\n    // If the guess was correct, the program has successfully completed its task.\n    if (correct == 1) {\n        return 0; // Exit with a success code.\n    } else {\n        // If the guess was incorrect (correct == 0), this indicates an unexpected issue.\n        // The N^2 drilling strategy is designed to be infallible for this problem.\n        // If this branch is reached, it might point to a subtle problem interpretation error\n        // or an extremely rare edge case. We exit with a non-zero code to signal abnormal termination.\n        return 1; \n    }\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\n#include <tuple>\n#include <map>\n#include <set>\n#include <iomanip>\n\nusing namespace std;\n\nlong long W;\nint D, N;\n\n// Represents a rectangular section.\nstruct Rect {\n    int x0, y0, x1, y1;       // Top-left (x0, y0) and bottom-right (x1, y1) coordinates.\n    long long area;           // Pre-calculated area.\n    int original_idx;         // Index within the generated list for a specific structure type (for debugging/tracking).\n};\n\n// Enum to identify different partition structures.\n// These are pre-defined layouts that divide the WxW area into N rectangles.\nenum StructureType {\n    RECURSIVE_BALANCED = 0, // Dynamically balanced subdivision.\n    VERTICAL_STRIPS = 1,    // N vertical strips of roughly equal width.\n    HORIZONTAL_STRIPS = 2,  // N horizontal strips of roughly equal height.\n    // Grid types: p x q grids where p is small and q is approx N/p.\n    GRID_2xN = 3, // 2 rows, approx N/2 cols\n    GRID_3xN = 4, // 3 rows, approx N/3 cols\n    GRID_4xN = 5, // 4 rows, approx N/4 cols\n    GRID_5xN = 6, // 5 rows, approx N/5 cols\n    GRID_6xN = 7, // 6 rows, approx N/6 cols\n    GRID_Nx2 = 8, // approx N/2 rows, 2 cols\n    GRID_Nx3 = 9, // approx N/3 rows, 3 cols\n    GRID_Nx4 = 10, // approx N/4 rows, 4 cols\n    GRID_Nx5 = 11, // approx N/5 rows, 5 cols\n    GRID_Nx6 = 12, // approx N/6 rows, 6 cols\n    NUM_STRUCTURES // Count of all defined types.\n};\n\n// Limit the number of candidate structures to evaluate to manage computation time.\nconst int MAX_STRUCTURES = 10; \n// Stores the types of partition structures that will be considered.\nvector<StructureType> active_structure_types;\n\n// --- Structure Generation Functions ---\n\n// Recursive helper to generate N rectangles by balanced subdivision.\n// Splits along the larger dimension to maintain aspect ratios.\nvoid generate_recursive_helper(vector<Rect>& rects, int x0, int y0, int x1, int y1, int count_needed, int& rect_idx) {\n    if (count_needed == 0) return; // No rectangles needed.\n    if (count_needed == 1) { // Base case: create the single rectangle.\n        rects.push_back({x0, y0, x1, y1, (long long)(x1 - x0) * (y1 - y0), rect_idx++});\n        return;\n    }\n\n    long long total_width = x1 - x0;\n    long long total_height = y1 - y0;\n    // Divide `count_needed` into two parts for the children.\n    int num_left_child = count_needed / 2;\n    int num_right_child = count_needed - num_left_child;\n\n    // Split along the larger dimension to keep rectangles somewhat square-like.\n    if (total_width >= total_height) { // Split vertically\n        // Calculate the split point `mid_x` such that the resulting child areas are proportional\n        // to the number of rectangles they will hold.\n        long long mid_x = x0 + total_width * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, mid_x, y1, num_left_child, rect_idx);\n        generate_recursive_helper(rects, mid_x, y0, x1, y1, num_right_child, rect_idx);\n    } else { // Split horizontally\n        long long mid_y = y0 + total_height * num_left_child / count_needed;\n        generate_recursive_helper(rects, x0, y0, x1, mid_y, num_left_child, rect_idx);\n        generate_recursive_helper(rects, x0, mid_y, x1, y1, num_right_child, rect_idx);\n    }\n}\n\n// Helper to generate a p x q grid of rectangles, ensuring exactly N rectangles are created.\n// If `rows * cols < N`, it subdivides existing rectangles until N are generated.\nvoid generate_grid_structure(vector<Rect>& rects, int rows, int cols, int& rect_idx) {\n    if (rows <= 0 || cols <= 0) return; // Ensure valid grid dimensions.\n    \n    long long total_width = W;\n    long long total_height = W;\n\n    // Calculate width for each column, distributing any remainder pixels.\n    vector<long long> col_widths(cols);\n    long long base_w = total_width / cols;\n    long long remainder_w = total_width % cols;\n    for (int j = 0; j < cols; ++j) {\n        col_widths[j] = base_w + (j < remainder_w ? 1 : 0);\n    }\n\n    // Calculate height for each row, distributing any remainder pixels.\n    vector<long long> row_heights(rows);\n    long long base_h = total_height / rows;\n    long long remainder_h = total_height % rows;\n    for (int i = 0; i < rows; ++i) {\n        row_heights[i] = base_h + (i < remainder_h ? 1 : 0);\n    }\n\n    int current_y = 0;\n    int rect_count_initially = 0; // Count rectangles generated by initial grid layout.\n    for (int i = 0; i < rows; ++i) {\n        long long h = row_heights[i]; // Height of the current row.\n        int current_x = 0;\n        for (int j = 0; j < cols; ++j) {\n            // Only add rectangles if we haven't reached the target N.\n            // The loop structure naturally generates rows * cols cells.\n            if (rect_count_initially < N) { \n                long long w = col_widths[j]; // Width of the current column.\n                if (w > 0 && h > 0) { // Create rectangle if dimensions are positive.\n                    rects.push_back({current_x, current_y, current_x + (int)w, current_y + (int)h, w * h, rect_idx++});\n                    rect_count_initially++;\n                } else { // If dimensions are zero, add a dummy (should be rare).\n                    rects.push_back({current_x, current_y, current_x, current_y, 0, rect_idx++});\n                    rect_count_initially++;\n                }\n                current_x += w;\n            } else {\n                break; // Stop adding cells if N rectangles have already been generated.\n            }\n        }\n        current_y += h;\n        if (rect_count_initially == N) break; // Stop if N rectangles are generated.\n    }\n    \n    // Subdivision phase: If the initial grid layout produced fewer than N rectangles,\n    // subdivide existing rectangles until N are generated. This ensures no zero-area dummy rectangles.\n    while (rects.size() < static_cast<size_t>(N)) {\n        // Find the largest rectangle that can be subdivided into two valid rectangles.\n        int best_rect_idx_to_subdivide = -1;\n        long long max_subdiv_dim = -1; // Max dimension (width or height) that can be split.\n\n        for(int i = 0; i < rects.size(); ++i) {\n            long long current_w = rects[i].x1 - rects[i].x0;\n            long long current_h = rects[i].y1 - rects[i].y0;\n            // Prefer splitting the largest dimension.\n            if (current_w > 1 && current_w >= max_subdiv_dim) { // Can split vertically\n                max_subdiv_dim = current_w;\n                best_rect_idx_to_subdivide = i;\n            }\n            if (current_h > 1 && current_h >= max_subdiv_dim) { // Can split horizontally\n                max_subdiv_dim = current_h;\n                best_rect_idx_to_subdivide = i;\n            }\n        }\n\n        if (best_rect_idx_to_subdivide != -1) {\n            Rect rect_to_subdivide = rects[best_rect_idx_to_subdivide];\n            // Remove the rectangle to be subdivided.\n            rects.erase(rects.begin() + best_rect_idx_to_subdivide);\n\n            long long sub_w = rect_to_subdivide.x1 - rect_to_subdivide.x0;\n            long long sub_h = rect_to_subdivide.y1 - rect_to_subdivide.y0;\n\n            // Decide split direction: prefer splitting the larger dimension.\n            if (sub_w >= sub_h) { // Split vertically\n                int mid_x = rect_to_subdivide.x0 + sub_w / 2;\n                // Add first part\n                rects.push_back({rect_to_subdivide.x0, rect_to_subdivide.y0, mid_x, rect_to_subdivide.y1, (long long)(mid_x - rect_to_subdivide.x0) * sub_h, rect_idx++});\n                // Add second part\n                rects.push_back({mid_x, rect_to_subdivide.y0, rect_to_subdivide.x1, rect_to_subdivide.y1, (long long)(rect_to_subdivide.x1 - mid_x) * sub_h, rect_idx++});\n            } else { // Split horizontally\n                int mid_y = rect_to_subdivide.y0 + sub_h / 2;\n                // Add first part\n                rects.push_back({rect_to_subdivide.x0, rect_to_subdivide.y0, rect_to_subdivide.x1, mid_y, (long long)sub_w * (mid_y - rect_to_subdivide.y0), rect_idx++});\n                // Add second part\n                rects.push_back({rect_to_subdivide.x0, mid_y, rect_to_subdivide.x1, rect_to_subdivide.y1, (long long)sub_w * (rect_to_subdivide.y1 - mid_y), rect_idx++});\n            }\n        } else {\n            // If no rectangle can be subdivided (e.g., all are 1x1 or similar edge cases)\n            // and rects.size() < N, it means we are in a state where we cannot create N valid rectangles.\n            // This should be extremely rare given W=1000 and N<=50. Break to avoid infinite loop.\n            // The generated output might be invalid if N is not met, but this path is highly unlikely.\n            break; \n        }\n    }\n}\n\n// Generates the list of N Rect objects for a given structure type.\nvector<Rect> generate_rects_for_structure(StructureType type, int num_rects) {\n    vector<Rect> rects;\n    rects.reserve(num_rects); // Reserve space for efficiency.\n    int current_idx = 0; // Tracks the index for each generated rectangle.\n\n    if (type == RECURSIVE_BALANCED) {\n        generate_recursive_helper(rects, 0, 0, W, W, num_rects, current_idx);\n    } else if (type == VERTICAL_STRIPS) {\n        long long base_w = W / num_rects;\n        long long remainder_w = W % num_rects;\n        int current_x = 0;\n        for (int i = 0; i < num_rects; ++i) {\n            long long w = base_w + (i < remainder_w ? 1 : 0);\n            if (w > 0) { // Add rectangle if width is positive.\n                rects.push_back({current_x, 0, current_x + (int)w, (int)W, w * W, current_idx++});\n                current_x += w;\n            } else { // Safeguard for N > W (though constraints say N <= 50, W=1000). Add dummy if width is zero.\n                 rects.push_back({current_x, 0, current_x, (int)W, 0, current_idx++});\n            }\n        }\n    } else if (type == HORIZONTAL_STRIPS) {\n        long long base_h = W / num_rects;\n        long long remainder_h = W % num_rects;\n        int current_y = 0;\n        for (int i = 0; i < num_rects; ++i) {\n            long long h = base_h + (i < remainder_h ? 1 : 0);\n            if (h > 0) { // Add rectangle if height is positive.\n                rects.push_back({0, current_y, (int)W, current_y + (int)h, W * h, current_idx++});\n                current_y += h;\n            } else { // Safeguard for N > W. Add dummy if height is zero.\n                 rects.push_back({0, current_y, (int)W, current_y, 0, current_idx++});\n            }\n        }\n    } else { // Grid types (e.g., 2xN, Nx3).\n        int rows = -1, cols = -1;\n        // Define rows and columns for specific grid types using integer division for cols/rows.\n        if (type == GRID_2xN) { rows = 2; cols = N / 2; }\n        else if (type == GRID_3xN) { rows = 3; cols = N / 3; }\n        else if (type == GRID_4xN) { rows = 4; cols = N / 4; }\n        else if (type == GRID_5xN) { rows = 5; cols = N / 5; }\n        else if (type == GRID_6xN) { rows = 6; cols = N / 6; }\n        else if (type == GRID_Nx2) { rows = N / 2; cols = 2; }\n        else if (type == GRID_Nx3) { rows = N / 3; cols = 3; }\n        else if (type == GRID_Nx4) { rows = N / 4; cols = 4; }\n        else if (type == GRID_Nx5) { rows = N / 5; cols = 5; }\n        else if (type == GRID_Nx6) { rows = N / 6; cols = 6; }\n        \n        // Call grid generator if rows/cols are valid. `generate_grid_structure` handles creating exactly N rects.\n        if (rows > 0 && cols > 0) {\n            generate_grid_structure(rects, rows, cols, current_idx);\n        }\n    }\n\n    // Ensure exactly `num_rects` are generated by padding with dummy rectangles if needed.\n    // This is a final safeguard, but the subdivision logic in generate_grid_structure should prevent zero-area dummies.\n    while (rects.size() < static_cast<size_t>(num_rects)) { \n        rects.push_back({0, 0, 0, 0, 0, current_idx++}); // Add a zero-area dummy rectangle if N is not met.\n    }\n    return rects;\n}\n\n// --- Partition Cost Calculation ---\n\n// Represents partition lines using maps of intervals.\n// `h_lines`: maps row index -> list of [y_start, y_end) intervals for horizontal segments on that row.\n// `v_lines`: maps column index -> list of [x_start, x_end) intervals for vertical segments on that column.\nusing PartitionLines = pair<map<int, vector<pair<int, int>>>, map<int, vector<pair<int, int>>>>;\n\n// Merges overlapping or adjacent intervals in a list. Essential for simplifying partition representations.\nvoid normalize_intervals(vector<pair<int, int>>& intervals) {\n    if (intervals.empty()) return;\n    sort(intervals.begin(), intervals.end()); // Sort intervals by start point.\n    vector<pair<int, int>> merged;\n    merged.push_back(intervals[0]);\n    for (size_t i = 1; i < intervals.size(); ++i) {\n        // If current interval starts before or at the end of the last merged interval, merge them.\n        if (intervals[i].first <= merged.back().second) {\n            merged.back().second = max(merged.back().second, intervals[i].second);\n        } else {\n            merged.push_back(intervals[i]); // Otherwise, start a new merged interval.\n        }\n    }\n    intervals = merged;\n}\n\n// Generates the `PartitionLines` representation from a list of `Rect` objects.\nPartitionLines get_partition_lines(const vector<Rect>& rects) {\n    map<int, vector<pair<int, int>>> h_lines; // Map for horizontal partition segments.\n    map<int, vector<pair<int, int>>> v_lines; // Map for vertical partition segments.\n\n    for (const auto& r : rects) {\n        // Horizontal segments are on grid lines `i` where `1 <= i <= W-1`.\n        // Vertical segments are on grid lines `j` where `1 <= j <= W-1`.\n\n        // Top edge partition at row r.x0 (if it's an interior grid line).\n        if (r.x0 >= 1 && r.x0 <= W - 1 && r.y0 < r.y1) {\n            h_lines[r.x0].push_back({r.y0, r.y1});\n        }\n        // Bottom edge partition at row r.x1 (if it's an interior grid line).\n        if (r.x1 >= 1 && r.x1 <= W - 1 && r.y0 < r.y1) {\n            h_lines[r.x1].push_back({r.y0, r.y1});\n        }\n\n        // Left edge partition at column r.y0 (if it's an interior grid line).\n        if (r.y0 >= 1 && r.y0 <= W - 1 && r.x0 < r.x1) {\n            v_lines[r.y0].push_back({r.x0, r.x1});\n        }\n        // Right edge partition at column r.y1 (if it's an interior grid line).\n        if (r.y1 >= 1 && r.y1 <= W - 1 && r.x0 < r.x1) {\n            v_lines[r.y1].push_back({r.x0, r.x1});\n        }\n    }\n    \n    // Normalize intervals for each row/column to simplify calculations.\n    for (auto& pair : h_lines) normalize_intervals(pair.second);\n    for (auto& pair : v_lines) normalize_intervals(pair.second);\n    \n    return {h_lines, v_lines};\n}\n\n// Helper to get a boolean array representing segment coverage using a sweep-line algorithm.\n// `present` array of size `W_bound` indicates if a segment at index `k` (0 to W_bound-1) is covered.\nvector<bool> get_coverage_array(const vector<pair<int, int>>& intervals, int W_bound) {\n    vector<bool> present(W_bound, false); // Initialize all segments as not present.\n    if (intervals.empty()) return present;\n\n    // Create event points: {coordinate, type (+1 for interval start, -1 for interval end)}.\n    vector<pair<int, int>> events;\n    events.reserve(intervals.size() * 2);\n    for(const auto& interval : intervals) {\n        if (interval.first < interval.second) { // Ensure valid interval [start, end).\n            events.push_back({interval.first, 1});  // Event at start of interval.\n            events.push_back({interval.second, -1}); // Event at end of interval.\n        }\n    }\n    sort(events.begin(), events.end()); // Sort events by coordinate.\n\n    int current_coverage = 0; // Tracks how many intervals cover the current position.\n    int current_pos = 0;      // The current position in the sweep.\n\n    // Process events to determine coverage.\n    for(const auto& event : events) {\n        int pos = event.first;\n        int type = event.second;\n\n        // Fill the `present` array for the segment [current_pos, pos) if it's covered.\n        // Clamp `pos` to `W_bound` to avoid out-of-bounds access.\n        int end_pos = min(pos, W_bound);\n        if (current_coverage > 0) { // If coverage > 0, this range is covered.\n            for (int k = current_pos; k < end_pos; ++k) {\n                present[k] = true;\n            }\n        }\n        current_coverage += type; // Update coverage based on event type.\n        current_pos = pos;        // Move sweep position.\n        if (current_pos >= W_bound) break; // Stop if we've swept past the boundary.\n    }\n    return present;\n}\n\n// Calculates the partition installation/removal cost between two `PartitionLines` configurations.\n// Cost is incurred for each unit segment where the partition state differs.\nlong long calculate_partition_cost(const PartitionLines& p1, const PartitionLines& p2) {\n    long long cost = 0;\n    const auto& H1 = p1.first; const auto& V1 = p1.second;\n    const auto& H2 = p2.first; const auto& V2 = p2.second;\n\n    // Collect all unique row and column indices that have partitions in either configuration.\n    set<int> h_rows, v_cols;\n    for(const auto& pair : H1) h_rows.insert(pair.first);\n    for(const auto& pair : H2) h_rows.insert(pair.first);\n    for(const auto& pair : V1) v_cols.insert(pair.first);\n    for(const auto& pair : V2) v_cols.insert(pair.first);\n\n    // Calculate horizontal cost: iterate through relevant rows.\n    // Horizontal segments exist on grid lines i = 1 to W-1.\n    for (int r : h_rows) {\n        if (r < 1 || r >= W) continue; // Skip rows outside the valid interior partition lines.\n\n        // Get interval lists for this row from both partition configurations. Use empty list if no partitions.\n        const vector<pair<int,int>>& intervals1 = (H1.count(r) ? H1.at(r) : vector<pair<int,int>>{});\n        const vector<pair<int,int>>& intervals2 = (H2.count(r) ? H2.at(r) : vector<pair<int,int>>{});\n        \n        // Get coverage arrays for this row to represent partition presence for each segment.\n        vector<bool> present1 = get_coverage_array(intervals1, W);\n        vector<bool> present2 = get_coverage_array(intervals2, W);\n\n        // Compare segment presence for segments (r,j)-(r,j+1) where j = 0 to W-1.\n        for (int j = 0; j < W; ++j) {\n            if (present1[j] != present2[j]) { // If partition state differs for segment j, increment cost.\n                cost++;\n            }\n        }\n    }\n\n    // Calculate vertical cost: iterate through relevant columns.\n    // Vertical segments exist on grid lines j = 1 to W-1.\n    for (int c : v_cols) {\n        if (c < 1 || c >= W) continue; // Skip columns outside the valid interior partition lines.\n\n        // Get interval lists for this column from both partition configurations.\n        const vector<pair<int,int>>& intervals1 = (V1.count(c) ? V1.at(c) : vector<pair<int,int>>{});\n        const vector<pair<int,int>>& intervals2 = (V2.count(c) ? V2.at(c) : vector<pair<int,int>>{});\n        \n        // Get coverage arrays for this column.\n        vector<bool> present1 = get_coverage_array(intervals1, W);\n        vector<bool> present2 = get_coverage_array(intervals2, W);\n\n        // Compare segment presence for segments (i,c)-(i+1,c) where i = 0 to W-1.\n        for (int i = 0; i < W; ++i) {\n            if (present1[i] != present2[i]) { // If partition state differs for segment i, increment cost.\n                cost++;\n            }\n        }\n    }\n    \n    return cost;\n}\n\n// --- Main Logic ---\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> W >> D >> N;\n\n    // Store desired areas for each reservation on each day.\n    // `a_d_k_sorted_by_area[d][i]` will store {area, original_k} for the reservation\n    // that has the i-th largest area on day `d`. This allows for greedy assignment.\n    vector<vector<pair<int, int>>> a_d_k_sorted_by_area(D, vector<pair<int, int>>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> a_d_k_sorted_by_area[d][k].first;\n            a_d_k_sorted_by_area[d][k].second = k; // Store original reservation index.\n        }\n        // Sort reservations for day `d` by area in descending order.\n        sort(a_d_k_sorted_by_area[d].rbegin(), a_d_k_sorted_by_area[d].rend());\n    }\n\n    // --- Generate candidate structures and precompute ---\n    // Using maps for cleaner storage and retrieval of structure-specific data.\n    map<StructureType, vector<Rect>> base_rects_map;\n    map<StructureType, PartitionLines> partition_lines_map;\n    map<StructureType, vector<long long>> area_costs_map; // Stores area costs per day for each structure type.\n\n    // Select a limited set of diverse partition structures to evaluate.\n    active_structure_types.clear();\n    active_structure_types.push_back(RECURSIVE_BALANCED);\n    active_structure_types.push_back(VERTICAL_STRIPS);\n    active_structure_types.push_back(HORIZONTAL_STRIPS);\n\n    // Add grid structures for small p (2 to 6).\n    // We include p x (N/p) and (N/p) x p grids using integer division.\n    // `generate_grid_structure` will then ensure exactly N rectangles are produced, subdividing if necessary.\n    for (int p = 2; p <= 6; ++p) {\n        // p x (N/p) grid type\n        if (active_structure_types.size() < MAX_STRUCTURES) {\n            // Assign to GRID_2xN + (p-2) for p=2..6\n            active_structure_types.push_back(static_cast<StructureType>(StructureType::GRID_2xN + (p - 2)));\n        }\n        // (N/p) x p grid type\n        // Only add if it's different from p x (N/p) aspect ratio AND we have space.\n        if (p != N / p && active_structure_types.size() < MAX_STRUCTURES) {\n            // Assign to GRID_Nx2 + (p-2) for p=2..6\n            active_structure_types.push_back(static_cast<StructureType>(StructureType::GRID_Nx2 + (p - 2)));\n        }\n    }\n    \n    // Trim the list of active structures if it exceeds the predefined MAX_STRUCTURES limit.\n    if (active_structure_types.size() > MAX_STRUCTURES) {\n        active_structure_types.resize(MAX_STRUCTURES);\n    }\n    \n    int num_active_structures = active_structure_types.size(); // Number of structures to evaluate.\n\n    // Precompute data for each selected structure type.\n    for (int i = 0; i < num_active_structures; ++i) {\n        StructureType current_type = active_structure_types[i];\n        \n        // 1. Generate the N base rectangles for this structure.\n        base_rects_map[current_type] = generate_rects_for_structure(current_type, N);\n        // 2. Get the partition line representation for this structure.\n        partition_lines_map[current_type] = get_partition_lines(base_rects_map[current_type]);\n        \n        // 3. Calculate area costs for each day using this structure.\n        area_costs_map[current_type].resize(D);\n        \n        // Sort the base rectangles by area in descending order. This defines the available \"slots\".\n        vector<Rect> sorted_base_rects = base_rects_map[current_type];\n        sort(sorted_base_rects.begin(), sorted_base_rects.end(), [](const Rect& a, const Rect& b) {\n            return a.area > b.area; // Descending order of area.\n        });\n\n        // Calculate area cost for each day by greedily assigning the i-th largest reservation\n        // to the i-th largest base rectangle slot.\n        for (int d = 0; d < D; ++d) {\n            long long current_day_area_cost = 0;\n            for (int res_rank = 0; res_rank < N; ++res_rank) { // Iterate through reservations sorted by area.\n                long long required_area = a_d_k_sorted_by_area[d][res_rank].first;\n                long long assigned_area = sorted_base_rects[res_rank].area;\n                current_day_area_cost += 100LL * max(0LL, required_area - assigned_area);\n            }\n            area_costs_map[current_type][d] = current_day_area_cost;\n        }\n    }\n\n    // Precompute partition costs between all pairs of *active* structure types.\n    // The cost matrix uses indices corresponding to the `active_structure_types` vector (0 to `num_active_structures - 1`).\n    vector<vector<long long>> partition_cost_matrix(num_active_structures, vector<long long>(num_active_structures));\n    for (int i = 0; i < num_active_structures; ++i) {\n        for (int j = 0; j < num_active_structures; ++j) {\n            // Calculate cost to transition from structure active_structure_types[j] to active_structure_types[i].\n            partition_cost_matrix[i][j] = calculate_partition_cost(partition_lines_map[active_structure_types[i]], partition_lines_map[active_structure_types[j]]);\n        }\n    }\n\n    // --- Dynamic Programming to find the optimal sequence of structures ---\n    // DP[d][i]: Minimum total cost up to day 'd', ending with the structure `active_structure_types[i]`.\n    vector<vector<long long>> DP(D, vector<long long>(num_active_structures));\n    // parent[d][i]: Stores the index (in `active_structure_types`) of the structure used on day 'd-1'\n    // that led to the minimum cost DP[d][i]. Used for backtracking the optimal path.\n    vector<vector<int>> parent(D, vector<int>(num_active_structures));\n\n    // Base case: Day 0. The cost is just the area cost for each structure type. No partition cost on day 0.\n    for (int i = 0; i < num_active_structures; ++i) {\n        StructureType current_type = active_structure_types[i];\n        DP[0][i] = area_costs_map[current_type][0]; // Area cost for day 0.\n        parent[0][i] = -1; // Sentinel value indicating the start of the path.\n    }\n\n    // Transitions: Calculate DP values for Day 1 up to Day D-1.\n    for (int d = 1; d < D; ++d) {\n        for (int i = 0; i < num_active_structures; ++i) { // Current structure type index for day 'd'.\n            StructureType curr_s_type = active_structure_types[i];\n            long long min_prev_total_cost = -1;\n            int best_prev_idx = -1; // Index in `active_structure_types` for the best previous structure.\n\n            long long current_day_area_cost = area_costs_map[curr_s_type][d]; // Area cost for current day with current structure.\n\n            // Iterate through all possible previous structure types for day 'd-1'.\n            for (int j = 0; j < num_active_structures; ++j) {\n                long long prev_day_total_cost = DP[d - 1][j]; // Min cost up to day d-1 ending with structure j.\n                long long partition_change_cost = partition_cost_matrix[i][j]; // Cost to transition from structure j to structure i.\n                \n                long long total_cost_through_prev = prev_day_total_cost + current_day_area_cost + partition_change_cost;\n\n                // Update if this path is better.\n                if (best_prev_idx == -1 || total_cost_through_prev < min_prev_total_cost) {\n                    min_prev_total_cost = total_cost_through_prev;\n                    best_prev_idx = j; // Store the index of the optimal previous structure.\n                }\n            }\n            DP[d][i] = min_prev_total_cost;\n            parent[d][i] = best_prev_idx;\n        }\n    }\n\n    // --- Find overall minimum cost and backtrack to determine the optimal structure sequence ---\n    long long min_total_overall_cost = -1;\n    int last_active_idx = -1; // Index in `active_structure_types` for the optimal structure on the last day.\n\n    // Find the minimum cost across all structures on the last day (D-1).\n    for (int i = 0; i < num_active_structures; ++i) {\n        if (last_active_idx == -1 || DP[D - 1][i] < min_total_overall_cost) {\n            min_total_overall_cost = DP[D - 1][i];\n            last_active_idx = i;\n        }\n    }\n\n    // Backtrack using the `parent` array to reconstruct the optimal sequence of structure indices.\n    vector<int> optimal_active_idx_sequence(D);\n    int current_active_idx = last_active_idx;\n    for (int d = D - 1; d >= 0; --d) {\n        optimal_active_idx_sequence[d] = current_active_idx; // Store the optimal structure index for day `d`.\n        if (d > 0) {\n            current_active_idx = parent[d][current_active_idx]; // Move to the parent structure index for the previous day.\n        }\n    }\n\n    // --- Output the rectangles for each day ---\n    // For each day, use the chosen structure and greedily assign reservations to rectangles.\n    for (int d = 0; d < D; ++d) {\n        // Get the chosen structure type for the current day from the optimal sequence.\n        StructureType chosen_s_type = active_structure_types[optimal_active_idx_sequence[d]];\n        const auto& structure_rects = base_rects_map[chosen_s_type]; // Base rectangles for this structure.\n\n        // Sort the base rectangles of the chosen structure by area in descending order.\n        vector<Rect> sorted_base_rects = structure_rects;\n        sort(sorted_base_rects.begin(), sorted_base_rects.end(), [](const Rect& a, const Rect& b) {\n            return a.area > b.area; // Descending order of area.\n        });\n\n        // Get the reservations for day 'd', already sorted by desired area (descending).\n        const auto& daily_reservations_sorted = a_d_k_sorted_by_area[d]; \n\n        // Determine the final assignment of rectangles for day 'd'.\n        // `current_day_assignments[k]` will store the `Rect` assigned to the original reservation `k`.\n        vector<Rect> current_day_assignments(N); \n        for (int res_rank = 0; res_rank < N; ++res_rank) { // `res_rank` is the rank by area (0 = largest).\n            int original_reservation_k = daily_reservations_sorted[res_rank].second; // Original index of this reservation.\n            \n            // Greedily assign: the `res_rank`-th largest reservation gets the `res_rank`-th largest base rectangle slot.\n            current_day_assignments[original_reservation_k] = sorted_base_rects[res_rank];\n        }\n\n        // Output the assigned rectangles for day 'd' in the order of original reservations (k=0 to N-1).\n        for (int k = 0; k < N; ++k) {\n            const Rect& r = current_day_assignments[k];\n            // Ensure output rectangle is valid. This check is defensive against potential bugs.\n            // The subdivision logic in `generate_grid_structure` should prevent 0-area rects.\n            if (r.x0 >= r.x1 || r.y0 >= r.y1) {\n                // This indicates a problem. In a contest, this might lead to WA.\n                // For debugging, one could print an error or a minimal valid rectangle.\n                // Given the problem context and W=1000, N<=50, a 1x1 rect is always possible.\n                // For submission, we assume the subdivision logic works.\n                // The previous error `0 0 0 0` was due to dummy rects. This is now handled.\n                // If this specific case occurs again, a more complex structure generation strategy is needed.\n            }\n            cout << r.x0 << \" \" << r.y0 << \" \" << r.x1 << \" \" << r.y1 << \"\\n\";\n        }\n    }\n\n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <tuple>\n#include <algorithm>\n#include <queue>\n\nusing namespace std;\n\n// Global constants and variables for the problem.\n// N, M, K are small enough that long long is not strictly necessary for them,\n// but using it for consistency and to avoid potential issues with larger constraints.\nlong long N_val, M_val, K_val; \nconst long long MOD = 998244353; // The modulus for scoring.\n\n// Structure to hold a state in the beam search.\n// A state includes the current board configuration, the sequence of operations to reach it,\n// and its total score.\nstruct State {\n    vector<vector<long long>> board; // The board configuration for this state.\n    vector<tuple<int, int, int>> operations; // The sequence of operations to reach this state.\n    long long current_score; // The score of this state (sum of board[i][j] % MOD).\n\n    // Operator for comparison in a priority queue.\n    // We want states with higher scores to have higher priority.\n    // std::priority_queue is a max-heap by default, so it will keep the element with the largest value\n    // (based on this operator) at the top.\n    bool operator<(const State& other) const {\n        return current_score < other.current_score;\n    }\n};\n\n/**\n * @brief Calculates the immediate score gain by applying a specific stamp at a given position on a given board.\n * \n * The gain is the sum of (new_cell_value % MOD - old_cell_value % MOD) for all affected cells.\n * This value can be positive, zero, or negative. Only positive gains are considered for extending the search.\n * \n * @param current_board The current board state.\n * @param stamp_idx The index of the stamp to consider (0 to M-1).\n * @param p The top row coordinate on the board where the stamp's (0,0) is placed.\n * @param q The left column coordinate on the board where the stamp's (0,0) is placed.\n * @param stamps The collection of all stamps.\n * @return The total score gain (sum of modulo differences) for this operation.\n */\nlong long calculate_gain_for_state(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    long long current_gain_sum = 0; // Accumulates the score change.\n    \n    // Iterate over the 3x3 squares of the stamp.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            int r = p + i; // Corresponding row on the board.\n            int c = q + j; // Corresponding column on the board.\n\n            // The current score contribution of the cell (r, c) to the total score.\n            // Since input values are non-negative, direct modulo is sufficient.\n            long long current_score_contrib = current_board[r][c] % MOD;\n            \n            // The value from the stamp at relative position (i, j).\n            long long stamp_val = stamps[stamp_idx][i][j];\n            \n            // The new total value on the board cell (r, c) after applying the stamp.\n            long long new_board_val = current_board[r][c] + stamp_val;\n            \n            // The new score contribution of the cell (r, c) after the operation.\n            long long new_score_contrib = new_board_val % MOD;\n            \n            // The change in score for this specific cell.\n            long long delta = new_score_contrib - current_score_contrib;\n            \n            current_gain_sum += delta; // Add the cell's score change to the total gain.\n        }\n    }\n    return current_gain_sum;\n}\n\n/**\n * @brief Applies a stamp to a board and returns the new board state.\n * \n * This function creates a copy of the board and applies the stamp values to it.\n * \n * @param current_board The board to apply the stamp to.\n * @param stamp_idx The index of the stamp to apply.\n * @param p The top row coordinate for placement.\n * @param q The left column coordinate for placement.\n * @param stamps The collection of all stamps.\n * @return A new board with the stamp applied.\n */\nvector<vector<long long>> apply_stamp_to_board(const vector<vector<long long>>& current_board, int stamp_idx, int p, int q, const vector<vector<vector<long long>>>& stamps) {\n    vector<vector<long long>> next_board = current_board; // Copy the board to avoid modifying the original state.\n    for (int i = 0; i < 3; ++i) {\n        for (int j = 0; j < 3; ++j) {\n            next_board[p + i][q + j] += stamps[stamp_idx][i][j];\n        }\n    }\n    return next_board;\n}\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read board dimensions (N) and number of stamps (M), and max operations (K).\n    cin >> N_val >> M_val >> K_val;\n\n    // Initialize the board with the given initial values and calculate initial score.\n    vector<vector<long long>> initial_board(N_val, vector<long long>(N_val));\n    long long initial_score = 0;\n    for (int i = 0; i < N_val; ++i) {\n        for (int j = 0; j < N_val; ++j) {\n            cin >> initial_board[i][j];\n            // Calculate initial score: sum of (value % MOD).\n            initial_score = (initial_score + (initial_board[i][j] % MOD)) % MOD;\n        }\n    }\n\n    // Read the values for all M stamps.\n    vector<vector<vector<long long>>> stamps(M_val, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M_val; ++m) {\n        for (int i = 0; i < 3; ++i) {\n            for (int j = 0; j < 3; ++j) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n\n    // --- Beam Search Strategy ---\n    // Beam search explores multiple promising states simultaneously to escape local optima.\n    // BEAM_WIDTH determines how many of the best states are kept at each step.\n    // Adjusted BEAM_WIDTH to 7. This value often provides a good balance between exploration\n    // and computational cost, aiming for more consistent score improvements.\n    const int BEAM_WIDTH = 7; \n    \n    // Priority queue to store states for the current step. `std::priority_queue` is a max-heap by default,\n    // so states with higher scores will be at the top.\n    priority_queue<State> pq;\n\n    // Create the initial state and push it into the priority queue.\n    State initial_state;\n    initial_state.board = initial_board;\n    initial_state.current_score = initial_score;\n    pq.push(initial_state);\n\n    // Track the best overall state found throughout the search.\n    State best_overall_state = initial_state;\n\n    // Perform beam search for up to K_val steps. Each step represents applying one more operation.\n    for (int k = 0; k < K_val; ++k) {\n        // Store candidate next states generated from the current step's states.\n        vector<State> candidates;\n\n        // Process up to BEAM_WIDTH states from the current priority queue.\n        // This is the number of states we will expand at this depth.\n        int states_to_process = min((int)pq.size(), BEAM_WIDTH);\n        \n        // If no states are left to process (pq is empty), break the loop.\n        if (states_to_process == 0) break;\n\n        // Expand each of the top 'states_to_process' states.\n        for(int i = 0; i < states_to_process; ++i) {\n            State current_state = pq.top();\n            pq.pop();\n\n            // Explore all possible next operations (stamp type and position) from this state.\n            for (int m = 0; m < M_val; ++m) {\n                for (int p = 0; p <= N_val - 3; ++p) { // Possible top-left row for stamp placement.\n                    for (int q = 0; q <= N_val - 3; ++q) { // Possible top-left column for stamp placement.\n                        \n                        // Calculate the immediate score gain from this potential operation.\n                        long long gain = calculate_gain_for_state(current_state.board, m, p, q, stamps);\n\n                        // Only consider operations that strictly increase the score.\n                        // This ensures we always move towards a better score and avoid unnecessary operations.\n                        // If gain is 0 or negative, it doesn't improve the score.\n                        if (gain > 0) {\n                            // Create a new state by applying the operation.\n                            State next_state;\n                            next_state.board = apply_stamp_to_board(current_state.board, m, p, q, stamps);\n                            next_state.operations = current_state.operations; // Copy operations from current state.\n                            next_state.operations.emplace_back(m, p, q); // Add the new operation.\n                            \n                            // Update the score: current score + gain. The gain is already the sum of modulo differences.\n                            // This summation is safe as both current_score and gain fit within long long.\n                            next_state.current_score = current_state.current_score + gain;\n                            \n                            // Add this new state to the list of candidates for the next step.\n                            candidates.push_back(next_state);\n\n                            // Update the best overall state found so far if this new state is better.\n                            // This ensures we keep track of the global best, even if it's not in the current beam.\n                            if (next_state.current_score > best_overall_state.current_score) {\n                                best_overall_state = next_state;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If no operations resulted in a positive gain from any of the processed states,\n        // it means we cannot improve the score further with positive gain operations.\n        // We can stop the search early.\n        if (candidates.empty()) {\n            break;\n        }\n\n        // Sort the generated candidates by their score in descending order.\n        // This is necessary to select the top BEAM_WIDTH candidates for the next iteration.\n        sort(candidates.begin(), candidates.end(), [](const State& a, const State& b){\n            return a.current_score > b.current_score;\n        });\n\n        // Push the top BEAM_WIDTH candidates into the priority queue for the next iteration.\n        // This prunes the search space, keeping only the most promising states for further exploration.\n        for(int i = 0; i < min((int)candidates.size(), BEAM_WIDTH); ++i) {\n            pq.push(candidates[i]);\n        }\n    }\n\n    // --- Output ---\n    // The 'best_overall_state' now holds the sequence of operations that yielded the highest score\n    // found during the beam search.\n    cout << best_overall_state.operations.size() << endl;\n    for (const auto& op : best_overall_state.operations) {\n        cout << get<0>(op) << \" \" << get<1>(op) << \" \" << get<2>(op) << endl;\n    }\n\n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <map>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\n// Maximum number of turns allowed.\nconst int MAX_TURNS = 10000;\nint N;\n\n// Grid state: stores container ID at (row, col), -1 if empty.\nvector<vector<int>> grid; \n// Stores crane ID at (row, col), -1 if empty. Used for collision detection.\nvector<vector<int>> crane_id_at; \n\n// Crane state structure.\nstruct Crane {\n    int id;\n    pair<int, int> pos;\n    int holding_container_id; // -1 if not holding any container.\n    bool is_large;\n    // Base priority for this crane, used to break ties and assign general importance.\n    int base_priority; \n};\nvector<Crane> cranes; // Vector to store all crane objects.\n\n// Receiving Gate state: for each gate i, index into A[i] for the next container to arrive.\nvector<int> receiving_gate_next_container_idx; \n\n// Dispatch Gate state: for each gate i, the ID of the next container expected. -1 if all dispatched.\nvector<int> dispatch_gate_expected_container; \n\n// List of coordinates for temporary storage cells.\nvector<pair<int, int>> temp_storage_cells;\n\n// Global variable to track current turn. Used for special Turn 0 logic.\nint current_turn;\n\n// Helper function to check if a cell (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Helper function to determine the target dispatch gate for a given container ID.\nint get_target_gate(int container_id) {\n    if (container_id < 0) return -1; // Should not happen for valid container IDs.\n    return container_id / N; // Gate i handles containers N*i to N*(i+1)-1.\n}\n\n// Greedy pathfinding: returns the next adjacent cell towards target_pos.\npair<int, int> get_next_step(pair<int, int> current_pos, pair<int, int> target_pos) {\n    if (current_pos == target_pos) return current_pos; // Already at target.\n\n    int r = current_pos.first;\n    int c = current_pos.second;\n    int tr = target_pos.first;\n    int tc = target_pos.second;\n\n    int dr = tr - r;\n    int dc = tc - c;\n\n    // Prioritize movement along the axis with the largest distance.\n    if (abs(dr) >= abs(dc)) { \n        if (dr > 0) return {r + 1, c}; // Move Down\n        else if (dr < 0) return {r - 1, c}; // Move Up\n    }\n    // If vertical distance is not greater, prioritize horizontal movement.\n    if (abs(dc) > abs(dr)) { \n        if (dc > 0) return {r, c + 1}; // Move Right\n        else if (dc < 0) return {r, c - 1}; // Move Left\n    }\n    \n    // Should not be reached if current_pos != target_pos, but as a fallback.\n    return current_pos; \n}\n\n// Enum for different types of tasks a crane can perform, ordered by general importance.\nenum TaskType {\n    WAIT,               // Do nothing.\n    MOVE_AWAY_FROM_REC, // Special task for Turn 0 to move cranes off receiving gates.\n    PICKUP_REC,         // Pick up a container from a Receiving Gate.\n    PICKUP_TEMP,        // Pick up a container from Temporary Storage.\n    STORE_CONTAINER,    // Store a container into Temporary Storage.\n    DELIVER_TO_GATE     // Deliver a container to its Dispatch Gate.\n};\n\n// Structure to represent a crane's determined task and its associated priority.\nstruct CraneTask {\n    TaskType type;\n    pair<int, int> target_pos; // The cell the crane needs to reach or act upon.\n    int priority;              // Higher value indicates higher priority.\n};\n\n// Helper to find an available temporary storage cell for placing a container.\n// A cell is available if it's within temp storage bounds, empty of container, and empty of crane.\npair<int, int> find_available_temp_cell() {\n    for (const auto& cell : temp_storage_cells) {\n        if (grid[cell.first][cell.second] == -1 && crane_id_at[cell.first][cell.second] == -1) {\n            return cell; // Found an available cell.\n        }\n    }\n    return {-1, -1}; // No available cell found.\n}\n\n// Function to determine the highest priority task for a given crane.\nCraneTask determine_crane_task(int crane_idx) {\n    Crane& crane = cranes[crane_idx];\n    pair<int, int> current_pos = crane.pos;\n\n    int current_base_priority = crane.is_large ? 1000 : 100 * (N - 1 - crane_idx); \n\n    // --- Special Handling for Turn 0 ---\n    // Cranes start at (i,0), blocking incoming containers. They must move away.\n    // This condition should only trigger for cranes starting at column 0.\n    if (current_turn == 0 && current_pos.second == 0) { // Check if on the receiving line.\n        // Target is (crane_idx, 1) (move right). This is a safe adjacent cell not on the receiving line.\n        // Note: N is always 5 in this problem, so N > 1 is always true.\n        return {MOVE_AWAY_FROM_REC, {crane_idx, 1}, current_base_priority + 200}; // Very high priority for initial move.\n    }\n\n    // --- Check for storage availability ---\n    pair<int, int> available_temp_cell = find_available_temp_cell();\n    bool temp_storage_available = (available_temp_cell != make_pair(-1, -1));\n\n    // --- Task 5: DELIVER_TO_GATE --- (Highest priority after initial move)\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n        \n        // Check if the container is the next expected one for its dispatch gate.\n        if (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]) {\n            pair<int, int> deliver_pos = {target_gate, N - 1}; // Target is the dispatch gate cell.\n            return {DELIVER_TO_GATE, deliver_pos, current_base_priority + 100}; // High task priority.\n        }\n    }\n\n    // --- Task 3 & 4: PICKUP_REC/TEMP (for required containers) ---\n    // If the crane is empty, it can pick up a container.\n    if (crane.holding_container_id == -1) { \n        // Iterate through all dispatch gates to find the next required container.\n        for (int i = 0; i < N; ++i) { // For each dispatch gate 'i'.\n            int expected_container_id = dispatch_gate_expected_container[i];\n            if (expected_container_id != -1) { // If a container is still expected at this gate.\n                if (get_target_gate(expected_container_id) == i) { // Check if it belongs to gate 'i'.\n                    // Task 3: PICKUP_REC - Check if required container is at its receiving gate.\n                    if (grid[i][0] == expected_container_id) {\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 80}; // High priority.\n                    }\n                    // Task 4: PICKUP_TEMP - Check if required container is in temporary storage.\n                    for (const auto& cell : temp_storage_cells) {\n                        if (grid[cell.first][cell.second] == expected_container_id) {\n                            return {PICKUP_TEMP, cell, current_base_priority + 70}; // High priority.\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // --- Task 2: STORE_CONTAINER ---\n    // If holding a non-critical container AND temp storage is available.\n    if (crane.holding_container_id != -1) {\n        int container_id = crane.holding_container_id;\n        int target_gate = get_target_gate(container_id);\n\n        // Check if the container is NOT needed right now for its target dispatch gate.\n        bool is_needed_now = (target_gate >= 0 && target_gate < N && dispatch_gate_expected_container[target_gate] != -1 && container_id == dispatch_gate_expected_container[target_gate]);\n        \n        if (!is_needed_now && temp_storage_available) { \n            return {STORE_CONTAINER, available_temp_cell, current_base_priority + 50}; // Medium priority.\n        }\n    }\n    \n    // --- Task 1: Proactive PICKUP_REC ---\n    // If crane is empty AND temp storage is available.\n    if (crane.holding_container_id == -1) { \n        if (temp_storage_available) { \n            for (int i = 0; i < N; ++i) { // Iterate through receiving gates.\n                if (receiving_gate_next_container_idx[i] < N) { // If containers are still arriving at gate i.\n                    // If the receiving gate cell (i,0) has a container and no crane is currently there.\n                    if (grid[i][0] != -1 && crane_id_at[i][0] == -1) {\n                        return {PICKUP_REC, {i, 0}, current_base_priority + 20}; // Low priority proactive pickup.\n                    }\n                }\n            }\n        }\n    }\n\n    // --- Task 0: WAIT ---\n    // Default task if no other task can be performed.\n    return {WAIT, current_pos, current_base_priority}; \n}\n\n// Structure to represent a crane's requested move for conflict resolution.\nstruct MoveRequest {\n    int crane_idx;\n    TaskType task_kind;        // The type of task requested.\n    pair<int, int> target_pos; // The intended destination cell or target cell for action.\n    int priority;              // The calculated priority for this request.\n\n    // Operator for sorting: higher priority requests come first.\n    // If priorities are equal, sort by crane_idx to ensure deterministic behavior.\n    bool operator<(const MoveRequest& other) const {\n        if (priority != other.priority) {\n            return priority > other.priority; // Sort descending by priority.\n        }\n        return crane_idx < other.crane_idx; // Sort ascending by crane index for ties.\n    }\n};\n\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    cin >> N;\n\n    // Initialize grid and crane_id_at to represent empty state.\n    grid.assign(N, vector<int>(N, -1));\n    crane_id_at.assign(N, vector<int>(N, -1));\n    \n    // Store input container sequence A.\n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> A[i][j];\n        }\n    }\n\n    // Initialize data structures.\n    receiving_gate_next_container_idx.assign(N, 0);\n    dispatch_gate_expected_container.assign(N, -1); \n\n    // Set the initial expected container for each dispatch gate.\n    for (int i = 0; i < N; ++i) {\n        dispatch_gate_expected_container[i] = N * i;\n    }\n\n    // Initialize cranes: one large crane at (0,0), N-1 small cranes at (i,0).\n    cranes.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cranes[i].id = i;\n        cranes[i].pos = {i, 0}; // Initial position on receiving gate row.\n        cranes[i].holding_container_id = -1;\n        cranes[i].is_large = (i == 0);\n        // Set base priorities. Large crane highest, small cranes ordered.\n        cranes[i].base_priority = (i == 0) ? 1000 : 100 * (N - 1 - i); \n\n        crane_id_at[i][0] = i; // Mark the initial position of each crane on the grid.\n    }\n\n    // Initialize temporary storage cells.\n    // Any cell (r, c) where c < N-1 can be used as temporary storage.\n    temp_storage_cells.clear(); \n    for (int r = 0; r < N; ++r) {\n        for (int c = 0; c < N - 1; ++c) { // Columns 0 to N-2 are valid for temp storage.\n            temp_storage_cells.push_back({r, c});\n        }\n    }\n    // Sort them for deterministic behavior.\n    sort(temp_storage_cells.begin(), temp_storage_cells.end());\n\n    vector<string> output_ops(N, \"\"); // Stores the operation sequence for each crane.\n\n    // Main simulation loop for each turn.\n    for (current_turn = 0; current_turn < MAX_TURNS; ++current_turn) {\n        \n        // --- Step 1: Container Arrival ---\n        for (int i = 0; i < N; ++i) { // For each receiving gate row i.\n            if (receiving_gate_next_container_idx[i] < N) { // If there are more containers to arrive for this gate.\n                // Check if the receiving gate cell (i,0) is empty (no container, no crane).\n                if (grid[i][0] == -1 && crane_id_at[i][0] == -1) {\n                    int container_id = A[i][receiving_gate_next_container_idx[i]]; \n                    grid[i][0] = container_id; \n                    receiving_gate_next_container_idx[i]++; \n                }\n            }\n        }\n\n        // --- Step 2: Crane Actions ---\n        vector<MoveRequest> requests; // List to hold all crane movement/action requests for this turn.\n        \n        // Determine the highest priority task for each crane.\n        for (int i = 0; i < N; ++i) {\n            CraneTask task = determine_crane_task(i);\n            requests.push_back({i, task.type, task.target_pos, task.priority});\n        }\n\n        // Sort requests by priority.\n        sort(requests.begin(), requests.end());\n\n        // `next_crane_id_at` stores crane positions AFTER all actions in this turn are resolved.\n        vector<vector<int>> next_crane_id_at = crane_id_at; \n        \n        // State variables to record the final outcome of each crane's action for this turn.\n        vector<pair<int, int>> final_crane_pos(N);          \n        vector<int> final_crane_holding(N);                 \n        vector<char> final_crane_action(N);                 \n        vector<bool> crane_action_committed(N, false);      \n\n        // Initialize final states assuming cranes do nothing.\n        for(int i=0; i<N; ++i) {\n            final_crane_pos[i] = cranes[i].pos;\n            final_crane_holding[i] = cranes[i].holding_container_id;\n            final_crane_action[i] = '.';\n        }\n\n        // Process requests in priority order to resolve conflicts.\n        for (const auto& req : requests) {\n            int k = req.crane_idx; // Current crane index.\n\n            if (crane_action_committed[k]) continue; // Skip if already committed.\n\n            Crane& current_crane_state = cranes[k]; // Reference to the actual crane object.\n            pair<int, int> current_pos = current_crane_state.pos; // Crane's position at the START of this turn.\n            \n            pair<int, int> intended_next_pos = current_pos;\n            char intended_action_char = '.';\n            bool action_possible = true; \n\n            // Determine intended action and movement based on the highest priority task found.\n            if (req.task_kind == MOVE_AWAY_FROM_REC) {\n                intended_next_pos = req.target_pos; // Target is set by determine_crane_task.\n                intended_action_char = 'R'; // Always move Right for this task.\n            } else if (req.task_kind == DELIVER_TO_GATE || req.task_kind == STORE_CONTAINER) {\n                if (current_pos == req.target_pos) { // Already at target for action.\n                    intended_action_char = 'Q';\n                    intended_next_pos = current_pos; // Stay put to perform 'Q'.\n                } else { // Need to move towards target.\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move towards target (e.g., already there, or blocked by pathing logic).\n                        intended_action_char = '.'; intended_next_pos = current_pos; \n                    }\n                }\n            } else if (req.task_kind == PICKUP_REC || req.task_kind == PICKUP_TEMP) {\n                if (current_pos == req.target_pos) { // Already at target for 'P'.\n                    intended_action_char = 'P';\n                    intended_next_pos = current_pos; // Stay put to perform 'P'.\n                } else { // Need to move towards target.\n                    intended_next_pos = get_next_step(current_pos, req.target_pos);\n                    if (intended_next_pos.first > current_pos.first) intended_action_char = 'D';\n                    else if (intended_next_pos.first < current_pos.first) intended_action_char = 'U';\n                    else if (intended_next_pos.second > current_pos.second) intended_action_char = 'R';\n                    else if (intended_next_pos.second < current_pos.second) intended_action_char = 'L';\n                    else { // Cannot move.\n                        intended_action_char = '.'; intended_next_pos = current_pos; \n                    }\n                }\n            } else { // WAIT task.\n                // Simplified WAIT: Crane does nothing but wait.\n                intended_action_char = '.'; \n                intended_next_pos = current_pos;\n            }\n\n            // --- Collision and Constraint Checking ---\n            \n            // 1. Check if intended destination is valid.\n            if (!is_valid(intended_next_pos.first, intended_next_pos.second)) {\n                action_possible = false; \n            }\n\n            // 2. Check for crane-crane conflict at the intended destination cell.\n            // If moving to a new cell, check if it's occupied by another crane (which has higher priority and already committed).\n            if (action_possible && intended_next_pos != current_pos) { \n                if (next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; // Destination occupied by higher priority crane.\n                }\n            }\n            \n            // 3. Small crane carrying container restriction.\n            if (action_possible && !current_crane_state.is_large && current_crane_state.holding_container_id != -1) {\n                // If carrying and moving to a cell with a container.\n                if (grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; \n                }\n            }\n            \n            // 4. Action-specific cell validity (for 'P' and 'Q').\n            if (action_possible && (intended_action_char == 'P' || intended_action_char == 'Q')) {\n                // For 'P': cell must have a container.\n                if (intended_action_char == 'P' && grid[current_pos.first][current_pos.second] == -1) {\n                    action_possible = false; \n                }\n                // For 'Q': destination cell must be empty of containers.\n                if (intended_action_char == 'Q' && grid[intended_next_pos.first][intended_next_pos.second] != -1) {\n                    action_possible = false; \n                }\n                // Check if destination cell is occupied by another crane.\n                if (next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != -1 && next_crane_id_at[intended_next_pos.first][intended_next_pos.second] != k) {\n                     action_possible = false; \n                }\n            }\n\n            // If all checks pass, the action is possible.\n            if (action_possible) {\n                final_crane_action[k] = intended_action_char; // Record the action.\n                final_crane_pos[k] = intended_next_pos;     // Update crane's position.\n                crane_action_committed[k] = true;           // Mark as committed.\n\n                // Update container holding status and grid state if 'P' or 'Q' was performed.\n                if (intended_action_char == 'P') {\n                    int container_id = grid[current_pos.first][current_pos.second]; \n                    grid[current_pos.first][current_pos.second] = -1; // Remove container from grid cell.\n                    final_crane_holding[k] = container_id; // Crane now holds it.\n                } else if (intended_action_char == 'Q') {\n                    int container_id = current_crane_state.holding_container_id; \n                    grid[intended_next_pos.first][intended_next_pos.second] = container_id; // Place container in destination cell.\n                    final_crane_holding[k] = -1; // Crane no longer holds it.\n                }\n                \n                // Update `next_crane_id_at` for collision detection by lower-priority cranes.\n                if (current_pos != intended_next_pos) { // If the crane actually moved.\n                    next_crane_id_at[current_pos.first][current_pos.second] = -1; // Old cell is now empty of this crane.\n                    next_crane_id_at[intended_next_pos.first][intended_next_pos.second] = k; // New cell is occupied by this crane.\n                }\n            } else {\n                // If action is not possible, the crane stays put and performs no action.\n                final_crane_action[k] = '.'; // Action is '.'.\n                final_crane_pos[k] = current_pos; // Position remains unchanged.\n                final_crane_holding[k] = current_crane_state.holding_container_id; // Holding status unchanged.\n            }\n        }\n        \n        // Apply the finalized states for all cranes after conflict resolution.\n        for(int i=0; i<N; ++i) {\n            cranes[i].pos = final_crane_pos[i];\n            cranes[i].holding_container_id = final_crane_holding[i];\n            output_ops[i] += final_crane_action[i]; // Append action to output string.\n        }\n        // Update the master `crane_id_at` grid for the start of the next turn.\n        crane_id_at = next_crane_id_at; \n\n        // --- Step 3: Dispatch ---\n        for (int i = 0; i < N; ++i) { // For each dispatch gate row i.\n            if (dispatch_gate_expected_container[i] != -1 && grid[i][N - 1] != -1) { // If gate expects a container and has one.\n                if (grid[i][N - 1] == dispatch_gate_expected_container[i]) { // If the container is the correct one.\n                    grid[i][N - 1] = -1; // Remove container from the grid.\n                    \n                    dispatch_gate_expected_container[i]++; // Update expected container.\n                    if (dispatch_gate_expected_container[i] >= N * (i + 1)) {\n                        dispatch_gate_expected_container[i] = -1; // All dispatched for this gate.\n                    }\n                }\n            }\n        }\n        \n        // Early exit condition if all containers are dispatched.\n        bool all_dispatched = true;\n        for(int i=0; i<N; ++i) {\n            if (dispatch_gate_expected_container[i] != -1) {\n                all_dispatched = false;\n                break;\n            }\n        }\n        // CORRECTED: Use the globally declared `current_turn` variable.\n        if (all_dispatched && current_turn > 0) { // Check if all were dispatched in this turn or previous.\n             break; // Exit if all containers have been dispatched.\n        }\n    }\n\n    // Pad all output strings with '.' to ensure they all have length MAX_TURNS.\n    for (int i = 0; i < N; ++i) {\n        while (output_ops[i].length() < MAX_TURNS) {\n            output_ops[i] += '.';\n        }\n    }\n\n    // Print the operation sequences for each crane.\n    for (int i = 0; i < N; ++i) {\n        cout << output_ops[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <string>\n#include <numeric>\n#include <algorithm>\n#include <vector> // Explicitly include vector\n\nusing namespace std;\n\nint N;\n// current_height: Stores the remaining height of soil in each grid cell.\n// This grid is modified as soil is loaded onto the truck or unloaded from it.\nvector<vector<int>> current_height;\n// current_pos: Stores the (row, column) coordinates of the dump truck.\npair<int, int> current_pos;\n// truck_load: Stores the current amount of soil loaded onto the dump truck.\nlong long truck_load;\n// operations: A list to store the sequence of commands to be output.\nvector<string> operations;\n\n// CHUNK_SIZE: Defines the maximum amount of soil transferred in a single load or unload operation.\n// We'll use a moderate value (20). The key is how it's applied in an interleaved strategy.\nconst long long CHUNK_SIZE = 20; \n\n// Adds a given operation string to the `operations` list.\nvoid add_op(const string& op) {\n    operations.push_back(op);\n}\n\n// Adds a load ('+') or unload ('-') operation.\n// 'd' is the amount of soil transferred. Ensures d > 0 as per problem statement.\nvoid add_load_unload(char type, long long d) {\n    if (d <= 0) return; // Do not add operations with zero or negative amount.\n    add_op(string(1, type) + to_string(d));\n}\n\n// Moves the dump truck from its `current_pos` to the target cell (`target_r`, `target_c`).\n// It appends the necessary 'U', 'D', 'L', 'R' operations to the `operations` list\n// and updates `current_pos`. This function is crucial for calculating movement cost.\nvoid move_to(int target_r, int target_c) {\n    // Vertical movement: Up or Down\n    while (current_pos.first < target_r) {\n        add_op(\"D\");\n        current_pos.first++;\n    }\n    while (current_pos.first > target_r) {\n        add_op(\"U\");\n        current_pos.first--;\n    }\n    // Horizontal movement: Left or Right\n    while (current_pos.second < target_c) {\n        add_op(\"R\");\n        current_pos.second++;\n    }\n    while (current_pos.second > target_c) {\n        add_op(\"L\");\n        current_pos.second--;\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster input/output.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read the grid size N.\n    cin >> N;\n\n    // Initialize the current_height grid with input values.\n    current_height.resize(N, vector<int>(N));\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            cin >> current_height[i][j];\n        }\n    }\n\n    // Initialize the truck's starting position and load.\n    current_pos = {0, 0};\n    truck_load = 0;\n\n    // Define a snake-like traversal path. This path visits every cell exactly once\n    // in a systematic manner (row by row, alternating direction).\n    vector<pair<int, int>> snake_path;\n    snake_path.reserve(N * N); // Reserve memory for efficiency.\n    for (int r = 0; r < N; ++r) {\n        if (r % 2 == 0) { // Even rows: traverse left to right.\n            for (int c = 0; c < N; ++c) {\n                snake_path.push_back({r, c});\n            }\n        } else { // Odd rows: traverse right to left.\n            for (int c = N - 1; c >= 0; --c) {\n                snake_path.push_back({r, c});\n            }\n        }\n    }\n\n    // --- Single Pass: Interleaved Loading and Unloading Strategy ---\n    // Iterate through the snake path. For each cell, perform both loading (if positive height)\n    // and unloading (if negative height and truck has load). This aims to keep the truck's\n    // load `d` as low as possible during movements, thereby reducing the `100+d` move cost.\n    for (const auto& pos_pair : snake_path) {\n        int r = pos_pair.first;\n        int c = pos_pair.second;\n\n        // Move the truck to the current cell. The cost of this move depends on `truck_load`\n        // *before* operations at this cell. Interleaving aims to reduce this `truck_load`.\n        move_to(r, c);\n\n        // --- Perform operations at the current cell ---\n\n        // 1. Load soil if the cell has positive height.\n        // Load soil in chunks up to CHUNK_SIZE until the cell's height becomes 0.\n        // This loop might execute multiple load operations at the same cell without movement.\n        while (current_height[r][c] > 0) {\n            // Determine the amount to load: minimum of remaining height in cell and CHUNK_SIZE.\n            long long amount_to_load = min((long long)current_height[r][c], CHUNK_SIZE);\n            add_load_unload('+', amount_to_load); // Add load operation.\n            truck_load += amount_to_load;          // Update truck's current load.\n            current_height[r][c] -= amount_to_load; // Decrease cell's height.\n        }\n\n        // 2. Unload soil if the cell has negative height AND the truck has soil to unload.\n        // Unload soil in chunks up to CHUNK_SIZE until the cell's height becomes 0\n        // or the truck becomes empty. This happens immediately after potential loading,\n        // or if there was already soil on the truck from previous cells.\n        while (current_height[r][c] < 0 && truck_load > 0) {\n            long long needed = -current_height[r][c]; // Amount of soil this cell requires.\n            // Determine amount to unload: minimum of needed soil, current truck load, and CHUNK_SIZE.\n            long long amount_to_unload = min({needed, truck_load, CHUNK_SIZE});\n            add_load_unload('-', amount_to_unload); // Add unload operation.\n            truck_load -= amount_to_unload;        // Update truck's current load.\n            current_height[r][c] += amount_to_unload; // Increase cell's height.\n        }\n    }\n    \n    // The problem guarantees that the sum of initial heights is 0.\n    // Therefore, by visiting all cells and performing the interleaved loading/unloading,\n    // all soil collected from positive-height cells must have been distributed to\n    // negative-height cells. As a result, at the end of this single pass,\n    // all `current_height` values should be 0, and `truck_load` should also be 0.\n    // No additional cleanup passes are needed if the logic is correct.\n\n    // Output all the generated operations, one per line.\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <numeric> // Not strictly necessary as sum is manual, but good practice to include if using numeric algorithms.\n#include <algorithm> // For std::sort\n\n// Use long long for sums to avoid potential overflow.\n// With M=15 and max value 100 per component, the max sum for a single seed is 15*100 = 1500,\n// which fits in a 32-bit integer. However, using `long long` is safer practice and has no performance penalty here.\nusing ll = long long;\n\n// Structure to hold seed information: its identifier, evaluation vector, and sum of values.\nstruct Seed {\n    int id; // Identifier of the seed within the current generation (0 to seed_count-1).\n    std::vector<int> evaluation_vector;\n    ll sum_v;\n\n    // Custom comparison operator for sorting seeds by sum_v in descending order.\n    // std::sort uses operator< to sort in ascending order. By defining it such that\n    // `a < b` if `a.sum_v > b.sum_v`, we achieve descending order sorting.\n    bool operator<(const Seed& other) const {\n        return sum_v > other.sum_v;\n    }\n};\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    // Disables synchronization with C stdio and unties cin from cout for faster I/O.\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N, M, T;\n    std::cin >> N >> M >> T;\n\n    // Total number of seeds in each generation.\n    // For N=6, this is 2 * 6 * (6 - 1) = 2 * 6 * 5 = 60 seeds.\n    int seed_count = 2 * N * (N - 1);\n\n    // Vector to hold the current generation of seeds.\n    std::vector<Seed> current_seeds(seed_count);\n\n    // Read initial seeds. Their initial indices are implicitly 0, 1, ..., seed_count-1.\n    for (int i = 0; i < seed_count; ++i) {\n        current_seeds[i].id = i; // Assign initial ID for this seed.\n        current_seeds[i].evaluation_vector.resize(M);\n        ll current_sum = 0;\n        for (int j = 0; j < M; ++j) {\n            std::cin >> current_seeds[i].evaluation_vector[j];\n            current_sum += current_seeds[i].evaluation_vector[j];\n        }\n        current_seeds[i].sum_v = current_sum;\n    }\n\n    // Main loop for T turns of the operation.\n    for (int t = 0; t < T; ++t) {\n        // 1. Sort the current seeds based on their sum_v in descending order.\n        // The `std::sort` function uses the `operator<` defined in the `Seed` struct.\n        std::sort(current_seeds.begin(), current_seeds.end());\n\n        // 2. Select the top N*N seeds for planting.\n        // These are the first N*N seeds in the sorted `current_seeds` vector.\n        // We need to output their `id`s arranged in the N*N grid.\n        std::vector<std::vector<int>> A(N, std::vector<int>(N));\n        \n        // Assign selected seeds to grid cells in row-major order.\n        // The seed placed at A[i][j] is the (i*N + j)-th best seed from the sorted list.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                // `current_seeds[i * N + j]` refers to the Seed struct which is the (i*N + j)-th best.\n                // Its `id` field holds the identifier of this seed within the current generation.\n                A[i][j] = current_seeds[i * N + j].id;\n            }\n        }\n\n        // 3. Output the grid assignment to standard output.\n        for (int i = 0; i < N; ++i) {\n            for (int j = 0; j < N; ++j) {\n                std::cout << A[i][j] << (j == N - 1 ? \"\" : \" \"); // Space separated values, no space after last element in a row.\n            }\n            std::cout << std::endl; // Newline after each row.\n        }\n        std::cout.flush(); // Ensure the output is sent immediately to the judge.\n\n        // 4. Read the evaluation vectors of the newly generated seeds for the next generation.\n        std::vector<Seed> next_seeds(seed_count);\n        for (int i = 0; i < seed_count; ++i) {\n            // Assign new sequential IDs (0 to seed_count-1) for the seeds in the next generation.\n            next_seeds[i].id = i; \n            next_seeds[i].evaluation_vector.resize(M);\n            ll current_sum = 0;\n            for (int j = 0; j < M; ++j) {\n                std::cin >> next_seeds[i].evaluation_vector[j];\n                current_sum += next_seeds[i].evaluation_vector[j];\n            }\n            next_seeds[i].sum_v = current_sum;\n        }\n\n        // 5. Replace the current seeds with the newly generated ones.\n        // `std::move` is used for efficiency, as it transfers ownership of the\n        // `next_seeds` vector's internal buffer to `current_seeds` without copying elements.\n        current_seeds = std::move(next_seeds);\n    }\n\n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <string>\n#include <cmath>\n#include <algorithm>\n#include <tuple>\n#include <map>\n#include <numeric> // For std::iota\n\n// Global variables for grid and arm parameters\nint N_GRID, M_TAKOYAKI, V_ARM;\n\n// Structure for 2D points\nstruct Point {\n    int r, c;\n    // Equality operators for comparisons\n    bool operator==(const Point& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n};\n\n// Manhattan distance for grid movement cost\nint manhattan_distance(Point p1, Point p2) {\n    return std::abs(p1.r - p2.r) + std::abs(p1.c - p2.c);\n}\n\n// --- Arm Design Parameters ---\nint V_prime; // Actual number of vertices in the arm (<= V_ARM)\nstd::vector<int> parent_map; // parent_map[i] is parent of vertex i+1 (0-indexed for edge array)\nstd::vector<int> edge_lengths; // edge_lengths[i] is length of edge connected to vertex i+1\nstd::vector<int> edge_orientations; // Current orientation of edges: 0:R(0,+1), 1:D(+1,0), 2:L(0,-1), 3:U(-1,0)\n\nPoint root_pos; // Current position of the arm's root\nstd::vector<Point> vertex_pos; // Stores current positions of all arm vertices\nstd::vector<int> fingertip_vertex_ids; // Vertex IDs that are fingertips\nstd::vector<int> joint_vertex_ids; // Vertex IDs that are joints (internal nodes, can rotate subtrees)\n\n// Direction vectors for R, D, L, U\nint dr[] = {0, 1, 0, -1}; // Corresponds to orientations 0, 1, 2, 3\nint dc[] = {1, 0, -1, 0}; // Corresponds to orientations 0, 1, 2, 3\n\n// Function to calculate the positions of all vertices based on root_pos and edge_orientations\nvoid calculate_vertex_positions() {\n    vertex_pos.assign(V_prime, {0, 0});\n    vertex_pos[0] = root_pos;\n\n    // Use BFS-like approach to calculate positions layer by layer\n    // For a tree, we can use a queue or simply iterate based on parent-child relationships.\n    // Let's build adjacency list for easier traversal.\n    std::vector<std::vector<std::pair<int, int>>> adj(V_prime); // {child_vertex_id, edge_index}\n    std::vector<int> edge_idx_for_child(V_prime, -1); // edge_idx_for_child[v] gives index for edge (p,v)\n\n    for (int i = 0; i < V_prime - 1; ++i) {\n        int p = parent_map[i];\n        int child = i + 1; // Vertex ID of child in path graph\n        adj[p].push_back({child, i});\n        edge_idx_for_child[child] = i;\n    }\n\n    std::vector<int> q;\n    q.push_back(0);\n    std::vector<bool> visited(V_prime, false);\n    visited[0] = true;\n\n    int head = 0;\n    while(head < q.size()) {\n        int u = q[head++];\n        \n        // Iterate through children of u\n        for (auto& edge_info : adj[u]) {\n            int v = edge_info.first;\n            int edge_idx = edge_info.second;\n\n            if (!visited[v]) {\n                int orientation = edge_orientations[edge_idx];\n                int length = edge_lengths[edge_idx];\n                \n                vertex_pos[v].r = vertex_pos[u].r + dr[orientation] * length;\n                vertex_pos[v].c = vertex_pos[u].c + dc[orientation] * length;\n                \n                q.push_back(v);\n                visited[v] = true;\n            }\n        }\n    }\n}\n\n// --- Takoyaki and Target Management ---\nstruct Takoyaki {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_taken; // Whether this takoyaki is currently held by a fingertip\n};\nstruct Target {\n    Point pos;\n    int initial_idx; // To match with initial input, useful for debugging\n    bool is_filled; // Whether this target square is occupied by a takoyaki\n};\n\nstd::vector<Takoyaki> takoyaki_list;\nstd::vector<Target> target_list;\n\n// --- Fingertip State Management ---\nstruct Fingertip {\n    int vertex_id; // The vertex ID of this fingertip in the arm\n    bool is_holding; // True if currently holding a takoyaki\n    int holding_takoyaki_idx; // Index in takoyaki_list if holding, -1 otherwise\n    int assigned_pickup_source_idx; // Index in takoyaki_list for planned pickup, -1 if none\n    int assigned_drop_target_idx; // Index in target_list for planned drop, -1 if none\n};\nstd::vector<Fingertip> fingertips;\n\n// --- Operation String Generation ---\n// Generates the operation string for the current turn.\nstd::string generate_operation_string(int current_turn) {\n    std::string S(2 * V_prime, '.'); // Initialize with no operations\n\n    // 1. Update Arm Positions: Calculate current positions of all vertices.\n    calculate_vertex_positions();\n\n    // 2. Task Assignment: Assign takoyaki to free fingertips and targets to holding fingertips.\n    // Reset previous assignments for this turn.\n    for (auto& ft : fingertips) {\n        ft.assigned_pickup_source_idx = -1;\n        ft.assigned_drop_target_idx = -1;\n    }\n    \n    // Greedily assign pickups to fingertips that are not holding anything.\n    std::vector<bool> source_assigned_for_pickup(takoyaki_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (!ft.is_holding) { // If fingertip is empty\n            int best_takoyaki_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2; // Initialize with a large distance\n\n            // Find the closest available takoyaki\n            for (size_t j = 0; j < takoyaki_list.size(); ++j) {\n                if (!takoyaki_list[j].is_taken && !source_assigned_for_pickup[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], takoyaki_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_takoyaki_idx = j;\n                    }\n                }\n            }\n            // Assign the best takoyaki if found\n            if (best_takoyaki_idx != -1) {\n                ft.assigned_pickup_source_idx = best_takoyaki_idx;\n                source_assigned_for_pickup[best_takoyaki_idx] = true;\n            }\n        }\n    }\n\n    // Greedily assign drops to fingertips that are holding a takoyaki.\n    std::vector<bool> target_assigned_for_drop(target_list.size(), false);\n    for (auto& ft : fingertips) {\n        if (ft.is_holding) { // If fingertip is holding\n            int best_target_idx = -1;\n            int min_dist = N_GRID * N_GRID * 2;\n\n            // Find the closest available target\n            for (size_t j = 0; j < target_list.size(); ++j) {\n                if (!target_list[j].is_filled && !target_assigned_for_drop[j]) {\n                    int d = manhattan_distance(vertex_pos[ft.vertex_id], target_list[j].pos);\n                    if (d < min_dist) {\n                        min_dist = d;\n                        best_target_idx = j;\n                    }\n                }\n            }\n            // Assign the best target if found\n            if (best_target_idx != -1) {\n                ft.assigned_drop_target_idx = best_target_idx;\n                target_assigned_for_drop[best_target_idx] = true;\n            }\n        }\n    }\n    \n    // 3. Determine Root Move (S[0])\n    int total_delta_r = 0;\n    int total_delta_c = 0;\n    int num_tasks_with_goal = 0;\n\n    // Calculate the aggregated movement required by all fingertips towards their goals\n    for (auto& ft : fingertips) {\n        Point current_pos = vertex_pos[ft.vertex_id];\n        Point goal_pos = {-1, -1}; // Sentinel value indicating no assigned goal\n\n        if (ft.is_holding) { // If holding, the goal is to reach its assigned drop target\n            if (ft.assigned_drop_target_idx != -1) {\n                goal_pos = target_list[ft.assigned_drop_target_idx].pos;\n            }\n        } else { // If not holding, the goal is to reach its assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1) {\n                goal_pos = takoyaki_list[ft.assigned_pickup_source_idx].pos;\n            }\n        }\n\n        // If a goal is assigned, contribute its delta to the total\n        if (goal_pos.r != -1) {\n            total_delta_r += (goal_pos.r - current_pos.r);\n            total_delta_c += (goal_pos.c - current_pos.c);\n            num_tasks_with_goal++;\n        }\n    }\n\n    // Determine the dominant direction for root movement\n    char root_move = '.'; // Default to no movement\n    if (num_tasks_with_goal > 0) {\n        int abs_delta_r = std::abs(total_delta_r);\n        int abs_delta_c = std::abs(total_delta_c);\n\n        // Prioritize movement in the direction with larger displacement sum\n        if (abs_delta_r > abs_delta_c) {\n            if (total_delta_r > 0) root_move = 'D'; // Move Down if total delta_r is positive\n            else if (total_delta_r < 0) root_move = 'U'; // Move Up if total delta_r is negative\n        } else if (abs_delta_c > abs_delta_r) {\n            if (total_delta_c > 0) root_move = 'R'; // Move Right if total delta_c is positive\n            else if (total_delta_c < 0) root_move = 'L'; // Move Left if total delta_c is negative\n        } else { // If tied, pick one direction, e.g., prefer vertical then horizontal\n            if (total_delta_r > 0) root_move = 'D';\n            else if (total_delta_r < 0) root_move = 'U';\n            else if (total_delta_c > 0) root_move = 'R';\n            else if (total_delta_c < 0) root_move = 'L';\n        }\n    }\n    S[0] = root_move; // Set the root movement character\n\n    // 4. Rotations (S[1] to S[V_prime-1])\n    // Currently, this strategy does NOT implement rotations for simplicity and speed.\n    // All rotation characters remain '.'\n    // If performance is insufficient, rotations for joints (vertices 1 to V_prime-2) could be added.\n\n    // 5. Fingertip Actions (S[V_prime] to S[2*V_prime-1])\n    // The action for vertex `vid` is at index `V_prime + vid` in string S.\n    for (const auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = '.'; // Default to no action\n        Point current_pos = vertex_pos[vid];\n        \n        if (ft.is_holding) { // If currently holding a takoyaki\n            // Check if at the assigned drop target\n            if (ft.assigned_drop_target_idx != -1 && current_pos == target_list[ft.assigned_drop_target_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        } else { // If not holding any takoyaki\n            // Check if at the assigned pickup source\n            if (ft.assigned_pickup_source_idx != -1 && current_pos == takoyaki_list[ft.assigned_pickup_source_idx].pos) {\n                action = 'P'; // Perform pickup/drop action\n            }\n        }\n        S[V_prime + vid] = action; // Set the action character for this vertex\n    }\n\n    return S;\n}\n\n// --- State Update Function ---\n// Applies the operations from the generated string and updates the game state.\nvoid apply_operation(const std::string& op_string) {\n    // Update root position based on the first character (root move)\n    char root_move = op_string[0];\n    if (root_move == 'U') root_pos.r--;\n    else if (root_move == 'D') root_pos.r++;\n    else if (root_move == 'L') root_pos.c--;\n    else if (root_move == 'R') root_pos.c++;\n\n    // Update rotations - THIS PART IS NOT IMPLEMENTED FOR NOW.\n    // The logic would go here if rotations were to be used.\n\n    // Apply fingertip actions ('P' for pickup/drop)\n    for (auto& ft : fingertips) {\n        int vid = ft.vertex_id;\n        char action = op_string[V_prime + vid]; // Action character for this vertex\n        \n        if (action == 'P') {\n            if (ft.is_holding) { // Finger was holding, attempting to drop\n                int target_idx = ft.assigned_drop_target_idx;\n                // Check if the fingertip is at the assigned target location\n                if (target_idx != -1 && target_list[target_idx].pos == vertex_pos[vid]) {\n                    // Successfully dropped takoyaki\n                    target_list[target_idx].is_filled = true; // Mark target as filled\n                    takoyaki_list[ft.holding_takoyaki_idx].is_taken = false; // Release the takoyaki from being \"taken\"\n                    \n                    ft.is_holding = false; // Fingertip is now empty\n                    ft.holding_takoyaki_idx = -1; // No longer holding a takoyaki\n                    ft.assigned_drop_target_idx = -1; // Clear the drop assignment\n                } else {\n                    // If 'P' action occurs but not at target, it's an invalid/ineffective action.\n                    // This indicates a potential issue in assignment or movement logic.\n                }\n            } else { // Finger was not holding, attempting to pick up\n                int source_idx = ft.assigned_pickup_source_idx;\n                // Check if the fingertip is at the assigned source location\n                if (source_idx != -1 && takoyaki_list[source_idx].pos == vertex_pos[vid]) {\n                    // Successfully picked up takoyaki\n                    takoyaki_list[source_idx].is_taken = true; // Mark takoyaki as taken\n                    ft.is_holding = true; // Fingertip is now holding\n                    ft.holding_takoyaki_idx = source_idx; // Record which takoyaki is held\n                    ft.assigned_pickup_source_idx = -1; // Clear the pickup assignment\n                } else {\n                    // If 'P' action occurs but not at source, it's an invalid/ineffective action.\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Optimize C++ standard streams for faster I/O\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    // Read input parameters\n    std::cin >> N_GRID >> M_TAKOYAKI >> V_ARM;\n\n    // Read initial takoyaki positions\n    takoyaki_list.resize(M_TAKOYAKI);\n    int current_takoyaki_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store takoyaki: {position, initial_index, is_taken=false}\n                takoyaki_list[current_takoyaki_idx] = {{i, j}, current_takoyaki_idx, false};\n                current_takoyaki_idx++;\n            }\n        }\n    }\n\n    // Read target positions\n    target_list.resize(M_TAKOYAKI);\n    int current_target_idx = 0;\n    for (int i = 0; i < N_GRID; ++i) {\n        std::string row;\n        std::cin >> row;\n        for (int j = 0; j < N_GRID; ++j) {\n            if (row[j] == '1') {\n                // Store target: {position, initial_index, is_filled=false}\n                target_list[current_target_idx] = {{i, j}, current_target_idx, false};\n                current_target_idx++;\n            }\n        }\n    }\n\n    // --- Design the Robotic Arm ---\n    V_prime = V_ARM; // Use the maximum available vertices\n    parent_map.resize(V_prime - 1);\n    edge_lengths.resize(V_prime - 1);\n    edge_orientations.resize(V_prime - 1);\n    vertex_pos.resize(V_prime); // Pre-allocate space for vertex positions\n    fingertips.clear();\n    joint_vertex_ids.clear();\n\n    // Arm Design: Path graph 0-1-2-...-V-1\n    // Parent of vertex i+1 is vertex i.\n    // Edge lengths are uniformly 1.\n    // Initial edge orientations are all 0 (Right).\n    for (int i = 0; i < V_prime - 1; ++i) {\n        parent_map[i] = i;          // Parent of vertex i+1 is vertex i\n        edge_lengths[i] = 1;        // Edge length is 1\n        edge_orientations[i] = 0;   // Initial orientation is Right (0)\n    }\n\n    // Initial root position: Center of the grid.\n    root_pos = {N_GRID / 2, N_GRID / 2};\n\n    // Identify fingertips and joints based on the path graph structure.\n    if (V_prime == 1) {\n        // If only one vertex, it's the root and also a fingertip. No joints.\n        fingertip_vertex_ids.push_back(0);\n    } else {\n        // For V' > 1, vertices 0 and V'-1 are leaves (fingertips).\n        fingertip_vertex_ids.push_back(0);\n        fingertip_vertex_ids.push_back(V_prime - 1);\n        // Vertices 1 to V'-2 are internal nodes (joints) where rotations can occur.\n        for (int i = 1; i < V_prime - 1; ++i) {\n            joint_vertex_ids.push_back(i);\n        }\n    }\n\n    // Initialize fingertip state trackers.\n    fingertips.resize(fingertip_vertex_ids.size());\n    for (size_t i = 0; i < fingertip_vertex_ids.size(); ++i) {\n        fingertips[i].vertex_id = fingertip_vertex_ids[i];\n        fingertips[i].is_holding = false;\n        fingertips[i].holding_takoyaki_idx = -1; // Tracks index in takoyaki_list IF holding\n        fingertips[i].assigned_pickup_source_idx = -1; // Tracks index in takoyaki_list for planned pickup\n        fingertips[i].assigned_drop_target_idx = -1; // Tracks index in target_list for planned drop\n    }\n\n    // Output the designed robotic arm structure.\n    std::cout << V_prime << std::endl;\n    for (int i = 0; i < V_prime - 1; ++i) {\n        std::cout << parent_map[i] << \" \" << edge_lengths[i] << std::endl;\n    }\n    std::cout << root_pos.r << \" \" << root_pos.c << std::endl;\n\n    // --- Operation Phase ---\n    int delivered_count = 0;\n    int max_turns = 100000; // Set a limit to prevent TLE.\n\n    // Main loop for executing turns.\n    for (int turn = 0; turn < max_turns; ++turn) {\n        // If all takoyaki are delivered, stop early.\n        if (delivered_count == M_TAKOYAKI) {\n            break;\n        }\n\n        // Generate the operation string for the current turn.\n        std::string op_string = generate_operation_string(turn);\n        \n        // Output the operation string.\n        std::cout << op_string << std::endl;\n        \n        // Apply the generated operations to update the game state.\n        apply_operation(op_string);\n\n        // Recalculate the number of delivered takoyaki after applying operations.\n        delivered_count = 0;\n        for(const auto& target : target_list) {\n            if (target.is_filled) {\n                delivered_count++;\n            }\n        }\n    }\n\n    return 0;\n}\n","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <map>\n\nstruct Point {\n    int x, y;\n    int type; // 0 for mackerel, 1 for sardine\n};\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int n;\n    std::cin >> n;\n\n    std::vector<Point> points(2 * n);\n    std::vector<int> x_coords_all, y_coords_all;\n    x_coords_all.reserve(2 * n);\n    y_coords_all.reserve(2 * n);\n\n    for (int i = 0; i < 2 * n; ++i) {\n        points[i].type = (i < n) ? 0 : 1;\n        std::cin >> points[i].x >> points[i].y;\n        x_coords_all.push_back(points[i].x);\n        y_coords_all.push_back(points[i].y);\n    }\n\n    // Sort and unique coordinates to get candidate boundary points.\n    std::sort(x_coords_all.begin(), x_coords_all.end());\n    x_coords_all.erase(std::unique(x_coords_all.begin(), x_coords_all.end()), x_coords_all.end());\n    std::sort(y_coords_all.begin(), y_coords_all.end());\n    y_coords_all.erase(std::unique(y_coords_all.begin(), y_coords_all.end()), y_coords_all.end());\n\n    // K_cand is the number of candidate coordinate values to consider along each axis.\n    // A larger K_cand increases the chances of finding an optimal rectangle but also increases runtime.\n    // K_cand = 100 is chosen to balance search space and performance.\n    int K_cand = 100; \n\n    std::vector<int> sx, sy;\n    sx.reserve(K_cand);\n    sy.reserve(K_cand);\n\n    // Always include the bounding box coordinates 0 and 100000.\n    sx.push_back(0);\n    sx.push_back(100000);\n    sy.push_back(0);\n    sy.push_back(100000);\n\n    // Select K_cand-2 points from all unique x-coordinates, attempting to space them evenly.\n    // This ensures candidate boundaries cover the distribution of points.\n    if (x_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            // Select index: (i * (total_unique - 1)) / (num_points_to_select - 1)\n            // This samples points from the available unique coordinates.\n            sx.push_back(x_coords_all[(i * (x_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (x_coords_all.size() > 0) {\n        // If there are fewer than 2 unique coordinates (excluding 0 and 100000 if they are not present),\n        // add some of the existing unique coordinates to ensure some variation.\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, x_coords_all.size()); ++i) {\n            sx.push_back(x_coords_all[i]);\n        }\n    }\n    \n    // Select K_cand-2 points from all unique y-coordinates, similar to x-coordinates.\n    if (y_coords_all.size() > 2) {\n        for (int i = 1; i < K_cand - 1; ++i) {\n            sy.push_back(y_coords_all[(i * (y_coords_all.size() - 1)) / (K_cand - 1)]);\n        }\n    } else if (y_coords_all.size() > 0) {\n        for (size_t i = 0; i < std::min((size_t)K_cand - 2, y_coords_all.size()); ++i) {\n            sy.push_back(y_coords_all[i]);\n        }\n    }\n    \n    // Sort and remove duplicates from candidate coordinates to ensure valid intervals.\n    std::sort(sx.begin(), sx.end());\n    sx.erase(std::unique(sx.begin(), sx.end()), sx.end());\n    std::sort(sy.begin(), sy.end());\n    sy.erase(std::unique(sy.begin(), sy.end()), sy.end());\n\n    int num_sx = sx.size();\n    int num_sy = sy.size();\n\n    // `grid_diff` is a 2D difference array.\n    // `grid_diff[i][j]` stores the value that starts contributing to cells starting at `sx[i]` and `sy[j]`.\n    // Specifically, it applies a value change to the grid cell starting at `[sx[i], sx[i+1]) x [sy[j], sy[j+1])`.\n    // The size is `num_sx` x `num_sy` to handle points correctly.\n    std::vector<std::vector<int>> grid_diff(num_sx, std::vector<int>(num_sy, 0));\n\n    for (const auto& p : points) {\n        // Determine the grid cell index `ix` for point `p.x`.\n        // `ix` should be the index `i` such that `sx[i] <= p.x < sx[i+1]`.\n        // `std::upper_bound(sx.begin(), sx.end(), p.x)` finds the first element `sx[k]` strictly greater than `p.x`.\n        // The index `k` indicates that `p.x` is in the interval `[sx[k-1], sx[k])`. So `ix = k-1`.\n        auto it_x = std::upper_bound(sx.begin(), sx.end(), p.x);\n        int ix = (it_x - sx.begin()) - 1;\n        \n        // Similarly, determine the grid cell index `iy` for point `p.y`.\n        auto it_y = std::upper_bound(sy.begin(), sy.end(), p.y);\n        int iy = (it_y - sy.begin()) - 1;\n        \n        int val = (p.type == 0 ? 1 : -1); // +1 for mackerel, -1 for sardine.\n\n        // Apply the difference array update.\n        // `val` is added at the top-left corner of the cell `(ix, iy)`.\n        // It's subtracted at `(ix+1, iy)` and `(ix, iy+1)` to limit its effect to the cell `(ix, iy)`.\n        // It's added back at `(ix+1, iy+1)` to correct the double subtraction.\n        // Indices must be within bounds.\n        if (ix < num_sx && iy < num_sy) {\n            grid_diff[ix][iy] += val;\n            if (ix + 1 < num_sx) grid_diff[ix + 1][iy] -= val;\n            if (iy + 1 < num_sy) grid_diff[ix][iy + 1] -= val;\n            if (ix + 1 < num_sx && iy + 1 < num_sy) grid_diff[ix + 1][iy + 1] += val;\n        }\n    }\n    \n    // `grid_ps[i][j]` will store the cumulative sum for the rectangle `[sx[0], sx[i+1]) x [sy[0], sy[j+1])`.\n    // This is computed using 2D prefix sums on `grid_diff`.\n    std::vector<std::vector<int>> grid_ps(num_sx, std::vector<int>(num_sy, 0));\n    for (int i = 0; i < num_sx; ++i) {\n        for (int j = 0; j < num_sy; ++j) {\n            grid_ps[i][j] = grid_diff[i][j];\n            if (i > 0) grid_ps[i][j] += grid_ps[i-1][j];\n            if (j > 0) grid_ps[i][j] += grid_ps[i][j-1];\n            if (i > 0 && j > 0) grid_ps[i][j] -= grid_ps[i-1][j-1];\n        }\n    }\n\n    // Lambda function `get_ps_val` to safely retrieve prefix sum values.\n    // It handles out-of-bounds indices (e.g., for calculations involving `index-1`) by returning 0.\n    // `grid_ps[r_idx][c_idx]` stores the sum of points `p` such that `p.x < sx[r_idx+1]` and `p.y < sy[c_idx+1]`.\n    auto get_ps_val = [&](int r_idx, int c_idx) {\n        if (r_idx < 0 || c_idx < 0) return 0;\n        // Clamp indices to be within the bounds of grid_ps.\n        // This handles cases where calculation might exceed max index.\n        r_idx = std::min(r_idx, num_sx - 1);\n        c_idx = std::min(c_idx, num_sy - 1);\n        return grid_ps[r_idx][c_idx];\n    };\n\n    long long max_score_diff = -2e18; // Initialize with a very small value to find the maximum.\n    int best_x1_idx = -1, best_x2_idx = -1, best_y1_idx = -1, best_y2_idx = -1;\n\n    // Iterate through all possible rectangles defined by pairs of candidate coordinates.\n    // A rectangle is defined by its bottom-left corner (sx[i1], sy[j1]) and top-right corner (sx[i2], sy[j2]).\n    for (int i1 = 0; i1 < num_sx; ++i1) {\n        for (int i2 = i1; i2 < num_sx; ++i2) {\n            for (int j1 = 0; j1 < num_sy; ++j1) {\n                for (int j2 = j1; j2 < num_sy; ++j2) {\n                    \n                    // Variable to store the score difference (mackerels - sardines) for the current rectangle.\n                    long long current_score_diff = 0; \n\n                    // Calculate the score for the rectangle defined by [sx[i1], sx[i2]] x [sy[j1], sy[j2]].\n                    // This score is calculated using the 2D prefix sums for a rectangle query:\n                    // Sum(X_max, Y_max) - Sum(X_min-1, Y_max) - Sum(X_max, Y_min-1) + Sum(X_min-1, Y_min-1)\n                    // Here, Sum(X, Y) denotes the sum of points `p` such that `p.x <= X` and `p.y <= Y`.\n                    // Using `grid_ps`:\n                    // Sum(sx[i2], sy[j2]) corresponds to `get_ps_val(i2, j2)`\n                    // Sum(sx[i1]-1, sy[j2]) corresponds to `get_ps_val(i1-1, j2)`\n                    // Sum(sx[i2], sy[j1]-1) corresponds to `get_ps_val(i2, j1-1)`\n                    // Sum(sx[i1]-1, sy[j1]-1) corresponds to `get_ps_val(i1-1, j1-1)`\n                    current_score_diff = get_ps_val(i2, j2) \n                                       - get_ps_val(i1 - 1, j2) \n                                       - get_ps_val(i2, j1 - 1) \n                                       + get_ps_val(i1 - 1, j1 - 1);\n\n                    // Calculate the perimeter of the rectangle.\n                    long long current_perimeter = 2LL * ((long long)(sx[i2] - sx[i1]) + (long long)(sy[j2] - sy[j1]));\n\n                    // Check if the perimeter constraint is satisfied.\n                    if (current_perimeter <= 400000LL) {\n                        // If the current rectangle has a better score difference, update the best found rectangle.\n                        if (current_score_diff > max_score_diff) {\n                            max_score_diff = current_score_diff;\n                            best_x1_idx = i1;\n                            best_x2_idx = i2;\n                            best_y1_idx = j1;\n                            best_y2_idx = j2;\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    // If no valid rectangle was found (e.g., all rectangles exceeded perimeter, or all had non-positive score diff),\n    // default to a minimal valid rectangle: a single point at (0,0) if (0,0) is a candidate.\n    // The indices sx[0], sy[0] are always 0. So this effectively picks (0,0) as the rectangle.\n    // This rectangle has perimeter 0 and a score difference of 0 if no points are at (0,0),\n    // resulting in a score of max(0, 0+1)=1, which is a valid baseline.\n    if (best_x1_idx == -1) {\n        best_x1_idx = 0;\n        best_x2_idx = 0;\n        best_y1_idx = 0;\n        best_y2_idx = 0;\n    }\n    \n    // Output the 4 vertices of the best rectangle found.\n    // The vertices are (sx[best_x1_idx], sy[best_y1_idx]), (sx[best_x2_idx], sy[best_y1_idx]),\n    // (sx[best_x2_idx], sy[best_y2_idx]), and (sx[best_x1_idx], sy[best_y2_idx}).\n    std::cout << 4 << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y1_idx] << std::endl;\n    std::cout << sx[best_x2_idx] << \" \" << sy[best_y2_idx] << std::endl;\n    std::cout << sx[best_x1_idx] << \" \" << sy[best_y2_idx] << std::endl;\n\n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <string>\n#include <utility> // for std::pair\n\n// Structure to hold noisy dimensions for a rectangle\nstruct Rect {\n    long long w_prime, h_prime;\n};\n\n// Structure to hold information about a rectangle after placement\nstruct PlacedRect {\n    int id; // original index of the rectangle\n    long long x, y, w, h; // position (top-left) and dimensions\n};\n\n// Structure to represent an entry in the output placement sequence for a turn\nstruct OutputEntry {\n    int p; // rectangle index\n    int r; // rotation (0: original, 1: 90 deg rotated)\n    char d; // direction ('U' for Up, 'L' for Left)\n    int b; // reference rectangle index (-1 for origin, or index in current_placed_rects)\n};\n\nint main() {\n    // Improve I/O performance\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N; // Number of rectangles\n    int T; // Number of turns\n    long long sigma; // Standard deviation of measurement error\n    std::cin >> N >> T >> sigma;\n\n    // Read noisy dimensions for each rectangle\n    std::vector<Rect> rects(N);\n    for (int i = 0; i < N; ++i) {\n        std::cin >> rects[i].w_prime >> rects[i].h_prime;\n    }\n\n    // Pre-calculate the sum of (w'_i + h'_i) for all suffixes of rectangles.\n    // penalty_sum[k] will store sum_{i=k to N-1} (rects[i].w_prime + rects[i].h_prime).\n    // This is used to quickly calculate the penalty for unused rectangles.\n    std::vector<long long> penalty_sum(N + 1, 0);\n    for (int i = N - 1; i >= 0; --i) {\n        penalty_sum[i] = penalty_sum[i + 1] + rects[i].w_prime + rects[i].h_prime;\n    }\n\n    // Main loop for each turn\n    for (int t = 0; t < T; ++t) {\n        // Variables to store the best placement strategy found for the current turn\n        std::vector<OutputEntry> best_output_sequence;\n        int best_n = 0; // Number of rectangles to place in this turn\n        long long best_turn_score = -1; // Score for the best strategy in this turn\n\n        // Iterate through all possible numbers of rectangles to place, from N down to 0.\n        // We try to place `num_to_place` rectangles, specifically indices 0, 1, ..., num_to_place - 1.\n        // This is because rectangles must be placed in ascending order of their original indices.\n        for (int num_to_place = N; num_to_place >= 0; --num_to_place) {\n            // Case: placing 0 rectangles.\n            if (num_to_place == 0) {\n                // The score is 0 (W+H) + penalty for all N unused rectangles.\n                long long current_score = 0 + 0 + penalty_sum[0];\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = 0;\n                    best_output_sequence.clear(); // Empty sequence\n                }\n                continue; // Move to the next iteration of `num_to_place`\n            }\n\n            // State for placing `num_to_place` rectangles:\n            std::vector<PlacedRect> current_placed_rects; // Stores info about rectangles placed so far in this attempt.\n            std::vector<OutputEntry> current_output_sequence; // Stores the placement instructions for this attempt.\n            bool possible_to_place_all = true; // Flag to check if all `num_to_place` can be placed validly.\n\n            long long current_max_W = 0; // Current bounding box width after placing rectangles so far.\n            long long current_max_H = 0; // Current bounding box height after placing rectangles so far.\n\n            // Attempt to place rectangles 0, 1, ..., num_to_place - 1 in order.\n            for (int i = 0; i < num_to_place; ++i) {\n                int current_rect_idx = i; // The original index of the rectangle being considered for placement.\n\n                // Define the two possible dimensions (original and rotated) for the current rectangle.\n                std::pair<long long, long long> dims[2];\n                dims[0] = {rects[current_rect_idx].w_prime, rects[current_rect_idx].h_prime}; // r = 0 (no rotation)\n                dims[1] = {rects[current_rect_idx].h_prime, rects[current_rect_idx].w_prime}; // r = 1 (rotated 90 degrees)\n\n                // Variables to track the best placement found for the current rectangle `i`.\n                long long best_x = -1, best_y = -1; // Best position (top-left corner)\n                int best_r = -1; // Best rotation option (0 or 1)\n                char best_d_char = ' '; // Best direction ('U' or 'L')\n                int best_b_idx_in_placed = -1; // Index of the reference rectangle in `current_placed_rects` (-1 if origin).\n                long long min_placement_cost = -1; // The cost (W+H) of the best found placement for this rectangle.\n\n                // Iterate through all possible reference rectangles.\n                // `b_place_idx` is the index in `current_placed_rects`. -1 refers to the origin (0,0).\n                for (int b_place_idx = -1; b_place_idx < current_placed_rects.size(); ++b_place_idx) {\n                    // Get reference rectangle's properties if b_place_idx is valid.\n                    long long ref_x = 0, ref_y = 0, ref_w = 0, ref_h = 0;\n                    if (b_place_idx != -1) {\n                        ref_x = current_placed_rects[b_place_idx].x;\n                        ref_y = current_placed_rects[b_place_idx].y;\n                        ref_w = current_placed_rects[b_place_idx].w;\n                        ref_h = current_placed_rects[b_place_idx].h;\n                    }\n\n                    // Iterate through rotation options (0 or 1).\n                    for (int r_opt = 0; r_opt < 2; ++r_opt) {\n                        long long W = dims[r_opt].first; // Width of the rectangle in this orientation.\n                        long long H = dims[r_opt].second; // Height of the rectangle in this orientation.\n\n                        // Iterate through placement directions ('U' or 'L').\n                        for (char d_char : {'U', 'L'}) {\n                            long long cur_x, cur_y; // Proposed position for the top-left corner.\n\n                            if (d_char == 'U') {\n                                // Place upwards: align left edge with ref's right edge, top edge with ref's bottom edge.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x + ref_w);\n                                cur_y = (b_place_idx == -1) ? 0 : (ref_y + ref_h);\n                            } else { // d_char == 'L'\n                                // Place leftwards: align right edge with ref's left edge, top edge with ref's top edge.\n                                // The resulting x-coordinate must be non-negative.\n                                cur_x = (b_place_idx == -1) ? 0 : (ref_x - W);\n                                cur_y = (b_place_idx == -1) ? 0 : ref_y;\n                                \n                                // Constraint: rectangles must be placed in x >= 0 and y >= 0.\n                                // For 'L' placement, if `ref_x - W` results in a negative x-coordinate,\n                                // this specific alignment with `ref_x` is not possible without going left of the origin.\n                                // The rule implies stopping at x=0. If `ref_x < W`, the rectangle cannot be placed \n                                // such that its right edge is at `ref_x` AND its left edge is >= 0.\n                                // Thus, `ref_x` must be at least `W` for this alignment to be possible.\n                                if (cur_x < 0) { \n                                    continue; // This placement combination is invalid.\n                                }\n                            }\n\n                            // Calculate the resulting bounding box dimensions if this rectangle is placed at (cur_x, cur_y).\n                            // `current_max_W` and `current_max_H` store the bounding box of already placed rectangles.\n                            long long candidate_W = std::max(current_max_W, cur_x + W);\n                            long long candidate_H = std::max(current_max_H, cur_y + H);\n                            \n                            // The cost for this placement is the sum of the bounding box dimensions.\n                            long long current_placement_cost = candidate_W + candidate_H;\n\n                            // If this is the first valid placement found, or if it yields a better (smaller) cost, update best found.\n                            if (min_placement_cost == -1 || current_placement_cost < min_placement_cost) {\n                                min_placement_cost = current_placement_cost;\n                                best_x = cur_x;\n                                best_y = cur_y;\n                                best_r = r_opt;\n                                best_d_char = d_char;\n                                best_b_idx_in_placed = b_place_idx;\n                            }\n                        } // End of loop for `d_char`\n                    } // End of loop for `r_opt`\n                } // End of loop for `b_place_idx`\n\n                // If no valid placement was found for the current rectangle `i` with the current `num_to_place` setting.\n                if (best_x == -1) {\n                    possible_to_place_all = false; // This `num_to_place` strategy is not feasible.\n                    break; // Stop trying to place more rectangles for this `num_to_place` value.\n                }\n\n                // Record the best placement found for rectangle `i`.\n                current_placed_rects.push_back({current_rect_idx, best_x, best_y, dims[best_r].first, dims[best_r].second});\n                current_output_sequence.push_back({current_rect_idx, best_r, best_d_char, best_b_idx_in_placed});\n                \n                // Update the overall bounding box dimensions with the newly placed rectangle.\n                current_max_W = std::max(current_max_W, best_x + dims[best_r].first);\n                current_max_H = std::max(current_max_H, best_y + dims[best_r].second);\n\n            } // End of loop for `i` (placing rectangles 0 to num_to_place - 1)\n\n            // If we successfully placed all `num_to_place` rectangles:\n            if (possible_to_place_all) {\n                // Calculate the total score for this specific `num_to_place` strategy.\n                // Score = (final W + final H of placed rectangles) + (penalty sum of unused rectangles).\n                long long current_score = current_max_W + current_max_H + penalty_sum[num_to_place];\n                \n                // If this score is better than the best score found so far for this turn, update bests.\n                if (best_turn_score == -1 || current_score < best_turn_score) {\n                    best_turn_score = current_score;\n                    best_n = num_to_place;\n                    best_output_sequence = current_output_sequence;\n                }\n            }\n        } // End of loop for `num_to_place` (trying different counts of rectangles to place)\n\n        // Output the chosen placement strategy for the current turn.\n        std::cout << best_n << std::endl;\n        for (const auto& p : best_output_sequence) {\n            std::cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << std::endl;\n        }\n        std::cout << std::flush; // Ensure output is sent immediately.\n\n        // Read the measured bounding box dimensions for this turn.\n        // These are not used by the current strategy, but are required by the problem protocol.\n        long long measured_W_prime, measured_H_prime;\n        std::cin >> measured_W_prime >> measured_H_prime;\n    } // End of loop for turns `t`\n\n    return 0; // Program finished successfully.\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <algorithm>\n#include <queue>\n#include <tuple> // Not strictly needed for PQ_Entry, but included for completeness.\n\nusing namespace std;\n\n// Structure to store information about a representative of a DSU set.\nstruct DSU_Rep_Info {\n    int root_vertex;    // The actual vertex ID that is the root of this tree.\n    int max_height;     // The maximum height among all vertices in this tree, relative to root_vertex.\n    long long sum_beauty; // The sum of beauty values of all vertices in this tree.\n    int component_size; // The number of vertices in this component.\n};\n\nvector<int> dsu_parent; // Standard DSU parent array.\nvector<DSU_Rep_Info> rep_info; // Stores information about each representative.\n\n// Finds the representative of the set containing vertex v. Path compression is used.\nint find_set(int v) {\n    if (v == dsu_parent[v])\n        return v;\n    return dsu_parent[v] = find_set(dsu_parent[v]);\n}\n\n// Structure for priority queue entries to handle custom comparison.\nstruct PQ_Entry {\n    long long gain; // Primary criterion: sum of beauty of the child component.\n    int h_child; // Secondary: max height of the child component (prefer deeper).\n    int h_parent_height; // Tertiary: max height of the parent component (prefer deeper parents).\n    long long h_parent_sum_beauty; // Quaternary: sum of beauty of the parent component (prefer higher beauty parents).\n    \n    // For comparing average beauty of children using integer cross-multiplication.\n    // We store child_sum_beauty and child_component_size.\n    long long child_sum_beauty;\n    int child_component_size;\n\n    int parent_root_repr_id; // ID of the parent's DSU representative.\n    int child_root_repr_id;  // ID of the child's DSU representative.\n\n    // Custom comparison operator for the max-heap priority queue.\n    // Returns true if 'this' is considered \"less than\" 'other', meaning 'other' has higher priority.\n    bool operator<(const PQ_Entry& other) const {\n        // Primary: maximize gain (sum of beauty of the child component).\n        if (gain != other.gain) return gain < other.gain;\n\n        // Secondary: maximize h_child (prefer deeper children).\n        if (h_child != other.h_child) return h_child < other.h_child;\n\n        // Tertiary: maximize h_parent_height (prefer deeper parents).\n        if (h_parent_height != other.h_parent_height) return h_parent_height < other.h_parent_height;\n\n        // Quaternary: maximize h_parent_sum_beauty (prefer merging into more beautiful parents).\n        if (h_parent_sum_beauty != other.h_parent_sum_beauty) return h_parent_sum_beauty < other.h_parent_sum_beauty;\n\n        // Quinary: maximize average beauty of the child component using integer cross-multiplication.\n        // Compare S1/Z1 vs S2/Z2 using cross-multiplication: S1*Z2 vs S2*Z1.\n        // Use unsigned __int128 for intermediate products to avoid overflow.\n        unsigned __int128 val1 = (unsigned __int128)child_sum_beauty * other.child_component_size;\n        unsigned __int128 val2 = (unsigned __int128)other.child_sum_beauty * child_component_size;\n        if (val1 != val2) return val1 < val2; // Prefer child with higher average beauty.\n\n        // If all criteria are equal, the order doesn't significantly impact score.\n        // Return false to indicate equality.\n        return false;\n    }\n};\n\n// Merges the set represented by root_c_repr into the set represented by root_p_repr.\n// Removed unused parameters H and adj.\nvoid union_sets(int root_p_repr, int root_c_repr, int root_p_vertex, int root_c_vertex, vector<int>& p, vector<DSU_Rep_Info>& rep_info, vector<int>& dsu_parent) {\n    dsu_parent[root_c_repr] = root_p_repr;\n    p[root_c_vertex] = root_p_vertex;\n\n    rep_info[root_p_repr].sum_beauty += rep_info[root_c_repr].sum_beauty;\n    rep_info[root_p_repr].max_height = max(rep_info[root_p_repr].max_height, rep_info[root_c_repr].max_height + 1);\n    rep_info[root_p_repr].component_size += rep_info[root_c_repr].component_size;\n    rep_info[root_p_repr].root_vertex = root_p_vertex; // Ensure root_vertex is consistent\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n; // Number of vertices\n    int m; // Number of edges\n    int h_limit; // Maximum allowed height\n    cin >> n >> m >> h_limit;\n\n    vector<long long> a(n); // Beauty values of vertices\n    for (int i = 0; i < n; ++i) {\n        cin >> a[i];\n    }\n\n    vector<vector<int>> adj(n); // Adjacency list for the graph\n    vector<pair<int, int>> edges; // List of all edges\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        edges.push_back({u, v});\n    }\n\n    // Initialize DSU structure.\n    dsu_parent.resize(n);\n    iota(dsu_parent.begin(), dsu_parent.end(), 0); // dsu_parent[i] = i for all i\n    \n    rep_info.resize(n);\n    for (int i = 0; i < n; ++i) {\n        // Initially, each vertex is a root of its own tree.\n        rep_info[i] = {i, 0, a[i], 1}; \n    }\n\n    // Priority queue to store potential merges, using the custom PQ_Entry struct.\n    priority_queue<PQ_Entry> pq;\n\n    // Populate the priority queue with initial merge candidates.\n    for (const auto& edge : edges) {\n        int u_vtx = edge.first;\n        int v_vtx = edge.second;\n\n        int root_u_repr = find_set(u_vtx);\n        int root_v_repr = find_set(v_vtx);\n\n        // If they are already in the same component, this edge doesn't form a new merge candidate between components.\n        if (root_u_repr == root_v_repr) continue;\n\n        // Option 1: Make v's component a child of u's component.\n        // Parent: u's component (representative root_u_repr), Child: v's component (representative root_v_repr).\n        if (rep_info[root_v_repr].max_height + 1 <= h_limit) {\n            pq.push({\n                rep_info[root_v_repr].sum_beauty, // gain\n                rep_info[root_v_repr].max_height, // h_child\n                rep_info[root_u_repr].max_height, // h_parent_height (re-ordered to tertiary)\n                rep_info[root_u_repr].sum_beauty, // h_parent_sum_beauty (re-ordered to quaternary)\n                rep_info[root_v_repr].sum_beauty, // child_sum_beauty for density calc\n                rep_info[root_v_repr].component_size, // child_component_size for density calc\n                root_u_repr, // parent_root_repr_id\n                root_v_repr  // child_root_repr_id\n            });\n        }\n        // Option 2: Make u's component a child of v's component.\n        // Parent: v's component (representative root_v_repr), Child: u's component (representative root_u_repr).\n        if (rep_info[root_u_repr].max_height + 1 <= h_limit) {\n            pq.push({\n                rep_info[root_u_repr].sum_beauty, // gain\n                rep_info[root_u_repr].max_height, // h_child\n                rep_info[root_v_repr].max_height, // h_parent_height (re-ordered to tertiary)\n                rep_info[root_v_repr].sum_beauty, // h_parent_sum_beauty (re-ordered to quaternary)\n                rep_info[root_u_repr].sum_beauty, // child_sum_beauty for density calc\n                rep_info[root_u_repr].component_size, // child_component_size for density calc\n                root_v_repr, // parent_root_repr_id\n                root_u_repr  // child_root_repr_id\n            });\n        }\n    }\n\n    // Initialize the final parent array. -1 indicates a root vertex.\n    vector<int> p(n, -1); \n\n    // Greedily process merges from the priority queue.\n    while (!pq.empty()) {\n        PQ_Entry entry = pq.top();\n        pq.pop();\n\n        // Find current representatives for the components.\n        int current_parent_repr = find_set(entry.parent_root_repr_id);\n        int current_child_repr = find_set(entry.child_root_repr_id);\n\n        // If they are already in the same set, this merge is redundant.\n        if (current_parent_repr == current_child_repr) continue;\n        \n        // Stale entry check: if the vertex IDs stored in PQ are no longer the current representatives.\n        // This happens if one of the components has been merged into another.\n        if (current_parent_repr != entry.parent_root_repr_id || current_child_repr != entry.child_root_repr_id) {\n             continue; // Stale entry.\n        }\n\n        // Re-check height constraint using the *current* max heights from `rep_info`.\n        // The values stored in the PQ entry (like h_child) might be stale.\n        if (rep_info[entry.child_root_repr_id].max_height + 1 > h_limit) {\n            continue; // Height limit violated with the current configuration.\n        }\n\n        // Perform the union operation.\n        // Note: Passing the actual root vertex IDs (rep_info[id].root_vertex) is crucial for setting p[].\n        union_sets(entry.parent_root_repr_id, entry.child_root_repr_id, rep_info[entry.parent_root_repr_id].root_vertex, rep_info[entry.child_root_repr_id].root_vertex, p, rep_info, dsu_parent);\n    }\n\n    // Output the resulting parent array.\n    for (int i = 0; i < n; ++i) {\n        cout << p[i] << (i == n - 1 ? \"\" : \" \");\n    }\n    cout << endl;\n\n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <tuple>\n\nusing namespace std;\n\nint main() {\n    // Optimize C++ standard streams for competitive programming.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int n;\n    cin >> n;\n\n    // Read the initial board configuration.\n    vector<string> board(n);\n    for (int i = 0; i < n; ++i) {\n        cin >> board[i];\n    }\n\n    // Precompute safety information for each cell.\n    // has_fuku_above[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k < r.\n    // has_fuku_below[r][c] is true if there is any Fukunokami ('o') in column 'c' at a row 'k' where k > r.\n    // has_fuku_left[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k < c.\n    // has_fuku_right[r][c] is true if there is any Fukunokami ('o') in row 'r' at a column 'k' where k > c.\n    // These precomputed values allow O(1) safety checks for each direction.\n    vector<vector<bool>> has_fuku_above(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_below(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_left(n, vector<bool>(n, false));\n    vector<vector<bool>> has_fuku_right(n, vector<bool>(n, false));\n\n    // Compute has_fuku_above and has_fuku_below for all columns.\n    for (int c = 0; c < n; ++c) {\n        bool found_fuku_in_col = false;\n        // Scan downwards: for each cell (r, c), check if any Fuku was found in previous rows (k < r).\n        for (int r = 0; r < n; ++r) {\n            has_fuku_above[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column above current row.\n            }\n        }\n        \n        found_fuku_in_col = false; // Reset for scanning downwards to compute has_fuku_below.\n        // Scan upwards: for each cell (r, c), check if any Fuku was found in subsequent rows (k > r).\n        for (int r = n - 1; r >= 0; --r) {\n            has_fuku_below[r][c] = found_fuku_in_col;\n            if (board[r][c] == 'o') {\n                found_fuku_in_col = true; // Mark that a Fuku has been encountered in this column below current row.\n            }\n        }\n    }\n\n    // Compute has_fuku_left and has_fuku_right for all rows.\n    for (int r = 0; r < n; ++r) {\n        bool found_fuku_in_row = false;\n        // Scan rightwards: for each cell (r, c), check if any Fuku was found in previous columns (k < c).\n        for (int c = 0; c < n; ++c) {\n            has_fuku_left[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the left of current column.\n            }\n        }\n        \n        found_fuku_in_row = false; // Reset for scanning rightwards to compute has_fuku_right.\n        // Scan leftwards: for each cell (r, c), check if any Fuku was found in subsequent columns (k > c).\n        for (int c = n - 1; c >= 0; --c) {\n            has_fuku_right[r][c] = found_fuku_in_row;\n            if (board[r][c] == 'o') {\n                found_fuku_in_row = true; // Mark that a Fuku has been encountered in this row to the right of current column.\n            }\n        }\n    }\n\n    // Stores the sequence of operations to be performed.\n    vector<pair<char, int>> operations;\n    const int INF = 1e9; // A large enough value to represent infinity for costs.\n\n    // Iterate through each cell of the board.\n    for (int r = 0; r < n; ++r) {\n        for (int c = 0; c < n; ++c) {\n            // If the cell contains an Oni ('x').\n            if (board[r][c] == 'x') {\n                // Find the safest and cheapest direction to remove this specific Oni.\n                // The goal is to minimize operations (T) for the score 8N^2 - T.\n                int min_cost = INF;\n                char best_op_char = ' ';\n                int best_op_idx = -1;\n\n                // --- Evaluate Upward push ---\n                // Cost: r + 1 operations. An Oni at (r,c) moves up to (0,c) in 'r' steps, and then is removed by the (r+1)th UP shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k < r. This is checked by !has_fuku_above[r][c].\n                if (!has_fuku_above[r][c]) {\n                    int cost = r + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'U'; // Upward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Downward push ---\n                // Cost: N - r operations. An Oni at (r,c) moves down to (N-1,c) in (N-1)-r steps, and then is removed by the (N-r)th DOWN shift.\n                // Safety: Requires no Fukunokami in column 'c' at any row k > r. This is checked by !has_fuku_below[r][c].\n                if (!has_fuku_below[r][c]) {\n                    int cost = n - r;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'D'; // Downward shift\n                        best_op_idx = c;     // Column index\n                    }\n                }\n\n                // --- Evaluate Leftward push ---\n                // Cost: c + 1 operations. An Oni at (r,c) moves left to (r,0) in 'c' steps, and then is removed by the (c+1)th LEFT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k < c. This is checked by !has_fuku_left[r][c].\n                if (!has_fuku_left[r][c]) {\n                    int cost = c + 1;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'L'; // Leftward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // --- Evaluate Rightward push ---\n                // Cost: N - c operations. An Oni at (r,c) moves right to (r,N-1) in (N-1)-c steps, and then is removed by the (N-c)th RIGHT shift.\n                // Safety: Requires no Fukunokami in row 'r' at any column k > c. This is checked by !has_fuku_right[r][c].\n                if (!has_fuku_right[r][c]) {\n                    int cost = n - c;\n                    if (cost < min_cost) {\n                        min_cost = cost;\n                        best_op_char = 'R'; // Rightward shift\n                        best_op_idx = r;     // Row index\n                    }\n                }\n\n                // The problem guarantees that for every Oni, at least one direction is safe.\n                // Thus, min_cost will be less than INF and greater than or equal to 1.\n                // We add 'min_cost' operations of the chosen type. This ensures each Oni is removed.\n                // The total number of operations T will be the sum of these minimum costs for each Oni.\n                // This greedy strategy aims to minimize T by making the locally optimal choice for each Oni.\n                for (int k = 0; k < min_cost; ++k) {\n                    operations.push_back({best_op_char, best_op_idx});\n                }\n            }\n        }\n    }\n\n    // Output the total number of operations.\n    cout << operations.size() << endl;\n    // Output each operation in the specified format.\n    for (const auto& op : operations) {\n        cout << op.first << \" \" << op.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <numeric>\n#include <cmath>\n#include <algorithm>\n\nusing namespace std;\n\nint N; // Number of employees\nlong long L; // Total number of weeks\nvector<long long> T; // Target counts for each employee\n\n// l_counts[i] = ceil(T[i] / 2.0)\n// r_counts[i] = floor(T[i] / 2.0)\n// These represent the number of times employee i directs the process\n// to a_i (if its count becomes odd) or b_i (if its count becomes even).\nvector<long long> l_counts; \nvector<long long> r_counts; \n\n// current_O[j] stores the total count of \"odd-parity\" assignments directed to employee j.\n// This sum comes from all i such that a_i = j, contributing l_counts[i].\nvector<long long> current_O; \n// current_E[j] stores the total count of \"even-parity\" assignments directed to employee j.\n// This sum comes from all i such that b_i = j, contributing r_counts[i].\nvector<long long> current_E; \n\n// a[i] and b[i] store the chosen successors for employee i.\nvector<int> a;\nvector<int> b;\n\n// Calculates the total error based on current O and E counts.\n// Error is sum of absolute differences between target T_j and actual assignments (O_j + E_j).\nlong long calculate_total_error() {\n    long long error = 0;\n    for (int j = 0; j < N; ++j) {\n        error += abs((current_O[j] + current_E[j]) - T[j]);\n    }\n    return error;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input\n    cin >> N >> L;\n    T.resize(N);\n    for (int i = 0; i < N; ++i) {\n        cin >> T[i];\n    }\n\n    // Precompute l_counts and r_counts for each employee\n    l_counts.resize(N);\n    r_counts.resize(N);\n    for (int i = 0; i < N; ++i) {\n        l_counts[i] = (T[i] + 1) / 2; // Equivalent to ceil(T[i] / 2.0)\n        r_counts[i] = T[i] / 2;      // Equivalent to floor(T[i] / 2.0)\n    }\n\n    current_O.resize(N, 0);\n    current_E.resize(N, 0);\n    a.resize(N);\n    b.resize(N);\n\n    // Initialize: each employee i initially directs assignments to itself.\n    // a[i] = i, b[i] = i.\n    // Update current_O and current_E based on this initial assignment.\n    for (int i = 0; i < N; ++i) {\n        a[i] = i;\n        b[i] = i;\n        current_O[i] += l_counts[i];\n        current_E[i] += r_counts[i];\n    }\n\n    // Calculate initial total error\n    long long current_total_error = calculate_total_error();\n\n    // The core of the solution is a local search heuristic.\n    // We iterate a fixed number of times. In each iteration, for each employee i,\n    // we try to find the best pair (u, v) for (a[i], b[i]) that minimizes the total error.\n    // The total number of iterations is a hyperparameter. For N=100, N^3 complexity per iteration\n    // implies a limit around 1000-2000 iterations to stay within time limits.\n    // We chose 1500 iterations as a balance between exploration and performance.\n    int num_iterations = 1500; \n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        bool improved_in_iter = false; // Flag to check if any improvement was made in this iteration\n\n        // Iterate through each employee i to potentially change their a[i] and b[i]\n        for (int i = 0; i < N; ++i) {\n            int old_a = a[i]; // Store old assignment for a[i]\n            int old_b = b[i]; // Store old assignment for b[i]\n            \n            // Keep track of the best assignment found so far for employee i in this iteration\n            int best_new_a = old_a;\n            int best_new_b = old_b;\n            long long min_err_for_i = current_total_error; // Minimum error achievable by changing a[i], b[i]\n\n            // Try all possible pairs (u, v) for (a[i], b[i])\n            for (int u = 0; u < N; ++u) { // New target for a[i]\n                for (int v = 0; v < N; ++v) { // New target for b[i]\n                    \n                    // Store current counts before modification for backtracking\n                    long long temp_O_old_a = current_O[old_a];\n                    long long temp_O_u = current_O[u];\n                    long long temp_E_old_b = current_E[old_b];\n                    long long temp_E_v = current_E[v];\n\n                    // --- Calculate potential new total error if a[i] becomes u and b[i] becomes v ---\n                    // We need to efficiently update current_O and current_E.\n                    // If old_a != u, the contribution of l_counts[i] shifts from old_a to u.\n                    // If old_b != v, the contribution of r_counts[i] shifts from old_b to v.\n                    \n                    // Revert contributions of old assignments\n                    if (old_a != u) {\n                        current_O[old_a] -= l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] -= r_counts[i];\n                    }\n                    \n                    // Apply new contributions\n                    if (old_a != u) {\n                        current_O[u] += l_counts[i];\n                    }\n                    if (old_b != v) {\n                        current_E[v] += r_counts[i];\n                    }\n\n                    // Handle cases where u == old_a or v == old_b.\n                    // If u == old_a, the l_counts[i] contribution remains at old_a, so current_O[old_a] and current_O[u] are unchanged relative to each other for THIS i's contribution.\n                    // The logic above handles this correctly: if old_a == u, we do not subtract from old_a and do not add to u, keeping them as they were.\n                    // Same applies for b[i] and v.\n                    // If u == v == old_a == old_b, no changes happen.\n\n                    // Calculate the new total error with these tentative assignments\n                    long long temp_error = calculate_total_error();\n\n                    // If this new assignment (u, v) results in a lower total error, update best found for i\n                    if (temp_error < min_err_for_i) {\n                        min_err_for_i = temp_error;\n                        best_new_a = u;\n                        best_new_b = v;\n                        improved_in_iter = true; // Mark that an improvement has been made\n                    }\n                    \n                    // --- Backtrack: restore counts to their state before trying this (u,v) pair ---\n                    // This is crucial because current_O and current_E are global and used for next (u,v) pair.\n                    if (old_a != u) {\n                        current_O[old_a] = temp_O_old_a; // Restore old_a's count\n                        current_O[u] = temp_O_u;         // Restore u's count\n                    }\n                    if (old_b != v) {\n                        current_E[old_b] = temp_E_old_b; // Restore old_b's count\n                        current_E[v] = temp_E_v;         // Restore v's count\n                    }\n                }\n            }\n            \n            // After trying all (u,v) for employee i, apply the best found assignment\n            if (min_err_for_i < current_total_error) {\n                // Update the global counts based on the best move for employee i\n                // First, remove the contribution of the old assignment\n                if (old_a != best_new_a) {\n                    current_O[old_a] -= l_counts[i];\n                    current_O[best_new_a] += l_counts[i];\n                }\n                if (old_b != best_new_b) {\n                    current_E[old_b] -= r_counts[i];\n                    current_E[best_new_b] += r_counts[i];\n                }\n                \n                // Update a[i] and b[i] to the best choice\n                a[i] = best_new_a;\n                b[i] = best_new_b;\n                current_total_error = min_err_for_i; // Update the global minimum error\n            }\n        }\n        // If no improvement was made in this iteration for any employee, we can stop early.\n        if (!improved_in_iter) {\n            break;\n        }\n    }\n\n    // Output the resulting a[i] and b[i] values\n    for (int i = 0; i < N; ++i) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <map>\n#include <numeric>\n#include <set>\n#include <string> // For potential error messages\n\n// Structure to hold city information\nstruct City {\n    int id;\n    long long lx, rx, ly, ry;\n    double est_x, est_y; // Estimated coordinates (center of bounding box)\n};\n\n// Structure to represent an edge with estimated weight for sorting\nstruct Edge {\n    int u, v;\n    long long weight; // Use estimated distance as weight\n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) {\n            return weight < other.weight;\n        }\n        if (u != other.u) {\n            return u < other.u;\n        }\n        return v < other.v;\n    }\n};\n\n// Disjoint Set Union (DSU) data structure for Kruskal's algorithm\nstruct DSU {\n    std::vector<int> parent;\n    DSU(int n) {\n        if (n < 0) {\n            std::cerr << \"DSU constructor received negative size: \" << n << std::endl;\n            exit(1); // Fatal error\n        }\n        parent.resize(n);\n        std::iota(parent.begin(), parent.end(), 0); // Initialize each node as its own parent\n    }\n    \n    int find(int i) {\n        if (i < 0 || static_cast<size_t>(i) >= parent.size()) {\n            std::cerr << \"DSU::find: Index out of bounds: i=\" << i << \", size=\" << parent.size() << std::endl;\n            exit(1); // Fatal error\n        }\n        if (parent[i] == i)\n            return i;\n        return parent[i] = find(parent[i]); // Path compression\n    }\n    \n    void unite(int i, int j) {\n        if (i < 0 || static_cast<size_t>(i) >= parent.size() || j < 0 || static_cast<size_t>(j) >= parent.size()) {\n             std::cerr << \"DSU::unite: Index out of bounds: i=\" << i << \", j=\" << j << \", size=\" << parent.size() << std::endl;\n             exit(1); // Fatal error\n        }\n        int root_i = find(i);\n        int root_j = find(j);\n        if (root_i != root_j) {\n            parent[root_i] = root_j; // Union by rank/size can be added for optimization\n        }\n    }\n};\n\n// Global variables\nint GLOBAL_N;\nstd::vector<City> GLOBAL_CITIES;\n\n// Function to query MST for a subset of cities\n// Returns a vector of pairs (u, v) representing MST edges.\n// IMPORTANT: For a subset of size 2, it returns the single edge connecting them.\nstd::vector<std::pair<int, int>> query_mst(const std::vector<int>& cities_subset) {\n    size_t subset_size = cities_subset.size();\n\n    // If subset has only 2 cities, the MST is the single edge between them.\n    // We do NOT query the judge for size 2 subsets, as it seems to cause issues.\n    // We return the edge directly. Its weight will be estimated later.\n    if (subset_size == 2) {\n        int u = cities_subset[0];\n        int v = cities_subset[1];\n        if (u > v) std::swap(u, v); // Ensure lexicographical order\n        return {{u, v}};\n    }\n    \n    // For subsets of size > 2, query the judge.\n    std::cout << \"? \" << subset_size;\n    for (int city_id : cities_subset) {\n        std::cout << \" \" << city_id;\n    }\n    std::cout << std::endl; // Flush output\n\n    std::vector<std::pair<int, int>> mst_edges;\n    // Read subset_size - 1 pairs of cities forming the MST\n    // This loop will run for subset_size > 2.\n    for (size_t i = 0; i < subset_size - 1; ++i) {\n        int u, v;\n        if (!(std::cin >> u >> v)) {\n            // This error condition should ideally not be reached for subset_size > 2.\n            // If it is, it indicates a problem with judge output for larger sets.\n            std::cerr << \"ERROR: Failed to read MST edge from judge for subset size \" << subset_size \n                      << \". Expected \" << subset_size - 1 << \" edges, but failed at edge \" << i << \".\" << std::endl;\n            exit(1); // Fatal error\n        }\n        \n        // Enhanced Validation (same as before)\n        bool u_valid_id = (u >= 0 && u < GLOBAL_N);\n        bool v_valid_id = (v >= 0 && v < GLOBAL_N);\n\n        if (!u_valid_id || !v_valid_id) {\n            std::cerr << \"ERROR: Received out-of-bounds city ID from judge. u=\" << u << \", v=\" << v << \", N=\" << GLOBAL_N << std::endl;\n            exit(1); // Fatal error\n        }\n        \n        bool u_in_subset = false;\n        bool v_in_subset = false;\n        for(int city_in_subset : cities_subset) {\n            if (city_in_subset == u) u_in_subset = true;\n            if (city_in_subset == v) v_in_subset = true;\n        }\n        if (!u_in_subset || !v_in_subset) {\n            std::cerr << \"ERROR: Received city ID not present in queried subset. u=\" << u << \", v=\" << v << std::endl;\n            std::cerr << \"Queried subset: \";\n            for(int city_id : cities_subset) std::cerr << city_id << \" \";\n            std::cerr << std::endl;\n            exit(1); // Fatal error\n        }\n        // End Enhanced Validation\n\n        if (u > v) std::swap(u, v); // Ensure lexicographical order\n        mst_edges.push_back({u, v});\n    }\n    return mst_edges;\n}\n\n// Calculate estimated Euclidean distance between two cities\nlong long estimated_dist(const City& c1, const City& c2) {\n    long long dx = static_cast<long long>(std::round(c1.est_x)) - static_cast<long long>(std::round(c2.est_x));\n    long long dy = static_cast<long long>(std::round(c1.est_y)) - static_cast<long long>(std::round(c2.est_y));\n    \n    long long squared_dist = dx * dx + dy * dy;\n    if (squared_dist < 0) squared_dist = 0; \n    \n    return static_cast<long long>(std::sqrt(static_cast<double>(squared_dist)));\n}\n\nint main() {\n    std::ios_base::sync_with_stdio(false);\n    std::cin.tie(NULL);\n\n    int N_val_input, M, Q, L, W;\n    std::cin >> N_val_input >> M >> Q >> L >> W;\n\n    GLOBAL_N = N_val_input;\n\n    std::vector<int> G(M);\n    for (int i = 0; i < M; ++i) {\n        std::cin >> G[i];\n    }\n\n    GLOBAL_CITIES.resize(GLOBAL_N);\n    std::vector<int> p(GLOBAL_N);\n    for (int i = 0; i < GLOBAL_N; ++i) {\n        GLOBAL_CITIES[i].id = i;\n        std::cin >> GLOBAL_CITIES[i].lx >> GLOBAL_CITIES[i].rx >> GLOBAL_CITIES[i].ly >> GLOBAL_CITIES[i].ry;\n        GLOBAL_CITIES[i].est_x = (GLOBAL_CITIES[i].lx + GLOBAL_CITIES[i].rx) / 2.0;\n        GLOBAL_CITIES[i].est_y = (GLOBAL_CITIES[i].ly + GLOBAL_CITIES[i].ry) / 2.0;\n        p[i] = i;\n    }\n\n    std::sort(p.begin(), p.end(), [&](int i, int j) {\n        if (GLOBAL_CITIES[i].est_x != GLOBAL_CITIES[j].est_x) {\n            return GLOBAL_CITIES[i].est_x < GLOBAL_CITIES[j].est_x;\n        }\n        return GLOBAL_CITIES[i].est_y < GLOBAL_CITIES[j].est_y;\n    });\n\n    std::vector<std::vector<int>> final_groups(M);\n    std::vector<int> city_to_group_idx(GLOBAL_N);\n    int current_city_p_idx = 0;\n    for (int k = 0; k < M; ++k) {\n        for (int i = 0; i < G[k]; ++i) {\n            int city_id = p[current_city_p_idx++];\n            final_groups[k].push_back(city_id);\n            city_to_group_idx[city_id] = k;\n        }\n    }\n\n    std::vector<Edge> collected_queried_edges;\n    std::set<std::pair<int, int>> queried_edge_pairs_set;\n    int queries_used = 0;\n\n    // Phase 1: Query entire groups if their size is within the limit L.\n    // IMPORTANT: We only query groups with size >= 3, as querying size 2 seems problematic.\n    // Groups of size 2 will rely on Kruskal's with estimated distances.\n    for (int k = 0; k < M; ++k) {\n        // Query only if group size is between 3 and L (inclusive), and we have queries left.\n        if (final_groups[k].size() >= 3 && final_groups[k].size() <= static_cast<size_t>(L) && static_cast<size_t>(queries_used) < static_cast<size_t>(Q)) {\n            std::vector<std::pair<int, int>> mst_edges = query_mst(final_groups[k]);\n            for (const auto& edge_pair : mst_edges) {\n                int u = edge_pair.first;\n                int v = edge_pair.second;\n                if (queried_edge_pairs_set.find({u, v}) == queried_edge_pairs_set.end()) {\n                    collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(GLOBAL_CITIES[u], GLOBAL_CITIES[v]))});\n                    queried_edge_pairs_set.insert({u, v});\n                }\n            }\n            queries_used++;\n        }\n    }\n\n    // Phase 2: Use remaining queries for sliding windows of size L.\n    // L is guaranteed to be >= 3, so these subsets will always have size >= 3.\n    int num_windows_to_query = std::min(Q - queries_used, GLOBAL_N); \n    for (int i = 0; i < num_windows_to_query; ++i) {\n        std::vector<int> subset;\n        for (int j = 0; j < L; ++j) {\n            subset.push_back(p[(i + j) % GLOBAL_N]);\n        }\n        // subset.size() will be L, which is >= 3.\n        std::vector<std::pair<int, int>> mst_edges = query_mst(subset);\n        for (const auto& edge_pair : mst_edges) {\n            int u = edge_pair.first;\n            int v = edge_pair.second;\n            if (queried_edge_pairs_set.find({u, v}) == queried_edge_pairs_set.end()) {\n                collected_queried_edges.push_back({u, v, static_cast<int>(estimated_dist(GLOBAL_CITIES[u], GLOBAL_CITIES[v]))});\n                queried_edge_pairs_set.insert({u, v});\n            }\n        }\n    }\n\n    // Collect all potential edges for building final MSTs.\n    std::vector<Edge> all_candidate_edges;\n    // Add all edges collected from queries.\n    for(const auto& edge : collected_queried_edges) {\n        all_candidate_edges.push_back(edge);\n    }\n\n    // Add edges for pairs of cities that were NOT part of any queried subset.\n    // For groups of size 2, this is where the single edge will be implicitly considered\n    // when Kruskal's algorithm runs, if it's not covered by queried edges.\n    for(int i = 0; i < GLOBAL_N; ++i) {\n        for(int j = i + 1; j < GLOBAL_N; ++j) {\n            if(queried_edge_pairs_set.find({i, j}) == queried_edge_pairs_set.end()) {\n                all_candidate_edges.push_back({i, j, static_cast<int>(estimated_dist(GLOBAL_CITIES[i], GLOBAL_CITIES[j]))});\n            }\n        }\n    }\n    \n    std::sort(all_candidate_edges.begin(), all_candidate_edges.end());\n\n    // Build the Minimum Spanning Tree (MST) for each group.\n    std::vector<std::vector<std::pair<int, int>>> final_group_edges(M);\n    for (int k = 0; k < M; ++k) { // For each group k\n        // Groups of size 1 need no edges.\n        if (G[k] == 1) continue;\n\n        // Groups of size 2 require exactly one edge. If this edge wasn't in queried_edge_pairs_set,\n        // it will be added here if it's the shortest available edge.\n        // We don't query size 2 groups, so they rely solely on Kruskal's and estimated distances.\n\n        DSU dsu(GLOBAL_N); \n        \n        for (const auto& edge : all_candidate_edges) {\n            // Stop if we have enough edges for this group.\n            if (final_group_edges[k].size() >= static_cast<size_t>(G[k] - 1)) break;\n\n            int u = edge.u;\n            int v = edge.v;\n\n            // Check if both endpoints belong to the current group `k`.\n            if (city_to_group_idx[u] == k && city_to_group_idx[v] == k) {\n                // If adding this edge does not create a cycle within the current group's MST.\n                if (dsu.find(u) != dsu.find(v)) {\n                    dsu.unite(u, v);\n                    final_group_edges[k].push_back({u, v});\n                }\n            }\n        }\n    }\n\n    // Output the final answer.\n    std::cout << \"!\" << std::endl;\n    for (int k = 0; k < M; ++k) {\n        for (int city_id : final_groups[k]) {\n            std::cout << city_id << \" \";\n        }\n        std::cout << std::endl;\n        \n        for (const auto& edge : final_group_edges[k]) {\n            std::cout << edge.first << \" \" << edge.second << std::endl;\n        }\n    }\n\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <cmath>\n#include <tuple>\n#include <algorithm>\n#include <map>\n\nusing namespace std;\n\n// Global variables to store game state and parameters\nint N; // Size of the skating rink (N x N)\nint M; // Total number of points given in input (start position + M-1 targets)\nvector<pair<int, int>> all_points; // Stores all M points: start and targets\nset<pair<int, int>> blocks; // Stores coordinates of all placed blocks\npair<int, int> current_pos; // Current position of the player\n\n// --- Helper Functions ---\n\n// Checks if a given coordinate (r, c) is within the N x N grid boundaries.\nbool is_valid(int r, int c) {\n    return r >= 0 && r < N && c >= 0 && c < N;\n}\n\n// Returns the change in (row, column) for a given direction character.\npair<int, int> get_delta(char dir) {\n    if (dir == 'U') return {-1, 0}; // Up: decrease row\n    if (dir == 'D') return {1, 0};  // Down: increase row\n    if (dir == 'L') return {0, -1}; // Left: decrease column\n    if (dir == 'R') return {0, 1};  // Right: increase column\n    return {0, 0}; // Should not happen with valid input\n}\n\n// --- Game Simulation and Action Execution ---\n\n// Executes a chosen action and direction.\n// This function simulates the action's effect on the game state (current_pos, blocks)\n// and prints the action to standard output for the judge system.\nvoid execute_action(char action, char dir) {\n    pair<int, int> delta = get_delta(dir);\n    int dx = delta.first;\n    int dy = delta.second;\n\n    if (action == 'M') { // Move action\n        // Update current position by one step in the given direction.\n        current_pos.first += dx;\n        current_pos.second += dy;\n        cout << action << ' ' << dir << endl;\n    } else if (action == 'A') { // Alter action\n        // Calculate the coordinates of the adjacent square to alter.\n        int alter_r = current_pos.first + dx;\n        int alter_c = current_pos.second + dy;\n        \n        // Ensure the target square for alteration is within bounds.\n        if (is_valid(alter_r, alter_c)) {\n            // If a block exists, remove it. Otherwise, place a new block.\n            if (blocks.count({alter_r, alter_c})) {\n                blocks.erase({alter_r, alter_c});\n            } else {\n                blocks.insert({alter_r, alter_c});\n            }\n        }\n        cout << action << ' ' << dir << endl;\n        // The player's position (current_pos) does not change during an Alter action.\n    } else if (action == 'S') { // Slide action\n        int cx = current_pos.first;\n        int cy = current_pos.second;\n        int slide_dist = 0;\n        \n        // Simulate the slide step-by-step to determine how far it goes.\n        // The slide stops just before hitting a block or going out of bounds.\n        for (int k = 1; ; ++k) {\n            int r = cx + k * dx;\n            int c = cy + k * dy;\n            \n            // Stop if the next square is out of bounds or contains a block.\n            if (!is_valid(r, c) || blocks.count({r, c})) {\n                slide_dist = k - 1; // The actual distance slid is k-1 squares.\n                break;\n            }\n            // Note: The problem states \"If you slide over a target square without stopping on it, it is not considered visited.\"\n            // This means the slide continues until a block/boundary, even if it passes targets.\n            // Our simulation accurately finds the stopping point.\n        }\n        \n        // Update current position by the calculated slide distance.\n        current_pos.first += slide_dist * dx;\n        current_pos.second += slide_dist * dy;\n        cout << action << ' ' << dir << endl;\n    }\n}\n\n// --- Main Logic ---\n\nint main() {\n    // Optimize standard I/O operations.\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    // Read input parameters: grid size N and number of points M.\n    cin >> N >> M; \n    // M points are provided: (i_0, j_0) is the starting position,\n    // and (i_1, j_1) through (i_{M-1}, j_{M-1}) are the M-1 targets to visit in sequence.\n    all_points.resize(M);\n    for (int i = 0; i < M; ++i) {\n        cin >> all_points[i].first >> all_points[i].second;\n    }\n\n    // Initialize the player's current position to the starting point.\n    current_pos = all_points[0]; \n\n    // Iterate through each target point that needs to be visited.\n    // The targets are all_points[1] up to all_points[M-1].\n    for (int target_idx = 1; target_idx < M; ++target_idx) {\n        pair<int, int> target_pos = all_points[target_idx]; // The current target to reach.\n\n        // Keep planning and executing actions until the current position matches the target position.\n        while (current_pos != target_pos) {\n            int cx = current_pos.first;\n            int cy = current_pos.second;\n            int tx = target_pos.first;\n            int ty = target_pos.second;\n\n            // --- Determine Primary Direction to Move ---\n            char dir_char = ' ';\n            int dr = tx - cx; // Row difference\n            int dc = ty - cy; // Column difference\n\n            // Decide the primary direction:\n            // If the row difference is larger, prioritize vertical movement (Up/Down).\n            // Otherwise, prioritize horizontal movement (Left/Right).\n            // If row and column differences are equal, prioritize horizontal movement.\n            if (abs(dr) > abs(dc)) {\n                if (dr > 0) dir_char = 'D'; // Target is below\n                else dir_char = 'U';        // Target is above\n            } else { \n                if (dc > 0) dir_char = 'R'; // Target is to the right\n                else dir_char = 'L';        // Target is to the left\n            }\n\n            pair<int, int> delta = get_delta(dir_char);\n            int dx = delta.first;\n            int dy = delta.second;\n\n            // Calculate the position of the immediate next square in the chosen direction.\n            int next_r = cx + dx;\n            int next_c = cy + dy;\n\n            // Check if the target square itself contains a block.\n            bool is_target_blocked = blocks.count({tx, ty});\n            char action_to_take = ' '; // Variable to store the determined action.\n\n            // --- Decision Logic for Choosing Action ---\n\n            // Case 1: The target square is blocked AND we are exactly one step away from it.\n            // To visit the target, we must first remove the block.\n            if ((next_r == tx && next_c == ty) && is_target_blocked) {\n                action_to_take = 'A'; // Use Alter to remove the block at the target.\n            }\n            // Case 2: The very next square in our primary direction is blocked.\n            // This means there's an intermediate obstacle. We must clear it to proceed.\n            else if (blocks.count({next_r, next_c})) {\n                action_to_take = 'A'; // Use Alter to remove the intermediate block.\n            }\n            // Case 3: The next square is clear.\n            else {\n                // Calculate the Manhattan distance to the target.\n                int distance_to_target = abs(tx - cx) + abs(ty - cy);\n\n                // Heuristic strategy:\n                // For longer distances (heuristic threshold of 4), and if the target is clear,\n                // using Slide is more efficient for covering ground quickly.\n                // For shorter distances, or if the target is blocked (and we are not adjacent),\n                // using Move provides better precision and control.\n                if (distance_to_target > 4 && !is_target_blocked) {\n                    action_to_take = 'S'; // Prefer Slide for longer distances.\n                } else {\n                    action_to_take = 'M'; // Prefer Move for shorter distances or when target is blocked.\n                }\n            }\n            \n            // Execute the chosen action. This prints the action/direction and updates the game state.\n            execute_action(action_to_take, dir_char);\n        }\n    }\n\n    return 0; // Program finishes after all targets are visited.\n}"}}}