{"model_name":"glm-4.5","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;  // (a, b) and (c, d) are diagonal vertices\n    \n    Rectangle(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {\n        if (a > c) swap(a, c);\n        if (b > d) swap(b, d);\n    }\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(int x, int y) const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n    \n    int overlap_area(const Rectangle& other) const {\n        int overlap_a = max(a, other.a);\n        int overlap_b = max(b, other.b);\n        int overlap_c = min(c, other.c);\n        int overlap_d = min(d, other.d);\n        \n        if (overlap_a >= overlap_c || overlap_b >= overlap_d) return 0;\n        return (overlap_c - overlap_a) * (overlap_d - overlap_b);\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rectangle rect;\n    \n    double satisfaction() const {\n        int s = rect.area();\n        if (!rect.contains(x, y)) return 0.0;\n        \n        double min_val = min(r, s);\n        double max_val = max(r, s);\n        return 1.0 - pow(1.0 - min_val / max_val, 2);\n    }\n};\n\nvector<Rectangle> solve(int n, const vector<pair<int, int>>& points, const vector<int>& rs) {\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        companies[i].x = points[i].first;\n        companies[i].y = points[i].second;\n        companies[i].r = rs[i];\n    }\n    \n    // Sort companies by desired area (largest first)\n    vector<int> indices(n);\n    for (int i = 0; i < n; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return companies[i].r > companies[j].r;\n    });\n    \n    // Create a space-filling curve based initial placement\n    vector<pair<int, int>> space_order;\n    for (int y = 0; y < 100; ++y) {\n        for (int x = 0; x < 100; ++x) {\n            space_order.emplace_back(x, y);\n        }\n    }\n    \n    // Shuffle the space order for better distribution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(space_order.begin(), space_order.end(), rng);\n    \n    // Initialize rectangles\n    vector<Rectangle> placed_rectangles;\n    for (int i : indices) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Find dimensions that give area close to r\n        int w = min(10000, static_cast<int>(sqrt(r)) + 1);\n        int h = r / w;\n        if (w * h < r) h++;\n        \n        // Try to place the rectangle at different positions\n        Rectangle best_rect;\n        double best_score = -1.0;\n        \n        // Try positions based on the space order\n        for (const auto& pos : space_order) {\n            int base_x = pos.first * 100;\n            int base_y = pos.second * 100;\n            \n            // Try to place the rectangle with the desired point inside\n            int a = max(0, min(base_x, x - w/2));\n            int c = min(10000, a + w);\n            if (c - a < w) a = c - w;\n            \n            int b = max(0, min(base_y, y - h/2));\n            int d = min(10000, b + h);\n            if (d - b < h) b = d - h;\n            \n            Rectangle rect(a, b, c, d);\n            \n            // Check if the rectangle contains the desired point\n            if (!rect.contains(x, y)) continue;\n            \n            // Check for overlaps with already placed rectangles\n            bool has_overlap = false;\n            for (const auto& placed : placed_rectangles) {\n                if (rect.overlaps(placed)) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            \n            if (!has_overlap) {\n                // Calculate a score based on how close the area is to the desired area\n                int area = rect.area();\n                double score = 1.0 - abs(area - r) / max(area, r);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect;\n                }\n            }\n        }\n        \n        // If we couldn't find a non-overlapping position, use a minimal rectangle\n        if (best_score < 0) {\n            best_rect = Rectangle(x, y, x + 1, y + 1);\n        }\n        \n        companies[i].rect = best_rect;\n        placed_rectangles.push_back(best_rect);\n    }\n    \n    // Resolve overlaps iteratively\n    const int MAX_ITERATIONS = 100;\n    for (int iter = 0; iter < MAX_ITERATIONS; ++iter) {\n        bool has_overlap = false;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = i + 1; j < n; ++j) {\n                if (companies[i].rect.overlaps(companies[j].rect)) {\n                    has_overlap = true;\n                    \n                    // Calculate overlap area\n                    int overlap_area = companies[i].rect.overlap_area(companies[j].rect);\n                    \n                    // Resolve overlap by shrinking the rectangle with smaller desired area\n                    if (companies[i].r < companies[j].r) {\n                        // Shrink company i's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_i.a < rect_j.a) {\n                                rect_i.c = min(rect_i.c, rect_j.a);\n                            } else {\n                                rect_i.a = max(rect_i.a, rect_j.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_i.b < rect_j.b) {\n                                rect_i.d = min(rect_i.d, rect_j.b);\n                            } else {\n                                rect_i.b = max(rect_i.b, rect_j.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                            // Try a different approach\n                            rect_i = companies[i].rect;\n                            if (rect_j.a < rect_i.a) {\n                                rect_i.a = rect_j.c;\n                            } else {\n                                rect_i.c = rect_j.a;\n                            }\n                            \n                            if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_i = Rectangle(companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1);\n                            }\n                        }\n                    } else {\n                        // Shrink company j's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_j.a < rect_i.a) {\n                                rect_j.c = min(rect_j.c, rect_i.a);\n                            } else {\n                                rect_j.a = max(rect_j.a, rect_i.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_j.b < rect_i.b) {\n                                rect_j.d = min(rect_j.d, rect_i.b);\n                            } else {\n                                rect_j.b = max(rect_j.b, rect_i.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                            // Try a different approach\n                            rect_j = companies[j].rect;\n                            if (rect_i.a < rect_j.a) {\n                                rect_j.a = rect_i.c;\n                            } else {\n                                rect_j.c = rect_i.a;\n                            }\n                            \n                            if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_j = Rectangle(companies[j].x, companies[j].y, companies[j].x + 1, companies[j].y + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!has_overlap) break;\n    }\n    \n    // Final optimization using simulated annealing\n    rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n    double temperature = 100.0;\n    const double COOLING_RATE = 0.95;\n    const int SA_ITERATIONS = 1000;\n    \n    double current_score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        current_score += companies[i].satisfaction();\n    }\n    \n    for (int iter = 0; iter < SA_ITERATIONS; ++iter) {\n        temperature *= COOLING_RATE;\n        \n        // Choose a random company to modify\n        int i = rng() % n;\n        Rectangle old_rect = companies[i].rect;\n        double old_satisfaction = companies[i].satisfaction();\n        \n        // Choose a random modification\n        int mod_type = rng() % 8;\n        \n        switch (mod_type) {\n            case 0: {  // Move left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                companies[i].rect.c -= delta;\n                break;\n            }\n            case 1: {  // Move right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.a += delta;\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 2: {  // Move up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                companies[i].rect.d -= delta;\n                break;\n            }\n            case 3: {  // Move down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.b += delta;\n                companies[i].rect.d += delta;\n                break;\n            }\n            case 4: {  // Expand left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                break;\n            }\n            case 5: {  // Expand right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 6: {  // Expand up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                break;\n            }\n            case 7: {  // Expand down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.d += delta;\n                break;\n            }\n        }\n        \n        // Check constraints\n        bool valid = true;\n        \n        // Check if the rectangle still contains the desired point\n        if (!companies[i].rect.contains(companies[i].x, companies[i].y)) {\n            valid = false;\n        }\n        \n        // Check for overlaps\n        if (valid) {\n            for (int j = 0; j < n; ++j) {\n                if (i != j && companies[i].rect.overlaps(companies[j].rect)) {\n                    valid = false;\n                    break;\n                }\n            }\n        }\n        \n        if (valid) {\n            double new_satisfaction = companies[i].satisfaction();\n            double delta_score = new_satisfaction - old_satisfaction;\n            \n            // Accept or reject the move based on simulated annealing\n            if (delta_score > 0 || exp(delta_score / temperature) > (rng() % 1000) / 1000.0) {\n                current_score += delta_score;\n            } else {\n                companies[i].rect = old_rect;\n            }\n        } else {\n            companies[i].rect = old_rect;\n        }\n    }\n    \n    // Extract the final rectangles\n    vector<Rectangle> result;\n    for (int i = 0; i < n; ++i) {\n        result.push_back(companies[i].rect);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<pair<int, int>> points(n);\n    vector<int> rs(n);\n    \n    for (int i = 0; i < n; ++i) {\n        cin >> points[i].first >> points[i].second >> rs[i];\n    }\n    \n    vector<Rectangle> solution = solve(n, points, rs);\n    \n    for (const auto& rect : solution) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Tile {\n    int id;\n    vector<pair<int, int>> squares;\n    int total_value;\n    set<int> adjacent_tiles;\n    bool is_1x1;\n    pair<int, int> other_square;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tiles(50, vector<int>(50));\n    vector<vector<int>> points(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tiles[i][j];\n        }\n    }\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> points[i][j];\n        }\n    }\n    \n    // Build tile information\n    map<int, Tile> tile_map;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int tile_id = tiles[i][j];\n            if (tile_map.find(tile_id) == tile_map.end()) {\n                tile_map[tile_id] = {tile_id, {}, 0, {}, true, {-1, -1}};\n            }\n            tile_map[tile_id].squares.emplace_back(i, j);\n            tile_map[tile_id].total_value += points[i][j];\n        }\n    }\n    \n    // Determine tile types and other square\n    for (auto& [id, tile] : tile_map) {\n        if (tile.squares.size() == 2) {\n            tile.is_1x1 = false;\n            if (tile.squares[0].first == tile.squares[1].first) {\n                // 1x2 tile\n                if (tile.squares[0].second < tile.squares[1].second) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            } else {\n                // 2x1 tile\n                if (tile.squares[0].first < tile.squares[1].first) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            }\n        }\n    }\n    \n    // Build adjacency information\n    for (auto& [id, tile] : tile_map) {\n        for (auto& [i, j] : tile.squares) {\n            vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n            for (auto& [di, dj] : directions) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int neighbor_tile_id = tiles[ni][nj];\n                    if (neighbor_tile_id != id) {\n                        tile.adjacent_tiles.insert(neighbor_tile_id);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Start tile\n    int start_tile_id = tiles[si][sj];\n    set<int> visited_tiles;\n    visited_tiles.insert(start_tile_id);\n    int current_i = si, current_j = sj;\n    string path;\n    \n    // If starting tile is 1x2 or 2x1, move to the other square\n    if (!tile_map[start_tile_id].is_1x1) {\n        auto [oi, oj] = tile_map[start_tile_id].other_square;\n        if (oi < current_i) {\n            path += 'U';\n            current_i = oi;\n        } else if (oi > current_i) {\n            path += 'D';\n            current_i = oi;\n        } else if (oj < current_j) {\n            path += 'L';\n            current_j = oj;\n        } else if (oj > current_j) {\n            path += 'R';\n            current_j = oj;\n        }\n    }\n    \n    // Greedy walk with probabilistic selection\n    random_device rd;\n    mt19937 gen(rd());\n    \n    while (true) {\n        vector<pair<int, pair<char, pair<int, int>>>> candidates;\n        \n        vector<pair<char, pair<int, int>>> directions = {\n            {'U', {-1, 0}}, {'D', {1, 0}}, {'L', {0, -1}}, {'R', {0, 1}}\n        };\n        \n        for (auto& [dir, delta] : directions) {\n            int ni = current_i + delta.first;\n            int nj = current_j + delta.second;\n            \n            if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                int next_tile_id = tiles[ni][nj];\n                \n                if (visited_tiles.find(next_tile_id) == visited_tiles.end()) {\n                    int score = tile_map[next_tile_id].total_value;\n                    \n                    // Consider connectivity\n                    int adjacent_unvisited = 0;\n                    for (int adj_id : tile_map[next_tile_id].adjacent_tiles) {\n                        if (visited_tiles.find(adj_id) == visited_tiles.end()) {\n                            adjacent_unvisited++;\n                        }\n                    }\n                    \n                    score += adjacent_unvisited * 10;  // Weight for connectivity\n                    candidates.emplace_back(score, make_pair(dir, make_pair(ni, nj)));\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Probabilistic selection\n        vector<double> probabilities;\n        for (int i = 0; i < candidates.size(); ++i) {\n            probabilities.push_back(pow(0.8, i));\n        }\n        \n        double sum_probs = accumulate(probabilities.begin(), probabilities.end(), 0.0);\n        for (double& prob : probabilities) {\n            prob /= sum_probs;\n        }\n        \n        uniform_real_distribution<> dis(0.0, 1.0);\n        double r = dis(gen);\n        double cumulative = 0.0;\n        int selected_idx = 0;\n        \n        for (int i = 0; i < probabilities.size(); ++i) {\n            cumulative += probabilities[i];\n            if (r <= cumulative) {\n                selected_idx = i;\n                break;\n            }\n        }\n        \n        auto& [score, move_info] = candidates[selected_idx];\n        auto& [dir, next_pos] = move_info;\n        auto& [ni, nj] = next_pos;\n        \n        int next_tile_id = tiles[ni][nj];\n        \n        path += dir;\n        visited_tiles.insert(next_tile_id);\n        current_i = ni;\n        current_j = nj;\n        \n        // If tile is 1x2 or 2x1, move to the other square\n        if (!tile_map[next_tile_id].is_1x1) {\n            auto [oi, oj] = tile_map[next_tile_id].other_square;\n            if (oi != ni || oj != nj) {\n                if (oi < ni) {\n                    path += 'U';\n                    current_i = oi;\n                } else if (oi > ni) {\n                    path += 'D';\n                    current_i = oi;\n                } else if (oj < nj) {\n                    path += 'L';\n                    current_j = oj;\n                } else if (oj > nj) {\n                    path += 'R';\n                    current_j = oj;\n                }\n            }\n        }\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <functional>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\nint main() {\n    vector<vector<double>> hor_est(N, vector<double>(N-1, 5000.0));\n    vector<vector<double>> ver_est(N-1, vector<double>(N, 5000.0));\n\n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        vector<vector<double>> dist(N, vector<double>(N, 1e18));\n        vector<vector<tuple<int, int, char>>> parent(N, vector<tuple<int, int, char>>(N, make_tuple(-1, -1, ' ')));\n        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (i == ti && j == tj) {\n                break;\n            }\n            if (d > dist[i][j]) {\n                continue;\n            }\n\n            if (i > 0) {\n                double w = ver_est[i-1][j];\n                if (d + w < dist[i-1][j]) {\n                    dist[i-1][j] = d + w;\n                    parent[i-1][j] = make_tuple(i, j, 'U');\n                    pq.push({dist[i-1][j], i-1, j});\n                }\n            }\n            if (i < N-1) {\n                double w = ver_est[i][j];\n                if (d + w < dist[i+1][j]) {\n                    dist[i+1][j] = d + w;\n                    parent[i+1][j] = make_tuple(i, j, 'D');\n                    pq.push({dist[i+1][j], i+1, j});\n                }\n            }\n            if (j > 0) {\n                double w = hor_est[i][j-1];\n                if (d + w < dist[i][j-1]) {\n                    dist[i][j-1] = d + w;\n                    parent[i][j-1] = make_tuple(i, j, 'L');\n                    pq.push({dist[i][j-1], i, j-1});\n                }\n            }\n            if (j < N-1) {\n                double w = hor_est[i][j];\n                if (d + w < dist[i][j+1]) {\n                    dist[i][j+1] = d + w;\n                    parent[i][j+1] = make_tuple(i, j, 'R');\n                    pq.push({dist[i][j+1], i, j+1});\n                }\n            }\n        }\n\n        string path_str = \"\";\n        int i = ti, j = tj;\n        while (i != si || j != sj) {\n            auto [pi, pj, dir] = parent[i][j];\n            path_str += dir;\n            i = pi;\n            j = pj;\n        }\n        reverse(path_str.begin(), path_str.end());\n\n        cout << path_str << endl;\n        cout.flush();\n\n        int y;\n        cin >> y;\n\n        double L_est = 0.0;\n        vector<double*> edges_in_path;\n        i = si; j = sj;\n        for (char c : path_str) {\n            if (c == 'U') {\n                L_est += ver_est[i-1][j];\n                edges_in_path.push_back(&ver_est[i-1][j]);\n                i--;\n            } else if (c == 'D') {\n                L_est += ver_est[i][j];\n                edges_in_path.push_back(&ver_est[i][j]);\n                i++;\n            } else if (c == 'L') {\n                L_est += hor_est[i][j-1];\n                edges_in_path.push_back(&hor_est[i][j-1]);\n                j--;\n            } else if (c == 'R') {\n                L_est += hor_est[i][j];\n                edges_in_path.push_back(&hor_est[i][j]);\n                j++;\n            }\n        }\n\n        int m = edges_in_path.size();\n        double error = y - L_est;\n        for (double* ptr : edges_in_path) {\n            *ptr += 0.1 * error / m;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <array>\n\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int N = 20;\nconstexpr char EMPTY = '.';\nconstexpr array<char, 8> CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Problem {\n    int M;\n    vector<string> strings;\n    vector<array<array<int, 8>, N>> char_freq;\n    vector<int> string_importance;\n    \n    Problem(int M, const vector<string>& strings) : M(M), strings(strings) {\n        char_freq.resize(N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char_freq[i][j].fill(0);\n            }\n        }\n        \n        string_importance.resize(M);\n        for (int i = 0; i < M; i++) {\n            string_importance[i] = strings[i].size();\n        }\n        \n        for (int idx = 0; idx < M; idx++) {\n            const auto& s = strings[idx];\n            int k = s.size();\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int p = 0; p < min(k, N); p++) {\n                        int c = s[p] - 'A';\n                        char_freq[i][(j + p) % N][c] += string_importance[idx];\n                        char_freq[(i + p) % N][j][c] += string_importance[idx];\n                    }\n                }\n            }\n        }\n    }\n};\n\nstruct Solution {\n    vector<string> matrix;\n    vector<bool> satisfied;\n    int score;\n    int satisfied_count;\n    int empty_count;\n    \n    Solution() : matrix(N, string(N, EMPTY)), score(0), satisfied_count(0), empty_count(N*N) {}\n    \n    void fill_based_on_freq(const Problem& problem) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == EMPTY) {\n                    int max_freq = -1;\n                    char best_char = EMPTY;\n                    for (int c = 0; c < 8; c++) {\n                        if (problem.char_freq[i][j][c] > max_freq) {\n                            max_freq = problem.char_freq[i][j][c];\n                            best_char = 'A' + c;\n                        }\n                    }\n                    if (best_char != EMPTY) {\n                        matrix[i][j] = best_char;\n                    }\n                }\n            }\n        }\n        empty_count = 0;\n    }\n    \n    void random_partial_fill(double fill_ratio) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        int fill_count = static_cast<int>(N * N * fill_ratio);\n        vector<pair<int, int>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                positions.emplace_back(i, j);\n            }\n        }\n        shuffle(positions.begin(), positions.end(), rng);\n        for (int k = 0; k < fill_count; k++) {\n            auto [i, j] = positions[k];\n            matrix[i][j] = CHARS[char_dist(rng)];\n        }\n        empty_count = N * N - fill_count;\n    }\n    \n    bool is_subsequence(const string& s) const {\n        int k = s.size();\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                bool match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[i][(j + p) % N] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n                \n                match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[(i + p) % N][j] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    int calculate_score(const Problem& problem) {\n        satisfied.resize(problem.M);\n        satisfied_count = 0;\n        for (int i = 0; i < problem.M; i++) {\n            satisfied[i] = is_subsequence(problem.strings[i]);\n            if (satisfied[i]) {\n                satisfied_count++;\n            }\n        }\n        \n        if (satisfied_count < problem.M) {\n            score = static_cast<int>(round(1e8 * static_cast<double>(satisfied_count) / problem.M));\n        } else {\n            score = static_cast<int>(round(1e8 * (2.0 * N * N) / (2.0 * N * N - empty_count)));\n        }\n        \n        return score;\n    }\n    \n    void mutate(const Problem& problem) {\n        uniform_int_distribution<int> pos_dist(0, N-1);\n        uniform_int_distribution<int> char_dist(0, 7);\n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        double r = real_dist(rng);\n        \n        if (r < 0.6) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            if (matrix[i][j] != EMPTY) {\n                matrix[i][j] = CHARS[char_dist(rng)];\n            }\n        } else if (r < 0.8) {\n            int i1 = pos_dist(rng);\n            int j1 = pos_dist(rng);\n            int i2 = pos_dist(rng);\n            int j2 = pos_dist(rng);\n            swap(matrix[i1][j1], matrix[i2][j2]);\n        } else if (r < 0.9) {\n            if (real_dist(rng) < 0.5) {\n                int i = pos_dist(rng);\n                int shift = pos_dist(rng);\n                rotate(matrix[i].begin(), matrix[i].begin() + shift, matrix[i].end());\n            } else {\n                int j = pos_dist(rng);\n                int shift = pos_dist(rng);\n                vector<char> column(N);\n                for (int i = 0; i < N; i++) {\n                    column[i] = matrix[i][j];\n                }\n                rotate(column.begin(), column.begin() + shift, column.end());\n                for (int i = 0; i < N; i++) {\n                    matrix[i][j] = column[i];\n                }\n            }\n        } else {\n            vector<int> unsatisfied;\n            for (int i = 0; i < problem.M; i++) {\n                if (!satisfied[i]) {\n                    unsatisfied.push_back(i);\n                }\n            }\n            \n            if (!unsatisfied.empty()) {\n                uniform_int_distribution<int> unsat_dist(0, unsatisfied.size()-1);\n                int idx = unsatisfied[unsat_dist(rng)];\n                const string& s = problem.strings[idx];\n                int k = s.size();\n                \n                int i = pos_dist(rng);\n                int j = pos_dist(rng);\n                if (real_dist(rng) < 0.5) {\n                    for (int p = 0; p < k; p++) {\n                        matrix[i][(j + p) % N] = s[p];\n                    }\n                } else {\n                    for (int p = 0; p < k; p++) {\n                        matrix[(i + p) % N][j] = s[p];\n                    }\n                }\n            }\n        }\n    }\n    \n    void print() const {\n        for (const auto& row : matrix) {\n            cout << row << endl;\n        }\n    }\n};\n\nSolution solve(const Problem& problem) {\n    Solution best_solution;\n    int best_score = 0;\n    \n    vector<int> sorted_indices(problem.M);\n    for (int i = 0; i < problem.M; i++) {\n        sorted_indices[i] = i;\n    }\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return problem.string_importance[a] > problem.string_importance[b];\n    });\n    \n    for (int trial = 0; trial < 5; trial++) {\n        Solution solution;\n        \n        double fill_ratio = 0.3 + 0.1 * trial;\n        solution.random_partial_fill(fill_ratio);\n        solution.fill_based_on_freq(problem);\n        \n        for (int i = 0; i < min(30, problem.M); i++) {\n            int idx = sorted_indices[i];\n            const string& s = problem.strings[idx];\n            int k = s.size();\n            \n            uniform_int_distribution<int> pos_dist(0, N-1);\n            uniform_real_distribution<double> real_dist(0.0, 1.0);\n            int row = pos_dist(rng);\n            int col = pos_dist(rng);\n            \n            if (real_dist(rng) < 0.5) {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[row][(col + p) % N] = s[p];\n                }\n            } else {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[(row + p) % N][col] = s[p];\n                }\n            }\n        }\n        \n        solution.empty_count = 0;\n        int current_score = solution.calculate_score(problem);\n        \n        double temperature = 100.0;\n        double cooling_rate = 0.995;\n        int iterations = 15000;\n        \n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            Solution new_solution = solution;\n            new_solution.mutate(problem);\n            int new_score = new_solution.calculate_score(problem);\n            \n            if (new_score > current_score || real_dist(rng) < exp((new_score - current_score) / temperature)) {\n                solution = new_solution;\n                current_score = new_score;\n                \n                if (current_score > best_score) {\n                    best_solution = solution;\n                    best_score = current_score;\n                }\n            }\n            \n            temperature *= cooling_rate;\n            \n            if (iter % 1000 == 0) {\n                temperature = max(temperature, 1.0);\n            }\n        }\n    }\n    \n    if (best_solution.satisfied_count < problem.M) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_solution.matrix[i][j] == EMPTY) {\n                    best_solution.matrix[i][j] = CHARS[char_dist(rng)];\n                }\n            }\n        }\n        best_solution.empty_count = 0;\n        best_solution.calculate_score(problem);\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    cin >> M;\n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Problem problem(M, strings);\n    Solution solution = solve(problem);\n    solution.print();\n    \n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <list>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <unordered_map>\n#include <unordered_set>\n#include <string>\n#include <utility>\n#include <array>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    Point(int i_=0, int j_=0) : i(i_), j(j_) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n};\n\nstruct Segment {\n    bool is_horizontal;\n    int fixed_index;\n    int start, end;\n    Segment(bool h, int idx, int s, int e) : is_horizontal(h), fixed_index(idx), start(s), end(e) {}\n    bool operator==(const Segment& other) const {\n        return is_horizontal == other.is_horizontal && fixed_index == other.fixed_index && start == other.start && end == other.end;\n    }\n    bool operator<(const Segment& other) const {\n        if (is_horizontal != other.is_horizontal) return is_horizontal < other.is_horizontal;\n        if (fixed_index != other.fixed_index) return fixed_index < other.fixed_index;\n        if (start != other.start) return start < other.start;\n        return end < other.end;\n    }\n};\n\nvector<Point> dial_shortest_path(const vector<vector<int>>& grid_cost, int N, Point start, Point end) {\n    int max_cost = 9 * N * N;\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n    vector<list<Point>> buckets(max_cost + 1);\n\n    dist[start.i][start.j] = 0;\n    buckets[0].push_back(start);\n\n    for (int idx = 0; idx <= max_cost; idx++) {\n        while (!buckets[idx].empty()) {\n            Point p = buckets[idx].front();\n            buckets[idx].pop_front();\n            if (dist[p.i][p.j] < idx) continue;\n            if (p == end) break;\n            for (auto [di, dj] : {array<int,2>{-1,0}, {1,0}, {0,-1}, {0,1}}) {\n                int ni = p.i + di;\n                int nj = p.j + dj;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid_cost[ni][nj] == -1) continue;\n                int new_cost = dist[p.i][p.j] + grid_cost[ni][nj];\n                if (new_cost < dist[ni][nj]) {\n                    dist[ni][nj] = new_cost;\n                    parent[ni][nj] = p;\n                    if (new_cost <= max_cost) {\n                        buckets[new_cost].push_front(Point(ni, nj));\n                    }\n                }\n            }\n        }\n    }\n\n    vector<Point> path;\n    if (dist[end.i][end.j] == INF) {\n        return path;\n    }\n    Point cur = end;\n    while (cur != start) {\n        path.push_back(cur);\n        cur = parent[cur.i][cur.j];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<int> bipartite_matching(const vector<vector<int>>& graph, int nH, int nV) {\n    vector<int> matchH(nH, -1);\n    vector<int> matchV(nV, -1);\n    vector<bool> visited;\n\n    function<bool(int)> dfs = [&](int u) {\n        visited[u] = true;\n        for (int v : graph[u]) {\n            if (matchV[v] == -1 || (!visited[matchV[v]] && dfs(matchV[v]))) {\n                matchH[u] = v;\n                matchV[v] = u;\n                return true;\n            }\n        }\n        return false;\n    };\n\n    for (int u = 0; u < nH; u++) {\n        visited.assign(nH, false);\n        dfs(u);\n    }\n\n    vector<int> matching(nH, -1);\n    for (int u = 0; u < nH; u++) {\n        if (matchH[u] != -1) {\n            matching[u] = matchH[u];\n        }\n    }\n    return matching;\n}\n\nvector<Segment> konig_vertex_cover(const vector<vector<int>>& graph, const vector<int>& matching, int nH, int nV) {\n    vector<vector<int>> residual_graph(nH + nV);\n    for (int u = 0; u < nH; u++) {\n        for (int v : graph[u]) {\n            if (matching[u] == v) {\n                residual_graph[nH + v].push_back(u);\n            } else {\n                residual_graph[u].push_back(nH + v);\n            }\n        }\n    }\n\n    vector<bool> marked(nH + nV, false);\n    queue<int> q;\n    for (int u = 0; u < nH; u++) {\n        if (matching[u] == -1) {\n            marked[u] = true;\n            q.push(u);\n        }\n    }\n\n    while (!q.empty()) {\n        int node = q.front();\n        q.pop();\n        for (int neighbor : residual_graph[node]) {\n            if (!marked[neighbor]) {\n                marked[neighbor] = true;\n                q.push(neighbor);\n            }\n        }\n    }\n\n    vector<Segment> vertex_cover;\n    for (int u = 0; u < nH; u++) {\n        if (!marked[u]) {\n            vertex_cover.push_back(Segment(true, u, 0, 0));\n        }\n    }\n    for (int v = 0; v < nV; v++) {\n        if (marked[nH + v]) {\n            vertex_cover.push_back(Segment(false, v, 0, 0));\n        }\n    }\n    return vertex_cover;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid_str[i];\n    }\n\n    vector<vector<int>> grid_cost(N, vector<int>(N, -1));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                grid_cost[i][j] = grid_str[i][j] - '0';\n            }\n        }\n    }\n\n    vector<Segment> h_segments, v_segments;\n    vector<vector<Segment*>> h_segment_ptr(N, vector<Segment*>(N, nullptr));\n    vector<vector<Segment*>> v_segment_ptr(N, vector<Segment*>(N, nullptr));\n\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid_str[i][j] == '#') {\n                j++;\n                continue;\n            }\n            int start = j;\n            while (j < N && grid_str[i][j] != '#') {\n                j++;\n            }\n            int end = j - 1;\n            h_segments.emplace_back(true, i, start, end);\n            Segment* seg = &h_segments.back();\n            for (int k = start; k <= end; k++) {\n                h_segment_ptr[i][k] = seg;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid_str[i][j] == '#') {\n                i++;\n                continue;\n            }\n            int start = i;\n            while (i < N && grid_str[i][j] != '#') {\n                i++;\n            }\n            int end = i - 1;\n            v_segments.emplace_back(false, j, start, end);\n            Segment* seg = &v_segments.back();\n            for (int k = start; k <= end; k++) {\n                v_segment_ptr[k][j] = seg;\n            }\n        }\n    }\n\n    unordered_map<Segment*, int> h_segment_to_id;\n    unordered_map<Segment*, int> v_segment_to_id;\n    for (int i = 0; i < h_segments.size(); i++) {\n        h_segment_to_id[&h_segments[i]] = i;\n    }\n    for (int i = 0; i < v_segments.size(); i++) {\n        v_segment_to_id[&v_segments[i]] = i;\n    }\n\n    vector<vector<int>> bipartite_graph(h_segments.size());\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                Segment* h_seg = h_segment_ptr[i][j];\n                Segment* v_seg = v_segment_ptr[i][j];\n                int h_id = h_segment_to_id[h_seg];\n                int v_id = v_segment_to_id[v_seg];\n                bipartite_graph[h_id].push_back(v_id);\n            }\n        }\n    }\n\n    vector<int> matching = bipartite_matching(bipartite_graph, h_segments.size(), v_segments.size());\n    vector<Segment> vertex_cover_segments = konig_vertex_cover(bipartite_graph, matching, h_segments.size(), v_segments.size());\n\n    Segment* h_start_seg = h_segment_ptr[si][sj];\n    Segment* v_start_seg = v_segment_ptr[si][sj];\n    vector<Segment> segments_to_cover;\n    for (const Segment& seg : vertex_cover_segments) {\n        if (seg.is_horizontal) {\n            if (&h_segments[seg.fixed_index] != h_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        } else {\n            if (&v_segments[seg.fixed_index] != v_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        }\n    }\n\n    vector<Point> candidate_points;\n    for (const Segment& seg : segments_to_cover) {\n        if (seg.is_horizontal) {\n            candidate_points.emplace_back(seg.fixed_index, seg.start);\n        } else {\n            candidate_points.emplace_back(seg.start, seg.fixed_index);\n        }\n    }\n\n    vector<Point> P;\n    P.emplace_back(si, sj);\n    P.insert(P.end(), candidate_points.begin(), candidate_points.end());\n    int total_points = P.size();\n\n    vector<vector<int>> dist_matrix(total_points, vector<int>(total_points, INF));\n    vector<vector<vector<Point>>> paths(total_points, vector<vector<Point>>(total_points));\n\n    for (int i = 0; i < total_points; i++) {\n        vector<Point> path_to_end = dial_shortest_path(grid_cost, N, P[i], P[i]);\n        for (int j = 0; j < total_points; j++) {\n            if (i == j) {\n                dist_matrix[i][j] = 0;\n                paths[i][j] = {P[i]};\n                continue;\n            }\n            vector<Point> path_ij = dial_shortest_path(grid_cost, N, P[i], P[j]);\n            if (path_ij.empty()) {\n                dist_matrix[i][j] = INF;\n                paths[i][j] = {};\n            } else {\n                int total_cost = 0;\n                Point cur = P[i];\n                for (const Point& p : path_ij) {\n                    total_cost += grid_cost[p.i][p.j];\n                }\n                dist_matrix[i][j] = total_cost;\n                paths[i][j] = path_ij;\n            }\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited(total_points, false);\n    visited[0] = true;\n    tour.push_back(0);\n    int current = 0;\n    for (int step = 1; step < total_points; step++) {\n        int best_next = -1;\n        int best_dist = INF;\n        for (int j = 0; j < total_points; j++) {\n            if (!visited[j] && dist_matrix[current][j] < best_dist) {\n                best_dist = dist_matrix[current][j];\n                best_next = j;\n            }\n        }\n        if (best_next == -1) break;\n        visited[best_next] = true;\n        tour.push_back(best_next);\n        current = best_next;\n    }\n    tour.push_back(0);\n\n    vector<Point> full_route;\n    full_route.push_back(P[0]);\n    for (int idx = 0; idx < tour.size() - 1; idx++) {\n        int i = tour[idx];\n        int j = tour[idx+1];\n        if (i == j) continue;\n        vector<Point>& path_segment = paths[i][j];\n        full_route.insert(full_route.end(), path_segment.begin(), path_segment.end());\n    }\n\n    string moves;\n    for (int i = 0; i < full_route.size() - 1; i++) {\n        Point a = full_route[i];\n        Point b = full_route[i+1];\n        if (b.i < a.i) moves += 'U';\n        else if (b.i > a.i) moves += 'D';\n        else if (b.j < a.j) moves += 'L';\n        else if (b.j > a.j) moves += 'R';\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n#include <cstring>\n#include <sys/select.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(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    vector<vector<int>> prerequisites(N);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        prerequisites[v].push_back(u);\n    }\n\n    vector<int> task_status(N, -1);\n    vector<int> member_status(M, -1);\n    vector<int> start_day(N, 0);\n\n    vector<vector<int>> S(M, vector<int>(K, 0));\n\n    int current_day = 1;\n\n    while (true) {\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        vector<int> tokens;\n        char* cstr = new char[line.length() + 1];\n        strcpy(cstr, line.c_str());\n        char* p = strtok(cstr, \" \");\n        while (p != nullptr) {\n            tokens.push_back(atoi(p));\n            p = strtok(nullptr, \" \");\n        }\n        delete[] cstr;\n\n        int n = tokens[0];\n        vector<int> completed_members;\n        for (int i = 1; i <= n; ++i) {\n            completed_members.push_back(tokens[i]);\n        }\n\n        for (int idx = 0; idx < n; ++idx) {\n            int j0 = completed_members[idx];\n            int j = j0 - 1;\n            if (member_status[j] == -1) {\n                continue;\n            }\n            int task_i = member_status[j];\n            task_status[task_i] = 1;\n            member_status[j] = -1;\n\n            int t_taken = current_day - start_day[task_i];\n\n            if (t_taken == 1) {\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        S[j][k] = d[task_i][k];\n                    }\n                }\n            } else {\n                int current_w = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        current_w += d[task_i][k] - S[j][k];\n                    }\n                }\n\n                if (current_w > t_taken + 3) {\n                    int reduction_needed = current_w - (t_taken + 3);\n                    vector<pair<int, int>> deficits;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task_i][k] > S[j][k]) {\n                            int deficit_k = d[task_i][k] - S[j][k];\n                            deficits.emplace_back(deficit_k, k);\n                        }\n                    }\n                    sort(deficits.begin(), deficits.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                        return a.first > b.first;\n                    });\n                    for (auto& def : deficits) {\n                        if (reduction_needed <= 0) break;\n                        int deficit_k = def.first;\n                        int k = def.second;\n                        int increase = min(deficit_k, reduction_needed);\n                        S[j][k] += increase;\n                        reduction_needed -= increase;\n                    }\n                }\n            }\n        }\n\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] != -1) continue;\n            bool available = true;\n            for (int pre : prerequisites[i]) {\n                if (task_status[pre] != 1) {\n                    available = false;\n                    break;\n                }\n            }\n            if (available) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> free_team_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_status[j] == -1) {\n                free_team_members.push_back(j);\n            }\n        }\n\n        vector<pair<int, int>> assignments;\n        if (!available_tasks.empty() && !free_team_members.empty()) {\n            vector<pair<int, int>> task_list;\n            for (int i : available_tasks) {\n                int min_exp = -1;\n                for (int j : free_team_members) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (min_exp == -1 || exp_time < min_exp) {\n                        min_exp = exp_time;\n                    }\n                }\n                task_list.emplace_back(min_exp, i);\n            }\n\n            sort(task_list.begin(), task_list.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                return a.first > b.first;\n            });\n\n            set<int> free_set(free_team_members.begin(), free_team_members.end());\n            for (auto& p : task_list) {\n                if (free_set.empty()) break;\n                int i = p.second;\n                int best_j = -1;\n                int best_exp = -1;\n                for (int j : free_set) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (best_j == -1 || exp_time < best_exp) {\n                        best_j = j;\n                        best_exp = exp_time;\n                    }\n                }\n                assignments.emplace_back(best_j, i);\n                free_set.erase(best_j);\n            }\n        }\n\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        for (auto& p : assignments) {\n            int j = p.first;\n            int i = p.second;\n            task_status[i] = 0;\n            member_status[j] = i;\n            start_day[i] = current_day;\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <set>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Order {\n    int id;\n    int a, b;  // restaurant\n    int c, d;  // destination\n};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    \n    int manhattan_distance(const Point& other) const {\n        return abs(x - other.x) + abs(y - other.y);\n    }\n};\n\nvector<Order> orders;\nvector<int> selected_orders;\nvector<Point> route;\n\nmt19937 rng;\n\nint calculate_total_distance(const vector<Point>& route) {\n    int total = 0;\n    for (size_t i = 0; i < route.size() - 1; i++) {\n        total += route[i].manhattan_distance(route[i + 1]);\n    }\n    return total;\n}\n\nbool is_valid_route(const vector<int>& selected, const vector<Point>& route) {\n    vector<pair<int, int>> positions(1001, {-1, -1});\n    \n    for (size_t i = 0; i < route.size(); i++) {\n        for (int order_id : selected) {\n            const auto& order = orders[order_id];\n            if (route[i].x == order.a && route[i].y == order.b) {\n                if (positions[order_id].first == -1) {\n                    positions[order_id].first = i;\n                }\n            } else if (route[i].x == order.c && route[i].y == order.d) {\n                if (positions[order_id].second == -1) {\n                    positions[order_id].second = i;\n                }\n            }\n        }\n    }\n    \n    for (int order_id : selected) {\n        if (positions[order_id].first == -1 || positions[order_id].second == -1) {\n            return false;\n        }\n        if (positions[order_id].first >= positions[order_id].second) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nvector<Point> construct_greedy_route(const vector<int>& selected) {\n    vector<Point> route = {Point(400, 400)};\n    set<int> remaining_orders(selected.begin(), selected.end());\n    \n    while (!remaining_orders.empty()) {\n        int best_order = -1;\n        int best_pos = -1;\n        int best_increase = 1e9;\n        \n        for (int order_id : remaining_orders) {\n            const auto& order = orders[order_id];\n            \n            // Try inserting restaurant and destination in all possible positions\n            for (size_t i = 0; i <= route.size(); i++) {\n                for (size_t j = i + 1; j <= route.size(); j++) {\n                    vector<Point> temp_route = route;\n                    temp_route.insert(temp_route.begin() + i, Point(order.a, order.b));\n                    temp_route.insert(temp_route.begin() + j, Point(order.c, order.d));\n                    \n                    int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n                    \n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_order = order_id;\n                        best_pos = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_order == -1) break;\n        \n        const auto& best_order_data = orders[best_order];\n        size_t insert_dest_pos = best_pos + 1;\n        \n        // Find best position for destination\n        for (size_t j = best_pos + 1; j <= route.size(); j++) {\n            vector<Point> temp_route = route;\n            temp_route.insert(temp_route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n            temp_route.insert(temp_route.begin() + j, Point(best_order_data.c, best_order_data.d));\n            \n            int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n            \n            if (increase < best_increase) {\n                best_increase = increase;\n                insert_dest_pos = j;\n            }\n        }\n        \n        route.insert(route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n        route.insert(route.begin() + insert_dest_pos, Point(best_order_data.c, best_order_data.d));\n        remaining_orders.erase(best_order);\n    }\n    \n    route.push_back(Point(400, 400));\n    \n    assert(is_valid_route(selected, route));\n    return route;\n}\n\nvector<int> select_initial_orders() {\n    // Calculate center of mass for all orders\n    double center_x = 0, center_y = 0;\n    for (const auto& order : orders) {\n        center_x += (order.a + order.c) / 2.0;\n        center_y += (order.b + order.d) / 2.0;\n    }\n    center_x /= orders.size();\n    center_y /= orders.size();\n    \n    // Calculate distances from center for each order\n    vector<pair<double, int>> order_distances;\n    for (size_t i = 0; i < orders.size(); i++) {\n        const auto& order = orders[i];\n        double mid_x = (order.a + order.c) / 2.0;\n        double mid_y = (order.b + order.d) / 2.0;\n        double dist = abs(mid_x - center_x) + abs(mid_y - center_y);\n        order_distances.emplace_back(dist, i);\n    }\n    \n    // Sort by distance and select the closest 50\n    sort(order_distances.begin(), order_distances.end());\n    vector<int> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(order_distances[i].second);\n    }\n    \n    return selected;\n}\n\nvector<Point> simulated_annealing(const vector<int>& initial_selected, const vector<Point>& initial_route) {\n    vector<int> current_selected = initial_selected;\n    vector<Point> current_route = initial_route;\n    int current_distance = calculate_total_distance(current_route);\n    \n    vector<int> best_selected = current_selected;\n    vector<Point> best_route = current_route;\n    int best_distance = current_distance;\n    \n    const double initial_temp = 1000.0;\n    const double final_temp = 1.0;\n    const int iterations = 100000;\n    \n    double temp = initial_temp;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        temp = initial_temp * pow(final_temp / initial_temp, (double)iter / iterations);\n        \n        // Choose a random operation\n        int operation = uniform_int_distribution<int>(0, 2)(rng);\n        \n        if (operation == 0) {\n            // Swap two points in the route\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            int j = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            \n            if (i == j) continue;\n            \n            vector<Point> new_route = current_route;\n            swap(new_route[i], new_route[j]);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else if (operation == 1) {\n            // Reverse a segment\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 3)(rng);\n            int j = uniform_int_distribution<int>(i + 1, current_route.size() - 2)(rng);\n            \n            vector<Point> new_route = current_route;\n            reverse(new_route.begin() + i, new_route.begin() + j + 1);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else {\n            // Swap an order in the selected set with one not in the set\n            vector<int> unselected;\n            for (size_t i = 0; i < orders.size(); i++) {\n                if (find(current_selected.begin(), current_selected.end(), i) == current_selected.end()) {\n                    unselected.push_back(i);\n                }\n            }\n            \n            if (unselected.empty()) continue;\n            \n            int idx_to_remove = uniform_int_distribution<int>(0, current_selected.size() - 1)(rng);\n            int idx_to_add = uniform_int_distribution<int>(0, unselected.size() - 1)(rng);\n            \n            vector<int> new_selected = current_selected;\n            new_selected[idx_to_remove] = unselected[idx_to_add];\n            sort(new_selected.begin(), new_selected.end());\n            \n            vector<Point> new_route = construct_greedy_route(new_selected);\n            int new_distance = calculate_total_distance(new_route);\n            int delta = new_distance - current_distance;\n            \n            if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_selected = new_selected;\n                current_route = new_route;\n                current_distance = new_distance;\n                \n                if (current_distance < best_distance) {\n                    best_selected = current_selected;\n                    best_route = current_route;\n                    best_distance = current_distance;\n                }\n            }\n        }\n    }\n    \n    return best_route;\n}\n\nvoid solve() {\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n    \n    // Initialize random number generator\n    rng = mt19937(high_resolution_clock::now().time_since_epoch().count());\n    \n    // Select initial orders\n    selected_orders = select_initial_orders();\n    \n    // Construct initial route\n    route = construct_greedy_route(selected_orders);\n    \n    // Optimize with simulated annealing\n    route = simulated_annealing(selected_orders, route);\n    \n    // Output the result\n    cout << selected_orders.size();\n    for (int order_id : selected_orders) {\n        cout << \" \" << order_id + 1;  // Convert to 1-based indexing\n    }\n    cout << endl;\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << endl;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\nusing namespace std;\n\nclass DSU {\nprivate:\n    vector<int> parent;\n    vector<int> rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n\n    void union_set(int x, int y) {\n        int rx = find(x);\n        int ry = find(y);\n        if (rx == ry) {\n            return;\n        }\n        if (rank[rx] < rank[ry]) {\n            parent[rx] = ry;\n        } else if (rank[rx] > rank[ry]) {\n            parent[ry] = rx;\n        } else {\n            parent[ry] = rx;\n            rank[rx]++;\n        }\n    }\n};\n\nstruct Edge {\n    int u, v;\n    double d;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N = 400;\n    int M = 1995;\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        edges[i].index = i;\n        int u = edges[i].u, v = edges[i].v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        edges[i].d = round(dist);\n    }\n\n    vector<int> tree_id(M, -1);\n    vector<Edge> remaining_edges = edges;\n    for (int t = 0; t < 5; t++) {\n        sort(remaining_edges.begin(), remaining_edges.end(), [](const Edge& a, const Edge& b) {\n            return a.d < b.d;\n        });\n\n        DSU dsu_temp(N);\n        vector<Edge> tree_edges;\n        vector<Edge> new_remaining;\n\n        for (Edge& e : remaining_edges) {\n            int u = e.u, v = e.v;\n            if (dsu_temp.find(u) != dsu_temp.find(v)) {\n                dsu_temp.union_set(u, v);\n                tree_edges.push_back(e);\n                tree_id[e.index] = t+1;\n            } else {\n                new_remaining.push_back(e);\n            }\n        }\n\n        remaining_edges = new_remaining;\n    }\n\n    DSU dsu_online(N);\n    vector<vector<int>> comp_edge_count(N, vector<int>(N, 0));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].u, v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n        if (a != b) {\n            comp_edge_count[a][b]++;\n            comp_edge_count[b][a]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n\n        if (a != b) {\n            comp_edge_count[a][b]--;\n            comp_edge_count[b][a]--;\n        }\n\n        if (a == b) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n\n        if (comp_edge_count[a][b] == 0) {\n            dsu_online.union_set(u, v);\n            int root_a = dsu_online.find(u);\n            int root_b = dsu_online.find(v);\n            for (int c = 0; c < N; c++) {\n                if (c == root_a) continue;\n                if (comp_edge_count[root_b][c] > 0) {\n                    comp_edge_count[root_a][c] += comp_edge_count[root_b][c];\n                    comp_edge_count[c][root_a] += comp_edge_count[c][root_b];\n                    comp_edge_count[root_b][c] = 0;\n                    comp_edge_count[c][root_b] = 0;\n                }\n            }\n            comp_edge_count[root_a][root_b] = 0;\n            comp_edge_count[root_b][root_a] = 0;\n\n            cout << 1 << endl;\n            cout.flush();\n        } else {\n            double progress = static_cast<double>(i) / M;\n            double base_threshold = 1.0;\n            double max_threshold = 3.0;\n            double factor = (6.0 - tree_id[i]) / 5.0;\n            double threshold = base_threshold + progress * (max_threshold - base_threshold) * factor;\n\n            if (l_i <= threshold * edges[i].d) {\n                dsu_online.union_set(u, v);\n                int root_a = dsu_online.find(u);\n                int root_b = dsu_online.find(v);\n                for (int c = 0; c < N; c++) {\n                    if (c == root_a) continue;\n                    if (comp_edge_count[root_b][c] > 0) {\n                        comp_edge_count[root_a][c] += comp_edge_count[root_b][c];\n                        comp_edge_count[c][root_a] += comp_edge_count[c][root_b];\n                        comp_edge_count[root_b][c] = 0;\n                        comp_edge_count[c][root_b] = 0;\n                    }\n                }\n                comp_edge_count[root_a][root_b] = 0;\n                comp_edge_count[root_b][root_a] = 0;\n\n                cout << 1 << endl;\n                cout.flush();\n            } else {\n                cout << 0 << endl;\n                cout.flush();\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\n#include <cstring>\n#include <iomanip>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\n\nstruct Position {\n    int x, y;\n    Position(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Position& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nbool is_buildable(int x, int y, const vector<Position>& pets, const vector<Position>& humans) {\n    for (const auto& pet : pets) {\n        if (pet.x == x && pet.y == y) {\n            return false;\n        }\n    }\n    for (const auto& human : humans) {\n        if (human.x == x && human.y == y) {\n            return false;\n        }\n    }\n\n    vector<pair<int,int>> adj = {{x-1,y}, {x+1,y}, {x,y-1}, {x,y+1}};\n    for (const auto& [ax, ay] : adj) {\n        if (ax < 1 || ax > 30 || ay < 1 || ay > 30) {\n            continue;\n        }\n        for (const auto& pet : pets) {\n            if (pet.x == ax && pet.y == ay) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M;\n    cin >> N;\n    vector<Position> pets(N);\n    vector<int> pet_types(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n    }\n    cin >> M;\n    vector<Position> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n\n    bool grid[31][31];\n    for (int i = 1; i <= 30; i++) {\n        for (int j = 1; j <= 30; j++) {\n            grid[i][j] = true;\n        }\n    }\n\n    vector<Position> perimeter;\n    for (int y = 10; y <= 20; y++) {\n        perimeter.push_back(Position(10, y));\n    }\n    for (int x = 11; x <= 20; x++) {\n        perimeter.push_back(Position(x, 20));\n    }\n    for (int y = 19; y >= 10; y--) {\n        perimeter.push_back(Position(20, y));\n    }\n    for (int x = 19; x >= 11; x--) {\n        perimeter.push_back(Position(x, 10));\n    }\n\n    vector<queue<Position>> human_queues(M);\n    int segment_size = perimeter.size() / M;\n    int extra = perimeter.size() % M;\n    int index = 0;\n    for (int i = 0; i < M; i++) {\n        int size = segment_size + (i < extra ? 1 : 0);\n        for (int j = 0; j < size; j++) {\n            human_queues[i].push(perimeter[index++]);\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n\n        if (turn < 20) {\n            for (int i = 0; i < M; i++) {\n                int x = humans[i].x;\n                int y = humans[i].y;\n                if (x >= 10 && x <= 20 && y >= 10 && y <= 20) {\n                    actions[i] = '.';\n                } else {\n                    int dx = 15 - x;\n                    int dy = 15 - y;\n                    if (abs(dx) > abs(dy)) {\n                        actions[i] = (dx > 0) ? 'D' : 'U';\n                    } else {\n                        actions[i] = (dy > 0) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            set<Position> built_this_turn;\n            vector<Position> intended_moves(M, Position(-1,-1));\n\n            for (int i = 0; i < M; i++) {\n                if (human_queues[i].empty()) {\n                    continue;\n                }\n\n                Position target = human_queues[i].front();\n                int dx = humans[i].x - target.x;\n                int dy = humans[i].y - target.y;\n                bool adjacent = (abs(dx) + abs(dy) == 1);\n\n                if (adjacent) {\n                    if (is_buildable(target.x, target.y, pets, humans)) {\n                        if (dx == -1) {\n                            actions[i] = 'd';\n                        } else if (dx == 1) {\n                            actions[i] = 'u';\n                        } else if (dy == -1) {\n                            actions[i] = 'r';\n                        } else if (dy == 1) {\n                            actions[i] = 'l';\n                        }\n                        built_this_turn.insert(target);\n                        human_queues[i].pop();\n                    } else {\n                        human_queues[i].pop();\n                        human_queues[i].push(target);\n                    }\n                } else {\n                    vector<pair<int,int>> dirs = {{-1,0},{1,0},{0,-1},{0,1}};\n                    vector<Position> adj_squares;\n                    for (const auto& d : dirs) {\n                        int nx = target.x + d.first;\n                        int ny = target.y + d.second;\n                        if (nx >= 1 && nx <= 30 && ny >= 1 && ny <= 30) {\n                            if (grid[nx][ny] && built_this_turn.find(Position(nx,ny)) == built_this_turn.end()) {\n                                adj_squares.push_back(Position(nx, ny));\n                            }\n                        }\n                    }\n\n                    if (adj_squares.empty()) {\n                        human_queues[i].pop();\n                        human_queues[i].push(target);\n                    } else {\n                        Position best_adj = adj_squares[0];\n                        int best_dist = abs(humans[i].x - best_adj.x) + abs(humans[i].y - best_adj.y);\n                        for (int j = 1; j < adj_squares.size(); j++) {\n                            int d = abs(humans[i].x - adj_squares[j].x) + abs(humans[i].y - adj_squares[j].y);\n                            if (d < best_dist) {\n                                best_dist = d;\n                                best_adj = adj_squares[j];\n                            }\n                        }\n\n                        vector<char> move_dirs = {'U','D','L','R'};\n                        vector<pair<int,int>> move_deltas = {{-1,0},{1,0},{0,-1},{0,1}};\n                        char best_move = '.';\n                        int best_move_dist = 1000000;\n                        for (int j = 0; j < 4; j++) {\n                            int nx = humans[i].x + move_deltas[j].first;\n                            int ny = humans[i].y + move_deltas[j].second;\n                            if (nx < 1 || nx > 30 || ny < 1 || ny > 30) {\n                                continue;\n                            }\n                            if (!grid[nx][ny] || built_this_turn.find(Position(nx,ny)) != built_this_turn.end()) {\n                                continue;\n                            }\n                            int d = abs(nx - best_adj.x) + abs(ny - best_adj.y);\n                            if (d < best_move_dist) {\n                                best_move_dist = d;\n                                best_move = move_dirs[j];\n                            }\n                        }\n                        if (best_move != '.') {\n                            actions[i] = best_move;\n                            if (best_move == 'U') intended_moves[i] = Position(humans[i].x-1, humans[i].y);\n                            else if (best_move == 'D') intended_moves[i] = Position(humans[i].x+1, humans[i].y);\n                            else if (best_move == 'L') intended_moves[i] = Position(humans[i].x, humans[i].y-1);\n                            else if (best_move == 'R') intended_moves[i] = Position(humans[i].x, humans[i].y+1);\n                        } else {\n                            human_queues[i].pop();\n                            human_queues[i].push(target);\n                        }\n                    }\n                }\n            }\n\n            for (const auto& pos : built_this_turn) {\n                grid[pos.x][pos.y] = false;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == '.') break;\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    string path;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\"});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            break;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj]});\n            }\n        }\n    }\n    \n    string shortest_path = paths[ti][tj];\n    if (shortest_path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    int redundancy = static_cast<int>(p * 4) + 1;\n    string robust_path;\n    for (char c : shortest_path) {\n        robust_path += string(redundancy, c);\n    }\n    \n    if (robust_path.size() > 200) {\n        robust_path = shortest_path;\n        int extra = min(200 - (int)shortest_path.size(), (int)shortest_path.size());\n        for (int i = 0; i < extra; i++) {\n            robust_path += shortest_path[i % shortest_path.size()];\n        }\n    }\n    \n    cout << robust_path << endl;\n    \n    return 0;\n}","ahc010":"","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <unordered_set>\n#include <tuple>\n#include <cmath>\n#include <climits>\n\nusing namespace std;\n\nconst int dx[] = {0, 0, -1, 1};\nconst int dy[] = {-1, 1, 0, 0};\nconst char dir_char[] = {'L', 'R', 'U', 'D'};\n\nstruct State {\n    vector<vector<int>> board;\n    int empty_x, empty_y;\n    string moves;\n};\n\nint count_connections(const vector<vector<int>>& board, int N) {\n    int connections = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            if (i < N - 1 && board[i+1][j] != 0) {\n                int down = board[i+1][j];\n                if ((tile & 8) && (down & 2)) {\n                    connections++;\n                }\n            }\n            if (j < N - 1 && board[i][j+1] != 0) {\n                int right = board[i][j+1];\n                if ((tile & 4) && (right & 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> board(N, vector<int>(N));\n    int empty_x = -1, empty_y = -1;\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            if (c == '0') {\n                board[i][j] = 0;\n                empty_x = i;\n                empty_y = j;\n            } else {\n                if (c >= '0' && c <= '9') {\n                    board[i][j] = c - '0';\n                } else {\n                    board[i][j] = 10 + (c - 'a');\n                }\n            }\n        }\n    }\n\n    string best_moves;\n    int best_connections = -1;\n\n    auto try_moves = [&](const string& move_sequence) {\n        vector<vector<int>> temp_board = board;\n        int ex = empty_x, ey = empty_y;\n        for (char c : move_sequence) {\n            int dir;\n            if (c == 'L') dir = 0;\n            else if (c == 'R') dir = 1;\n            else if (c == 'U') dir = 2;\n            else dir = 3;\n\n            int nx = ex + dx[dir];\n            int ny = ey + dy[dir];\n            if (nx < 0 || nx >= N || ny < 0 || ny >= N) return false;\n\n            swap(temp_board[ex][ey], temp_board[nx][ny]);\n            ex = nx;\n            ey = ny;\n        }\n        int connections = count_connections(temp_board, N);\n        if (connections > best_connections) {\n            best_connections = connections;\n            best_moves = move_sequence;\n        }\n        return true;\n    };\n\n    for (int iter = 0; iter < 100; ++iter) {\n        string moves;\n        vector<vector<int>> temp_board = board;\n        int ex = empty_x, ey = empty_y;\n        int current_connections = count_connections(temp_board, N);\n\n        for (int step = 0; step < min(T, 1000); ++step) {\n            vector<tuple<int, int, int, int>> possible_moves;\n            for (int dir = 0; dir < 4; ++dir) {\n                int nx = ex + dx[dir];\n                int ny = ey + dy[dir];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n                possible_moves.emplace_back(dir, nx, ny, temp_board[nx][ny]);\n            }\n\n            int best_dir = -1;\n            int best_delta = -1;\n            for (auto [dir, nx, ny, tile] : possible_moves) {\n                swap(temp_board[ex][ey], temp_board[nx][ny]);\n                int new_connections = count_connections(temp_board, N);\n                int delta = new_connections - current_connections;\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_dir = dir;\n                }\n                swap(temp_board[ex][ey], temp_board[nx][ny]);\n            }\n\n            if (best_dir == -1) {\n                best_dir = get<0>(possible_moves[0]);\n            }\n\n            int nx = ex + dx[best_dir];\n            int ny = ey + dy[best_dir];\n            swap(temp_board[ex][ey], temp_board[nx][ny]);\n            moves += dir_char[best_dir];\n            ex = nx;\n            ey = ny;\n            current_connections += best_delta;\n        }\n\n        try_moves(moves);\n    }\n\n    cout << best_moves << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <set>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nusing Point = pair<long long, long long>;\nusing Line = pair<Point, Point>;\n\nconst long long RADIUS = 10000;\nconst long long RADIUS_SQ = 100000000;\n\nstruct Solution {\n    vector<Line> lines;\n    double score;\n};\n\n// Calculate the cross product of vectors OA and OB\nlong long cross(const Point& O, const Point& A, const Point& B) {\n    return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);\n}\n\n// Determine which side of the line AB the point P is on\n// Returns > 0 if P is on the left side, < 0 if on the right side, 0 if on the line\nlong long side(const Line& line, const Point& P) {\n    const Point& A = line.first;\n    const Point& B = line.second;\n    return cross(A, B, P);\n}\n\n// Check if a point is inside the circle\nbool is_inside_circle(const Point& p) {\n    return p.first * p.first + p.second * p.second < RADIUS_SQ;\n}\n\n// Calculate the score for a given distribution\ndouble calculate_score(const vector<int>& a, const vector<int>& b) {\n    int total_distributed = 0;\n    int total_attendees = 0;\n    \n    for (int d = 1; d <= 10; d++) {\n        total_distributed += min(a[d-1], b[d-1]);\n        total_attendees += a[d-1];\n    }\n    \n    return 1000000.0 * total_distributed / total_attendees;\n}\n\n// Count strawberries in each region\nvector<int> count_strawberries(const vector<Point>& strawberries, const vector<Line>& lines) {\n    if (lines.empty()) {\n        return {static_cast<int>(strawberries.size())};\n    }\n    \n    // Map from region signature to count\n    unordered_map<string, int> region_counts;\n    \n    for (const auto& strawberry : strawberries) {\n        string signature;\n        bool on_line = false;\n        \n        for (const auto& line : lines) {\n            long long s = side(line, strawberry);\n            if (s == 0) {\n                on_line = true;\n                break;\n            }\n            signature += (s > 0) ? '1' : '0';\n        }\n        \n        if (!on_line) {\n            region_counts[signature]++;\n        }\n    }\n    \n    // Convert to distribution\n    vector<int> distribution(10, 0);\n    for (const auto& [_, count] : region_counts) {\n        if (count >= 1 && count <= 10) {\n            distribution[count-1]++;\n        }\n    }\n    \n    return distribution;\n}\n\n// Generate candidate lines\nvector<Line> generate_candidate_lines(const vector<Point>& strawberries, mt19937& rng, int num_candidates = 100) {\n    vector<Line> candidates;\n    int n = strawberries.size();\n    \n    // Random lines through two strawberries\n    for (int i = 0; i < num_candidates / 2 && i < n * n / 2; i++) {\n        int idx1 = rng() % n;\n        int idx2 = rng() % n;\n        if (idx1 != idx2) {\n            candidates.push_back({strawberries[idx1], strawberries[idx2]});\n        }\n    }\n    \n    // Random lines in random directions\n    uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n    for (int i = 0; i < num_candidates / 2; i++) {\n        Point p1 = {coord_dist(rng), coord_dist(rng)};\n        Point p2 = {coord_dist(rng), coord_dist(rng)};\n        candidates.push_back({p1, p2});\n    }\n    \n    return candidates;\n}\n\n// Main solving function\nSolution solve(int N, int K, const vector<int>& a, const vector<Point>& strawberries) {\n    mt19937 rng(12345);  // Fixed seed for reproducibility\n    \n    Solution best_solution;\n    best_solution.lines = {};\n    best_solution.score = 0;\n    \n    vector<Line> current_lines;\n    double current_score = 0;\n    \n    // Iteratively add lines\n    for (int iter = 0; iter < K; iter++) {\n        vector<Line> candidates = generate_candidate_lines(strawberries, rng);\n        \n        Line best_line;\n        double best_score = current_score;\n        bool improved = false;\n        \n        for (const auto& line : candidates) {\n            vector<Line> new_lines = current_lines;\n            new_lines.push_back(line);\n            \n            vector<int> distribution = count_strawberries(strawberries, new_lines);\n            double score = calculate_score(a, distribution);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = line;\n                improved = true;\n            }\n        }\n        \n        if (improved) {\n            current_lines.push_back(best_line);\n            current_score = best_score;\n            \n            if (current_score > best_solution.score) {\n                best_solution.lines = current_lines;\n                best_solution.score = current_score;\n            }\n        } else {\n            // If no improvement, try a random line\n            uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n            Point p1 = {coord_dist(rng), coord_dist(rng)};\n            Point p2 = {coord_dist(rng), coord_dist(rng)};\n            current_lines.push_back({p1, p2});\n        }\n    }\n    \n    // Final evaluation\n    vector<int> final_distribution = count_strawberries(strawberries, best_solution.lines);\n    best_solution.score = calculate_score(a, final_distribution);\n    \n    return best_solution;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(10);\n    for (int i = 0; i < 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].first >> strawberries[i].second;\n    }\n    \n    Solution solution = solve(N, K, a, strawberries);\n    \n    // Output the solution\n    cout << solution.lines.size() << \"\\n\";\n    for (const auto& line : solution.lines) {\n        cout << line.first.first << \" \" << line.first.second << \" \"\n             << line.second.first << \" \" << line.second.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    int c = (N - 1) / 2;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> col_dots(N);\n    vector<set<int>> row_dots(N);\n    set<tuple<int, int, int, int>> segments;\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    while (true) {\n        vector<pair<int, int>> non_dot_points;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    non_dot_points.emplace_back(x, y);\n                }\n            }\n        }\n\n        if (non_dot_points.empty()) {\n            break;\n        }\n\n        sort(non_dot_points.begin(), non_dot_points.end(), \n            [c](const pair<int, int>& a, const pair<int, int>& b) {\n                int wa = (a.first - c) * (a.first - c) + (a.second - c) * (a.second - c) + 1;\n                int wb = (b.first - c) * (b.first - c) + (b.second - c) * (b.second - c) + 1;\n                return wa > wb;\n            });\n\n        tuple<int, int, int, int, int, int, int, int> best_op;\n        vector<tuple<int, int, int, int>> best_segments_list;\n        int best_weight = -1;\n        bool found = false;\n\n        for (auto [x, y] : non_dot_points) {\n            int weight = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n            bool found_axis = false;\n            for (int x2 = 0; x2 < N; x2++) {\n                if (x2 == x) continue;\n                if (!grid[x2][y]) continue;\n\n                if (col_dots[x].size() <= col_dots[x2].size()) {\n                    for (int y2 : col_dots[x]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x2].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y, x2, y2);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                } else {\n                    for (int y2 : col_dots[x2]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y, x2, y2);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                }\n            }\n\n            bool found_diamond = false;\n            for (int role = 0; role < 4; role++) {\n                int max_a;\n                if (role == 0) {\n                    max_a = min({(N - 1 - x) / 2, (N - 1 - y), y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x + a;\n                        int cy = y;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + 2 * a - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + i;\n                            int x2 = x + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a + i;\n                            int y1 = y + a - i;\n                            int x2 = x + a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + 2 * a - i;\n                            int y1 = y - i;\n                            int x2 = x + 2 * a - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a + i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 1) {\n                    max_a = min({x, N - 1 - x, y / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y - a;\n                        int Ax = cx - a, Ay = cy;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - 2 * a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y - i;\n                            int x2 = x + i + 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - 2 * a + i;\n                            int x2 = x - i - 1;\n                            int y2 = y - 2 * a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y - a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 2) {\n                    max_a = min({x / 2, y, N - 1 - y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x - a;\n                        int cy = y;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - 2 * a + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - i;\n                            int x2 = x - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a - i;\n                            int y1 = y - a + i;\n                            int x2 = x - a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - 2 * a + i;\n                            int y1 = y + i;\n                            int x2 = x - 2 * a + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a - i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 3) {\n                    max_a = min({x, N - 1 - x, (N - 1 - y) / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y + a;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + 2 * a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y + i;\n                            int x2 = x - i - 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + 2 * a - i;\n                            int x2 = x + i + 1;\n                            int y2 = y + 2 * a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y + a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                }\n            }\n        }\n\n        if (!found) {\n            break;\n        }\n\n        auto [x, y, x1, y1, x2, y2, x3, y3] = best_op;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n        for (auto& seg : best_segments_list) {\n            segments.insert(seg);\n        }\n        operations.push_back(best_op);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        auto [x, y, x1, y1, x2, y2, x3, y3] = op;\n        cout << x << \" \" << y << \" \" << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \" \" << x3 << \" \" << y3 << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <queue>\n\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> cells;\n    int rows, cols;\n    \n    Grid(int r = 10, int c = 10) : rows(r), cols(c), cells(r, vector<int>(c, 0)) {}\n    \n    bool is_valid(int r, int c) const {\n        return r >= 0 && r < rows && c >= 0 && c < cols;\n    }\n    \n    int get_empty_count() const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) count++;\n            }\n        }\n        return count;\n    }\n    \n    pair<int, int> get_nth_empty(int n) const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) {\n                    count++;\n                    if (count == n) return {r, c};\n                }\n            }\n        }\n        return {-1, -1}; // Should not happen\n    }\n    \n    void tilt(char direction) {\n        if (direction == 'F') { // Forward (up)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = 0;\n                for (int r = 0; r < rows; ++r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'B') { // Backward (down)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = rows - 1;\n                for (int r = rows - 1; r >= 0; --r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        } else if (direction == 'L') { // Left\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = 0;\n                for (int c = 0; c < cols; ++c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'R') { // Right\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = cols - 1;\n                for (int c = cols - 1; c >= 0; --c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    void place(int r, int c, int flavor) {\n        cells[r][c] = flavor;\n    }\n    \n    // Calculate the score for the current grid state\n    double calculate_score() const {\n        // Find connected components for each flavor\n        vector<bool> visited(rows * cols, false);\n        vector<int> component_sizes;\n        \n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0 && !visited[r * cols + c]) {\n                    int flavor = cells[r][c];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    visited[r * cols + c] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        // Check 4-directional connectivity\n                        for (int dr = -1; dr <= 1; ++dr) {\n                            for (int dc = -1; dc <= 1; ++dc) {\n                                if (abs(dr) + abs(dc) != 1) continue; // Only 4 directions\n                                int nr = cr + dr;\n                                int nc = cc + dc;\n                                if (is_valid(nr, nc) && cells[nr][nc] == flavor && \n                                    !visited[nr * cols + nc]) {\n                                    visited[nr * cols + nc] = true;\n                                    q.push({nr, nc});\n                                }\n                            }\n                        }\n                    }\n                    \n                    component_sizes.push_back(size);\n                }\n            }\n        }\n        \n        // Calculate sum of squares of component sizes\n        double sum_squares = 0;\n        for (int size : component_sizes) {\n            sum_squares += size * size;\n        }\n        \n        // Calculate sum of squares of flavor counts\n        array<int, 4> flavor_counts = {0, 0, 0, 0};\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0) {\n                    flavor_counts[cells[r][c]]++;\n                }\n            }\n        }\n        \n        double denominator = 0;\n        for (int i = 1; i <= 3; ++i) {\n            denominator += flavor_counts[i] * flavor_counts[i];\n        }\n        \n        return sum_squares / denominator;\n    }\n    \n    // Get the position of a candy after tilting in a given direction\n    pair<int, int> get_tilted_position(int r, int c, char direction) const {\n        if (direction == 'F') { // Forward (up)\n            while (r > 0 && cells[r - 1][c] == 0) {\n                r--;\n            }\n        } else if (direction == 'B') { // Backward (down)\n            while (r < rows - 1 && cells[r + 1][c] == 0) {\n                r++;\n            }\n        } else if (direction == 'L') { // Left\n            while (c > 0 && cells[r][c - 1] == 0) {\n                c--;\n            }\n        } else if (direction == 'R') { // Right\n            while (c < cols - 1 && cells[r][c + 1] == 0) {\n                c++;\n            }\n        }\n        return {r, c};\n    }\n};\n\nclass CandyClustering {\nprivate:\n    Grid grid;\n    vector<int> flavors;\n    array<int, 4> flavor_counts = {0, 0, 0, 0}; // Index 1-3 used\n    vector<pair<int, int>> flavor_centers; // Center positions for each flavor\n    \npublic:\n    CandyClustering(const vector<int>& f) : flavors(f) {\n        // Initialize flavor centers based on distribution\n        initialize_flavor_centers();\n    }\n    \n    void initialize_flavor_centers() {\n        // Count flavors\n        for (int f : flavors) {\n            flavor_counts[f]++;\n        }\n        \n        // Calculate center positions for each flavor\n        int rows = grid.rows;\n        int cols = grid.cols;\n        \n        flavor_centers.resize(4); // Index 1-3 used\n        \n        // Divide the grid into three horizontal strips\n        int strip_height = rows / 3;\n        \n        if (flavor_counts[1] > 0) {\n            flavor_centers[1] = {strip_height / 2, cols / 2};\n        }\n        if (flavor_counts[2] > 0) {\n            flavor_centers[2] = {strip_height + strip_height / 2, cols / 2};\n        }\n        if (flavor_counts[3] > 0) {\n            flavor_centers[3] = {2 * strip_height + strip_height / 2, cols / 2};\n        }\n    }\n    \n    char decide_direction(int step, int pos) {\n        // Get the position where the candy is placed\n        auto [r, c] = grid.get_nth_empty(pos);\n        int flavor = flavors[step - 1];\n        \n        // Place the candy\n        grid.place(r, c, flavor);\n        \n        // If it's the last step, no tilt needed\n        if (step == 100) return ' ';\n        \n        // Update strategy based on current state\n        if (step % 20 == 0) {\n            update_flavor_centers();\n        }\n        \n        // Find the best direction to tilt\n        char best_dir = 'F';\n        double best_score = -1e9;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            // Create a copy of the grid to simulate the tilt\n            Grid temp_grid = grid;\n            temp_grid.tilt(dir);\n            \n            // Calculate score for this direction\n            double score = calculate_direction_score(temp_grid, flavor, r, c, dir, step);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        // Apply the tilt to the actual grid\n        grid.tilt(best_dir);\n        \n        return best_dir;\n    }\n    \n    void update_flavor_centers() {\n        // Calculate current center of mass for each flavor\n        array<vector<pair<int, int>>, 4> flavor_positions;\n        \n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (grid.cells[r][c] != 0) {\n                    flavor_positions[grid.cells[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!flavor_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : flavor_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_centers[f] = {sum_r / flavor_positions[f].size(), \n                                     sum_c / flavor_positions[f].size()};\n            }\n        }\n    }\n    \n    double calculate_direction_score(const Grid& g, int flavor, int r, int c, char dir, int step) {\n        double score = 0;\n        \n        // Find the new position of the candy after tilting\n        auto [new_r, new_c] = g.get_tilted_position(r, c, dir);\n        \n        // Prefer directions that move the candy closer to its flavor's center\n        auto center = flavor_centers[flavor];\n        double distance_before = sqrt(pow(r - center.first, 2) + pow(c - center.second, 2));\n        double distance_after = sqrt(pow(new_r - center.first, 2) + pow(new_c - center.second, 2));\n        score += (distance_before - distance_after) * 10;\n        \n        // Count same-flavor neighbors after tilting\n        int same_flavor_neighbors = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue; // Only 4 directions\n                int nr = new_r + dr;\n                int nc = new_c + dc;\n                if (g.is_valid(nr, nc) && g.cells[nr][nc] == flavor) {\n                    same_flavor_neighbors++;\n                }\n            }\n        }\n        score += same_flavor_neighbors * 50;\n        \n        // Penalize creating isolated candies\n        if (same_flavor_neighbors == 0) {\n            score -= 20;\n        }\n        \n        // In later stages, prefer directions that improve the overall score\n        if (step > 50) {\n            double current_score = grid.calculate_score();\n            double new_score = g.calculate_score();\n            score += (new_score - current_score) * 1000;\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    // Read flavor sequence\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n    \n    CandyClustering solver(flavors);\n    \n    // Process each step\n    for (int t = 1; t <= 100; ++t) {\n        int pos;\n        cin >> pos;\n        \n        char direction = solver.decide_direction(t, pos);\n        \n        if (t < 100) {\n            cout << direction << endl;\n            cout.flush();\n        }\n    }\n    \n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n#include <utility>\n#include <iomanip>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    int N = static_cast<int>(ceil((1.0 + sqrt(1 + 8 * M)) / 2.0));\n    if (N < 4) {\n        N = 4;\n    }\n\n    vector<pair<int, int>> pairs;\n    for (int a = 1; a <= N - 1; a++) {\n        for (int b = 1; b <= N - a; b++) {\n            pairs.push_back({a, b});\n        }\n    }\n\n    auto get_expected_vector = [N, eps](int a, int b) -> vector<double> {\n        double v1 = (a - 1) * (1 - 2 * eps) + eps * (N - 1);\n        double v2 = (b - 1) * (1 - 2 * eps) + eps * (N - 1);\n        double v3 = eps * (N - 1);\n        vector<double> vec;\n        vec.reserve(N);\n        for (int i = 0; i < N - a - b; i++) {\n            vec.push_back(v3);\n        }\n        for (int i = 0; i < b; i++) {\n            vec.push_back(v2);\n        }\n        for (int i = 0; i < a; i++) {\n            vec.push_back(v1);\n        }\n        return vec;\n    };\n\n    vector<pair<int, int>> chosen_pairs;\n    chosen_pairs.push_back(pairs[0]);\n    vector<pair<int, int>> available;\n    for (int i = 1; i < pairs.size(); i++) {\n        available.push_back(pairs[i]);\n    }\n\n    for (int i = 1; i < M; i++) {\n        double best_min_dist_sq = -1.0;\n        pair<int, int> best_pair;\n        int best_index = -1;\n\n        for (int idx = 0; idx < available.size(); idx++) {\n            auto p = available[idx];\n            vector<double> e_p = get_expected_vector(p.first, p.second);\n\n            double min_dist_sq = numeric_limits<double>::max();\n            for (auto& q : chosen_pairs) {\n                vector<double> e_q = get_expected_vector(q.first, q.second);\n                double d_sq = 0.0;\n                for (int j = 0; j < N; j++) {\n                    double diff = e_p[j] - e_q[j];\n                    d_sq += diff * diff;\n                }\n                if (d_sq < min_dist_sq) {\n                    min_dist_sq = d_sq;\n                }\n            }\n\n            if (min_dist_sq > best_min_dist_sq) {\n                best_min_dist_sq = min_dist_sq;\n                best_pair = p;\n                best_index = idx;\n            }\n        }\n\n        chosen_pairs.push_back(best_pair);\n        available.erase(available.begin() + best_index);\n    }\n\n    cout << N << endl;\n    for (auto& p : chosen_pairs) {\n        int a = p.first;\n        int b = p.second;\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if ((i < a && j < a) || (i >= a && i < a + b && j >= a && j < a + b)) {\n                    s += '1';\n                } else {\n                    s += '0';\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n\n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (H[idx] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                idx++;\n            }\n        }\n\n        sort(deg.begin(), deg.end());\n\n        int best_index = -1;\n        double best_dist_sq = numeric_limits<double>::max();\n\n        for (int i = 0; i < M; i++) {\n            int a = chosen_pairs[i].first;\n            int b = chosen_pairs[i].second;\n            vector<double> e_i = get_expected_vector(a, b);\n\n            double dist_sq = 0.0;\n            for (int j = 0; j < N; j++) {\n                double diff = deg[j] - e_i[j];\n                dist_sq += diff * diff;\n            }\n\n            if (dist_sq < best_dist_sq) {\n                best_dist_sq = dist_sq;\n                best_index = i;\n            }\n        }\n\n        cout << best_index << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int index;\n};\n\nusing ll = long long;\n\nll compute_alt(int u, int v, const Edge& e, const vector<vector<pair<int, int>>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, LLONG_MAX);\n    dist[u] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n    pq.push({0, u});\n\n    while (!pq.empty()) {\n        auto [d, node] = pq.top();\n        pq.pop();\n        if (d != dist[node]) continue;\n        if (node == v) return d;\n        for (auto [neighbor, weight] : adj[node]) {\n            if ((node == e.u && neighbor == e.v) || (node == e.v && neighbor == e.u)) {\n                continue;\n            }\n            ll new_dist = d + weight;\n            if (new_dist < dist[neighbor]) {\n                dist[neighbor] = new_dist;\n                pq.push({new_dist, neighbor});\n            }\n        }\n    }\n    return dist[v];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].index = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<vector<ll>> original_dist(N, vector<ll>(N, LLONG_MAX));\n    for (int i = 0; i < N; i++) {\n        vector<ll> dist(N, LLONG_MAX);\n        dist[i] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n        pq.push({0, i});\n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist[node]) continue;\n            for (auto [neighbor, weight] : adj[node]) {\n                ll new_dist = d + weight;\n                if (new_dist < dist[neighbor]) {\n                    dist[neighbor] = new_dist;\n                    pq.push({new_dist, neighbor});\n                }\n            }\n        }\n        for (int j = 0; j < N; j++) {\n            original_dist[i][j] = dist[j];\n        }\n    }\n\n    vector<double> criticality(M, 0.0);\n    for (int idx = 0; idx < M; idx++) {\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        int w = e.w;\n        ll alt_dist = compute_alt(u, v, e, adj);\n        if (alt_dist == LLONG_MAX) {\n            alt_dist = 1000000000;\n        }\n        ll increase = alt_dist - w;\n        if (increase < 0) increase = 0;\n\n        int count_S1 = 0;\n        for (int i = 0; i < N; i++) {\n            if (original_dist[i][u] == LLONG_MAX || original_dist[i][v] == LLONG_MAX) continue;\n            if (original_dist[i][u] + w == original_dist[i][v]) {\n                count_S1++;\n            }\n        }\n\n        int count_S2 = 0;\n        for (int j = 0; j < N; j++) {\n            if (original_dist[u][j] == LLONG_MAX || original_dist[v][j] == LLONG_MAX) continue;\n            if (original_dist[u][j] == original_dist[v][j] + w) {\n                count_S2++;\n            }\n        }\n\n        int count_T1 = 0;\n        for (int i = 0; i < N; i++) {\n            if (original_dist[i][v] == LLONG_MAX || original_dist[i][u] == LLONG_MAX) continue;\n            if (original_dist[i][v] + w == original_dist[i][u]) {\n                count_T1++;\n            }\n        }\n\n        int count_T2 = 0;\n        for (int j = 0; j < N; j++) {\n            if (original_dist[v][j] == LLONG_MAX || original_dist[u][j] == LLONG_MAX) continue;\n            if (original_dist[v][j] == original_dist[u][j] + w) {\n                count_T2++;\n            }\n        }\n\n        ll total_count = (ll)count_S1 * count_S2 + (ll)count_T1 * count_T2;\n        criticality[idx] = (double)increase * total_count;\n    }\n\n    vector<int> edge_indices(M);\n    for (int i = 0; i < M; i++) {\n        edge_indices[i] = i;\n    }\n\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return criticality[a] > criticality[b];\n    });\n\n    double max_crit = 0.0;\n    for (int i = 0; i < M; i++) {\n        if (criticality[i] > max_crit) {\n            max_crit = criticality[i];\n        }\n    }\n\n    vector<int> assignment(M, -1);\n    vector<double> day_criticality(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<vector<int>> vertex_day_count(N, vector<int>(D, 0));\n\n    for (int i = 0; i < M; i++) {\n        int idx = edge_indices[i];\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        double min_cost = 1e20;\n        int best_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict_count = vertex_day_count[u][d] + vertex_day_count[v][d];\n            double norm_crit = (max_crit > 0) ? (criticality[idx] / max_crit) : 0.0;\n            double cost = conflict_count + 10.0 * norm_crit;\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_day = d;\n            }\n        }\n        assignment[idx] = best_day;\n        day_criticality[best_day] += criticality[idx];\n        day_count[best_day]++;\n        vertex_day_count[u][best_day]++;\n        vertex_day_count[v][best_day]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] + 1;\n        if (i < M - 1) {\n            cout << \" \";\n        } else {\n            cout << endl;\n        }\n    }\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n#include <map>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[6] = {1, 0, 0, -1, 0, 0};\nconst int dy[6] = {0, 1, 0, 0, -1, 0};\nconst int dz[6] = {0, 0, 1, 0, 0, -1};\n\nusing Point = tuple<int, int, int>;\n\nvector<set<Point>> get_connected_components_from_set(const set<Point>& points) {\n    set<Point> visited;\n    vector<set<Point>> components;\n    for (const auto& p : points) {\n        if (visited.find(p) == visited.end()) {\n            set<Point> comp;\n            queue<Point> q;\n            q.push(p);\n            visited.insert(p);\n            while (!q.empty()) {\n                auto [x, y, z] = q.front(); q.pop();\n                comp.insert({x, y, z});\n                for (int dir = 0; dir < 6; dir++) {\n                    int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                    Point np = {nx, ny, nz};\n                    if (points.find(np) != points.end() && visited.find(np) == visited.end()) {\n                        visited.insert(np);\n                        q.push(np);\n                    }\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\nvector<set<Point>> get_connected_components_from_grid(const vector<vector<vector<bool>>>& grid, int D) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<set<Point>> components;\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (grid[z][x][y] && !visited[z][x][y]) {\n                    set<Point> comp;\n                    queue<Point> q;\n                    q.push({x, y, z});\n                    visited[z][x][y] = true;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.insert({cx, cy, cz});\n                        for (int dir = 0; dir < 6; dir++) {\n                            int nx = cx + dx[dir], ny = cy + dy[dir], nz = cz + dz[dir];\n                            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) \n                                continue;\n                            if (grid[nz][nx][ny] && !visited[nz][nx][ny]) {\n                                visited[nz][nx][ny] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n    return components;\n}\n\nbool dfs(int u, vector<vector<int>>& graph, vector<int>& match, vector<bool>& visited) {\n    for (int v : graph[u]) {\n        if (!visited[v]) {\n            visited[v] = true;\n            if (match[v] == -1 || dfs(match[v], graph, match, visited)) {\n                match[v] = u;\n                return true;\n            }\n        }\n    }\n    return false;\n}\n\nint bipartite_matching(vector<vector<int>>& graph, int n_left, int n_right) {\n    vector<int> match(n_right, -1);\n    int matching = 0;\n    for (int u = 0; u < n_left; u++) {\n        vector<bool> visited(n_right, false);\n        if (dfs(u, graph, match, visited)) {\n            matching++;\n        }\n    }\n    return matching;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> cand1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> cand2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> Common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (f1[z][x] == '1' && r1[z][y] == '1') {\n                    cand1[z][x][y] = true;\n                }\n                if (f2[z][x] == '1' && r2[z][y] == '1') {\n                    cand2[z][x][y] = true;\n                }\n                if (cand1[z][x][y] && cand2[z][x][y]) {\n                    Common[z][x][y] = true;\n                }\n            }\n        }\n    }\n\n    set<Point> A1_set, B1_set;\n\n    auto process_object = [&](const vector<string>& f, const vector<string>& r, \n                              const vector<vector<vector<bool>>>& cand, \n                              const vector<vector<vector<bool>>>& common, \n                              set<Point>& additional_set) {\n        vector<vector<bool>> uncovered_front(D, vector<bool>(D, false));\n        vector<vector<bool>> uncovered_right(D, vector<bool>(D, false));\n\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (f[z][x] == '1') {\n                    bool covered = false;\n                    for (int y = 0; y < D; y++) {\n                        if (common[z][x][y]) {\n                            covered = true;\n                            break;\n                        }\n                    }\n                    if (!covered) {\n                        uncovered_front[z][x] = true;\n                    }\n                }\n            }\n        }\n\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (r[z][y] == '1') {\n                    bool covered = false;\n                    for (int x = 0; x < D; x++) {\n                        if (common[z][x][y]) {\n                            covered = true;\n                            break;\n                        }\n                    }\n                    if (!covered) {\n                        uncovered_right[z][y] = true;\n                    }\n                }\n            }\n        }\n\n        vector<Point> L_list;\n        vector<Point> R_list;\n        map<Point, int> L_index, R_index;\n\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (uncovered_front[z][x]) {\n                    L_list.push_back({x, z, -1});\n                }\n            }\n        }\n\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (uncovered_right[z][y]) {\n                    R_list.push_back({y, z, -1});\n                }\n            }\n        }\n\n        for (int i = 0; i < L_list.size(); i++) {\n            L_index[L_list[i]] = i;\n        }\n        for (int j = 0; j < R_list.size(); j++) {\n            R_index[R_list[j]] = j;\n        }\n\n        vector<vector<int>> graph(L_list.size());\n        for (int i = 0; i < L_list.size(); i++) {\n            auto [x, z, dummy] = L_list[i];\n            for (int y = 0; y < D; y++) {\n                if (cand[z][x][y] && !common[z][x][y] && uncovered_right[z][y]) {\n                    Point r_node = {y, z, -1};\n                    if (R_index.find(r_node) != R_index.end()) {\n                        int j = R_index[r_node];\n                        graph[i].push_back(j);\n                    }\n                }\n            }\n        }\n\n        int n_left = L_list.size();\n        int n_right = R_list.size();\n        int matching_size = bipartite_matching(graph, n_left, n_right);\n\n        vector<int> match_R(n_right, -1);\n        {\n            vector<int> match(n_right, -1);\n            for (int u = 0; u < n_left; u++) {\n                vector<bool> visited(n_right, false);\n                dfs(u, graph, match, visited);\n            }\n            match_R = match;\n        }\n\n        set<int> matched_L, matched_R;\n        for (int j = 0; j < n_right; j++) {\n            if (match_R[j] != -1) {\n                matched_L.insert(match_R[j]);\n                matched_R.insert(j);\n            }\n        }\n\n        set<Point> cover_edges;\n        for (int i = 0; i < n_left; i++) {\n            if (matched_L.find(i) == matched_L.end()) {\n                for (int j : graph[i]) {\n                    auto [x, z, dummy] = L_list[i];\n                    auto [y, z2, dummy2] = R_list[j];\n                    cover_edges.insert({x, y, z});\n                    break;\n                }\n            }\n        }\n\n        for (int j = 0; j < n_right; j++) {\n            if (matched_R.find(j) == matched_R.end()) {\n                for (int i = 0; i < n_left; i++) {\n                    auto it = find(graph[i].begin(), graph[i].end(), j);\n                    if (it != graph[i].end()) {\n                        auto [x, z, dummy] = L_list[i];\n                        auto [y, z2, dummy2] = R_list[j];\n                        cover_edges.insert({x, y, z});\n                        break;\n                    }\n                }\n            }\n        }\n\n        for (int i = 0; i < n_left; i++) {\n            if (matched_L.find(i) != matched_L.end()) {\n                for (int j : graph[i]) {\n                    if (match_R[j] == i) {\n                        auto [x, z, dummy] = L_list[i];\n                        auto [y, z2, dummy2] = R_list[j];\n                        cover_edges.insert({x, y, z});\n                    }\n                }\n            }\n        }\n\n        additional_set = cover_edges;\n    };\n\n    process_object(f1, r1, cand1, Common, A1_set);\n    process_object(f2, r2, cand2, Common, B1_set);\n\n    auto common_components = get_connected_components_from_grid(Common, D);\n    auto a1_components = get_connected_components_from_set(A1_set);\n    auto b1_components = get_connected_components_from_set(B1_set);\n\n    int n = common_components.size() + a1_components.size() + b1_components.size();\n    vector<int> arr1(D*D*D, 0);\n    vector<int> arr2(D*D*D, 0);\n\n    int block_id = 1;\n    for (const auto& comp : common_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : a1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : b1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    cout << n << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr1[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr2[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <queue>\n#include <unordered_set>\n#include <chrono>\n#include <iomanip>\n#include <limits>\n\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    ll x, y;\n    \n    Point() : x(0), y(0) {}\n    Point(ll x, ll y) : x(x), y(y) {}\n    \n    ll dist2(const Point& other) const {\n        ll dx = x - other.x;\n        ll dy = y - other.y;\n        return dx * dx + dy * dy;\n    }\n    \n    double dist(const Point& other) const {\n        return sqrt(dist2(other));\n    }\n};\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int idx;\n    \n    Edge(int u, int v, ll w, int idx) : u(u), v(v), w(w), idx(idx) {}\n    \n    bool operator<(const Edge& other) const {\n        return w < other.w;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    ll cost;\n    int covered;\n    \n    Solution(int N, int M) : P(N, 0), B(M, 0), cost(0), covered(0) {}\n};\n\nclass TVNetworkOptimizer {\nprivate:\n    int N, M, K;\n    vector<Point> stations;\n    vector<Point> residents;\n    vector<Edge> edges;\n    vector<vector<pair<int, ll>>> adj; // adjacency list\n    \n    // Random number generation\n    mt19937 rng;\n    \n    // Best solution found\n    Solution best_solution;\n    \n    // Distance matrices\n    vector<vector<double>> station_to_resident_dist;\n    vector<vector<double>> station_to_station_dist;\n    \npublic:\n    TVNetworkOptimizer() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void read_input() {\n        cin >> N >> M >> K;\n        \n        stations.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> stations[i].x >> stations[i].y;\n        }\n        \n        edges.reserve(M);\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v;\n            ll w;\n            cin >> u >> v >> w;\n            u--; v--;\n            edges.emplace_back(u, v, w, i);\n            adj[u].emplace_back(v, w);\n            adj[v].emplace_back(u, w);\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].x >> residents[i].y;\n        }\n        \n        // Precompute distances\n        compute_distances();\n    }\n    \n    void compute_distances() {\n        station_to_resident_dist.resize(N, vector<double>(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                station_to_resident_dist[i][j] = stations[i].dist(residents[j]);\n            }\n        }\n        \n        station_to_station_dist.resize(N, vector<double>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                station_to_station_dist[i][j] = stations[i].dist(stations[j]);\n            }\n        }\n    }\n    \n    // Build initial MST solution\n    Solution build_mst_solution() {\n        Solution sol(N, M);\n        \n        // Prim's algorithm for MST\n        vector<bool> in_mst(N, false);\n        vector<ll> min_edge(N, numeric_limits<ll>::max());\n        vector<int> parent(N, -1);\n        \n        min_edge[0] = 0;\n        \n        for (int i = 0; i < N; i++) {\n            int u = -1;\n            for (int v = 0; v < N; v++) {\n                if (!in_mst[v] && (u == -1 || min_edge[v] < min_edge[u])) {\n                    u = v;\n                }\n            }\n            \n            if (min_edge[u] == numeric_limits<ll>::max()) break;\n            \n            in_mst[u] = true;\n            \n            if (parent[u] != -1) {\n                // Find the edge between u and parent[u]\n                for (const auto& edge : edges) {\n                    if ((edge.u == u && edge.v == parent[u]) || \n                        (edge.u == parent[u] && edge.v == u)) {\n                        sol.B[edge.idx] = 1;\n                        sol.cost += edge.w;\n                        break;\n                    }\n                }\n            }\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!in_mst[v] && w < min_edge[v]) {\n                    min_edge[v] = w;\n                    parent[v] = u;\n                }\n            }\n        }\n        \n        // Assign powers to cover residents\n        assign_powers(sol);\n        \n        return sol;\n    }\n    \n    // Assign powers to vertices to cover residents\n    void assign_powers(Solution& sol) {\n        vector<bool> covered(K, false);\n        sol.covered = 0;\n        \n        // First, find which vertices are reachable from vertex 1\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find the closest reachable station\n        vector<vector<int>> assignments(N);\n        for (int k = 0; k < K; k++) {\n            double min_dist = numeric_limits<double>::max();\n            int best_station = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (reachable[i] && station_to_resident_dist[i][k] < min_dist) {\n                    min_dist = station_to_resident_dist[i][k];\n                    best_station = i;\n                }\n            }\n            \n            if (best_station != -1) {\n                assignments[best_station].push_back(k);\n            }\n        }\n        \n        // Calculate power for each station\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            if (!assignments[i].empty()) {\n                double max_dist = 0;\n                for (int k : assignments[i]) {\n                    max_dist = max(max_dist, station_to_resident_dist[i][k]);\n                }\n                sol.P[i] = min(5000, static_cast<int>(ceil(max_dist)));\n                power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n                \n                for (int k : assignments[i]) {\n                    if (!covered[k]) {\n                        covered[k] = true;\n                        sol.covered++;\n                    }\n                }\n            } else {\n                sol.P[i] = 0;\n            }\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    // Find vertices reachable from vertex 1\n    vector<bool> find_reachable(const vector<int>& B) {\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!reachable[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                reachable[v] = true;\n                                q.push(v);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return reachable;\n    }\n    \n    // Calculate total edge cost\n    ll get_edge_cost(const vector<int>& B) {\n        ll cost = 0;\n        for (int i = 0; i < M; i++) {\n            if (B[i]) {\n                cost += edges[i].w;\n            }\n        }\n        return cost;\n    }\n    \n    // Try to improve solution by adding/removing edges\n    Solution local_search(const Solution& initial_sol) {\n        Solution best_sol = initial_sol;\n        Solution current_sol = initial_sol;\n        \n        uniform_int_distribution<int> edge_dist(0, M-1);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        double temperature = 1000.0;\n        double cooling_rate = 0.995;\n        int iterations = 10000;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Try random edge operation\n            int edge_idx = edge_dist(rng);\n            Solution new_sol = current_sol;\n            \n            if (new_sol.B[edge_idx] == 1) {\n                // Try removing edge\n                new_sol.B[edge_idx] = 0;\n                if (is_connected(new_sol.B)) {\n                    assign_powers(new_sol);\n                } else {\n                    new_sol.B[edge_idx] = 1; // Revert if disconnected\n                }\n            } else {\n                // Try adding edge\n                new_sol.B[edge_idx] = 1;\n                assign_powers(new_sol);\n            }\n            \n            // Accept or reject based on simulated annealing\n            if (accept_solution(current_sol, new_sol, temperature)) {\n                current_sol = new_sol;\n                if (current_sol.covered == K && \n                    (best_sol.covered < K || current_sol.cost < best_sol.cost)) {\n                    best_sol = current_sol;\n                }\n            }\n            \n            temperature *= cooling_rate;\n        }\n        \n        return best_sol;\n    }\n    \n    // Check if the graph with selected edges is connected\n    bool is_connected(const vector<int>& B) {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!visited[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                visited[v] = true;\n                                q.push(v);\n                                count++;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return count == N;\n    }\n    \n    // Simulated annealing acceptance criterion\n    bool accept_solution(const Solution& current, const Solution& new_sol, double temperature) {\n        if (new_sol.covered > current.covered) return true;\n        if (new_sol.covered < current.covered) return false;\n        \n        if (new_sol.cost < current.cost) return true;\n        \n        if (temperature < 1e-6) return false;\n        \n        double delta = new_sol.cost - current.cost;\n        double prob = exp(-delta / temperature);\n        \n        uniform_real_distribution<double> dist(0.0, 1.0);\n        return dist(rng) < prob;\n    }\n    \n    // Optimize power assignments given fixed network\n    void optimize_powers(Solution& sol) {\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find all stations that can cover it\n        vector<vector<int>> covering_stations(K);\n        for (int k = 0; k < K; k++) {\n            for (int i = 0; i < N; i++) {\n                if (reachable[i]) {\n                    double dist = station_to_resident_dist[i][k];\n                    if (dist <= 5000) {\n                        covering_stations[k].push_back(i);\n                    }\n                }\n            }\n        }\n        \n        // Greedily assign residents to minimize total power cost\n        vector<bool> covered(K, false);\n        vector<int> assignments(K, -1);\n        sol.covered = 0;\n        \n        // Sort residents by number of covering stations (ascending)\n        vector<int> resident_order(K);\n        for (int k = 0; k < K; k++) resident_order[k] = k;\n        sort(resident_order.begin(), resident_order.end(), \n             [&](int a, int b) { \n                 return covering_stations[a].size() < covering_stations[b].size(); \n             });\n        \n        for (int k : resident_order) {\n            if (covered[k]) continue;\n            \n            // Find best station for this resident\n            int best_station = -1;\n            double best_cost = numeric_limits<double>::max();\n            \n            for (int station : covering_stations[k]) {\n                double dist = station_to_resident_dist[station][k];\n                double additional_cost = dist * dist;\n                \n                // Check how many additional residents this station would cover\n                int additional_cover = 0;\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && station_to_resident_dist[station][other] <= dist) {\n                        additional_cover++;\n                    }\n                }\n                \n                double cost_per_resident = additional_cost / max(1, additional_cover);\n                \n                if (cost_per_resident < best_cost) {\n                    best_cost = cost_per_resident;\n                    best_station = station;\n                }\n            }\n            \n            if (best_station != -1) {\n                double required_power = station_to_resident_dist[best_station][k];\n                \n                // Assign this resident and others that can be covered\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && \n                        station_to_resident_dist[best_station][other] <= required_power) {\n                        covered[other] = true;\n                        assignments[other] = best_station;\n                        sol.covered++;\n                    }\n                }\n            }\n        }\n        \n        // Set powers based on assignments\n        vector<double> max_power(N, 0.0);\n        for (int k = 0; k < K; k++) {\n            if (assignments[k] != -1) {\n                max_power[assignments[k]] = max(max_power[assignments[k]], \n                                               station_to_resident_dist[assignments[k]][k]);\n            }\n        }\n        \n        // Calculate power cost\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            sol.P[i] = min(5000, static_cast<int>(ceil(max_power[i])));\n            power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    void solve() {\n        // Build initial MST solution\n        Solution sol = build_mst_solution();\n        \n        // Optimize power assignments\n        optimize_powers(sol);\n        best_solution = sol;\n        \n        // Run local search with simulated annealing\n        for (int trial = 0; trial < 5; trial++) {\n            Solution improved = local_search(best_solution);\n            optimize_powers(improved);\n            \n            if (improved.covered == K && \n                (best_solution.covered < K || improved.cost < best_solution.cost)) {\n                best_solution = improved;\n            }\n        }\n        \n        // Final power optimization\n        optimize_powers(best_solution);\n        \n        // Output solution\n        output_solution(best_solution);\n    }\n    \n    void output_solution(const Solution& sol) {\n        for (int i = 0; i < N; i++) {\n            cout << sol.P[i];\n            if (i < N - 1) cout << \" \";\n        }\n        cout << endl;\n        \n        for (int i = 0; i < M; i++) {\n            cout << sol.B[i];\n            if (i < M - 1) cout << \" \";\n        }\n        cout << endl;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TVNetworkOptimizer optimizer;\n    optimizer.read_input();\n    optimizer.solve();\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n\nusing namespace std;\n\nvector<vector<int>> pyramid;\nvector<tuple<int, int, int, int>> operations;\n\n// Check if two positions are adjacent\nbool is_adjacent(int x1, int y1, int x2, int y2) {\n    return (x1 == x2 - 1 && y1 == y2 - 1) ||\n           (x1 == x2 - 1 && y1 == y2) ||\n           (x1 == x2 && y1 == y2 - 1) ||\n           (x1 == x2 && y1 == y2 + 1) ||\n           (x1 == x2 + 1 && y1 == y2) ||\n           (x1 == x2 + 1 && y1 == y2 + 1);\n}\n\n// Count the number of violations\nint count_violations() {\n    int violations = 0;\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) violations++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) violations++;\n        }\n    }\n    return violations;\n}\n\n// Swap two balls and record the operation\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    if (!is_adjacent(x1, y1, x2, y2)) {\n        cerr << \"Error: Attempting to swap non-adjacent balls\" << endl;\n        return;\n    }\n    operations.emplace_back(x1, y1, x2, y2);\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n}\n\n// Top-down pass: ensure each ball is smaller than those below it\nvoid top_down_pass() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            int left_child = pyramid[x+1][y];\n            int right_child = pyramid[x+1][y+1];\n            \n            if (current > left_child || current > right_child) {\n                // Find the smaller child\n                if (left_child < right_child) {\n                    // Swap with left child\n                    swap_balls(x, y, x+1, y);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                } else {\n                    // Swap with right child\n                    swap_balls(x, y, x+1, y+1);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y+1;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Bubble up larger numbers towards the bottom\nvoid bubble_up() {\n    for (int x = 28; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check if current is larger than its parent\n            if (x > 0) {\n                int parent_y = -1;\n                if (y <= x-1 && pyramid[x-1][y] < current) {\n                    parent_y = y;\n                } else if (y > 0 && pyramid[x-1][y-1] < current) {\n                    parent_y = y-1;\n                }\n                \n                if (parent_y != -1) {\n                    // Swap with parent\n                    swap_balls(x, y, x-1, parent_y);\n                }\n            }\n        }\n    }\n}\n\n// Local refinement: fix specific violations\nvoid local_refinement() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check violation with left child\n            if (current > pyramid[x+1][y]) {\n                // Try to find a better position for current\n                bool found = false;\n                \n                // Check adjacent positions\n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    // Just swap with the child\n                    swap_balls(x, y, x+1, y);\n                }\n            }\n            \n            // Check violation with right child\n            if (current > pyramid[x+1][y+1]) {\n                // Similar logic as above\n                bool found = false;\n                \n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    swap_balls(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    pyramid.resize(30);\n    for (int x = 0; x < 30; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Apply our algorithm\n    int max_operations = 10000;\n    \n    // Initial top-down pass\n    top_down_pass();\n    \n    // Iterative improvement\n    while (operations.size() < max_operations) {\n        int violations_before = count_violations();\n        if (violations_before == 0) break;\n        \n        // Try different strategies\n        if (operations.size() % 3 == 0) {\n            bubble_up();\n        } else if (operations.size() % 3 == 1) {\n            top_down_pass();\n        } else {\n            local_refinement();\n        }\n        \n        // Check if we're making progress\n        int violations_after = count_violations();\n        if (violations_after >= violations_before) {\n            // Not making progress, try a different approach\n            break;\n        }\n    }\n    \n    // Final pass to fix remaining violations\n    if (operations.size() < max_operations) {\n        local_refinement();\n    }\n    \n    // Output the result\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <iomanip>\n\nusing namespace std;\n\nconst int D = 9;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nint grid[D][D];\nint base_distance[D][D];\n\nvoid bfs_base() {\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_distance[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_distance[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (base_distance[nx][ny] == -1 && grid[nx][ny] != -1) {\n                    base_distance[nx][ny] = base_distance[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nstruct BFSResult {\n    bool visited[D][D];\n    int dist[D][D];\n};\n\nBFSResult bfs_current() {\n    BFSResult res;\n    memset(res.visited, false, sizeof(res.visited));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            res.dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    res.visited[0][4] = true;\n    res.dist[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (!res.visited[nx][ny]) {\n                    if (grid[nx][ny] == 0 || grid[nx][ny] == -2) {\n                        res.visited[nx][ny] = true;\n                        res.dist[nx][ny] = res.dist[x][y] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n    }\n    return res;\n}\n\nbool check_reachability_after_placing(int i, int j, int t_d) {\n    grid[i][j] = t_d;\n    BFSResult res = bfs_current();\n    vector<pair<int, int>> container_cells;\n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            if (grid[x][y] >= 0) {\n                container_cells.push_back({x, y});\n            }\n        }\n    }\n    bool all_reachable = true;\n    for (auto [x, y] : container_cells) {\n        bool reachable = false;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (res.visited[nx][ny]) {\n                    reachable = true;\n                    break;\n                }\n            }\n        }\n        if (!reachable) {\n            all_reachable = false;\n            break;\n        }\n    }\n    grid[i][j] = 0;\n    return all_reachable;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    cin >> N;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            grid[i][j] = 0;\n        }\n    }\n    grid[0][4] = -2;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    bfs_base();\n\n    int min_base = INT_MAX, max_base = INT_MIN;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == 4) continue;\n            if (grid[i][j] == -1) continue;\n            if (base_distance[i][j] == -1) continue;\n            if (base_distance[i][j] < min_base) min_base = base_distance[i][j];\n            if (base_distance[i][j] > max_base) max_base = base_distance[i][j];\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    if (M > 0) {\n        for (int d = 0; d < M; d++) {\n            int t_d;\n            cin >> t_d;\n\n            double desired;\n            if (M == 1) {\n                desired = min_base;\n            } else {\n                desired = (double)(t_d) / (M - 1) * (max_base - min_base) + min_base;\n            }\n\n            BFSResult res1 = bfs_current();\n            vector<pair<int, int>> candidate_cells;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] == 0 && res1.visited[i][j]) {\n                        candidate_cells.push_back({i, j});\n                    }\n                }\n            }\n\n            vector<pair<int, int>> valid_candidates;\n            vector<double> costs;\n            vector<int> current_dists;\n\n            for (auto [i, j] : candidate_cells) {\n                if (check_reachability_after_placing(i, j, t_d)) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            if (valid_candidates.empty()) {\n                for (auto [i, j] : candidate_cells) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            int best_index = 0;\n            for (int idx = 1; idx < valid_candidates.size(); idx++) {\n                if (costs[idx] < costs[best_index]) {\n                    best_index = idx;\n                } else if (costs[idx] == costs[best_index]) {\n                    if (current_dists[idx] < current_dists[best_index]) {\n                        best_index = idx;\n                    } else if (current_dists[idx] == current_dists[best_index]) {\n                        if (base_distance[valid_candidates[idx].first][valid_candidates[idx].second] < \n                            base_distance[valid_candidates[best_index].first][valid_candidates[best_index].second]) {\n                            best_index = idx;\n                        }\n                    }\n                }\n            }\n\n            auto [i, j] = valid_candidates[best_index];\n            grid[i][j] = t_d;\n            cout << i << \" \" << j << endl;\n            cout.flush();\n        }\n    }\n\n    if (M > 0) {\n        vector<pair<int, int>> transport_order;\n        for (int step = 0; step < M; step++) {\n            BFSResult res = bfs_current();\n            vector<pair<int, int>> reachable_containers;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] >= 0) {\n                        for (int d = 0; d < 4; d++) {\n                            int ni = i + dx[d], nj = j + dy[d];\n                            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                                if (res.visited[ni][nj]) {\n                                    reachable_containers.push_back({i, j});\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int min_number = INT_MAX;\n            pair<int, int> min_cell = {-1, -1};\n            for (auto [i, j] : reachable_containers) {\n                if (grid[i][j] < min_number) {\n                    min_number = grid[i][j];\n                    min_cell = {i, j};\n                }\n            }\n\n            grid[min_cell.first][min_cell.second] = 0;\n            transport_order.push_back(min_cell);\n        }\n\n        for (auto [i, j] : transport_order) {\n            cout << i << \" \" << j << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nconst int dx[4] = {1, 0, -1, 0};\nconst int dy[4] = {0, 1, 0, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<vector<bool>> adj(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 = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    adj[c1][0] = true;\n                    adj[0][c1] = true;\n                } else {\n                    int c2 = grid[ni][nj];\n                    if (c1 != c2) {\n                        adj[c1][c2] = true;\n                        adj[c2][c1] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> new_grid(n, vector<int>(n, -1));\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<tuple<int, int, int>> q;\n\n    vector<int> A;\n    for (int c = 1; c <= m; c++) {\n        if (adj[c][0]) {\n            A.push_back(c);\n        }\n    }\n\n    vector<vector<int>> H(A.size());\n    for (int i = 0; i < A.size(); i++) {\n        for (int j = i+1; j < A.size(); j++) {\n            if (adj[A[i]][A[j]]) {\n                H[i].push_back(j);\n                H[j].push_back(i);\n            }\n        }\n    }\n\n    vector<int> order;\n    vector<bool> done(H.size(), false);\n    if (!H.empty()) {\n        queue<int> qq;\n        qq.push(0);\n        done[0] = true;\n        while (!qq.empty()) {\n            int u = qq.front(); qq.pop();\n            order.push_back(u);\n            for (int v : H[u]) {\n                if (!done[v]) {\n                    done[v] = true;\n                    qq.push(v);\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> boundary;\n    for (int j = 0; j < n; j++) {\n        boundary.emplace_back(0, j);\n    }\n    for (int i = 1; i < n; i++) {\n        boundary.emplace_back(i, n-1);\n    }\n    for (int j = n-2; j >= 0; j--) {\n        boundary.emplace_back(n-1, j);\n    }\n    for (int i = n-2; i >= 1; i--) {\n        boundary.emplace_back(i, 0);\n    }\n\n    vector<int> boundary_assignment;\n    if (!order.empty()) {\n        boundary_assignment.push_back(A[order[0]]);\n        for (int i = 1; i < order.size(); i++) {\n            int u = order[i-1];\n            int v = order[i];\n            bool adj_in_H = false;\n            for (int w : H[u]) {\n                if (w == v) {\n                    adj_in_H = true;\n                    break;\n                }\n            }\n            if (!adj_in_H) {\n                boundary_assignment.push_back(0);\n            }\n            boundary_assignment.push_back(A[v]);\n        }\n        int u = order.back();\n        int v = order[0];\n        bool adj_in_H = false;\n        for (int w : H[u]) {\n            if (w == v) {\n                adj_in_H = true;\n                break;\n            }\n        }\n        if (!adj_in_H) {\n            boundary_assignment.push_back(0);\n        }\n    }\n\n    for (int idx = 0; idx < boundary.size(); idx++) {\n        int color = (idx < boundary_assignment.size()) ? boundary_assignment[idx] : 0;\n        int i = boundary[idx].first;\n        int j = boundary[idx].second;\n        new_grid[i][j] = color;\n        visited[i][j] = true;\n        if (color != 0) {\n            q.push({i, j, color});\n        }\n    }\n\n    while (!q.empty()) {\n        auto [i, j, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n            if (visited[ni][nj]) continue;\n            bool can_assign = true;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + dx[dd];\n                int nnj = nj + dy[dd];\n                if (nni < 0 || nni >= n || nnj < 0 || nnj >= n) continue;\n                if (new_grid[nni][nnj] == -1) continue;\n                int d_color = new_grid[nni][nnj];\n                if (d_color == 0) continue;\n                if (d_color == c) continue;\n                if (!adj[c][d_color]) {\n                    can_assign = false;\n                    break;\n                }\n            }\n            if (can_assign) {\n                new_grid[ni][nj] = c;\n                visited[ni][nj] = true;\n                q.push({ni, nj, c});\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (new_grid[i][j] == -1) {\n                new_grid[i][j] = 0;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << new_grid[i][j] << (j < n-1 ? ' ' : '\\n');\n        }\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\n\n// Random number generator\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to output a query and get the result\nchar query(int nL, int nR, const vector<int>& L, const vector<int>& R) {\n    cout << nL << \" \" << nR;\n    for (int i : L) cout << \" \" << i;\n    for (int i : R) cout << \" \" << i;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\n// Function to partition items into D sets based on estimated weights\nvector<int> partition_items(int N, int D, const vector<double>& estimated_weights) {\n    // Create pairs of (item_index, estimated_weight)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.emplace_back(estimated_weights[i], i);\n    }\n    \n    // Sort items by estimated weight in descending order\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize D sets\n    vector<double> set_weights(D, 0.0);\n    vector<int> assignment(N, -1);\n    \n    // Greedy assignment: assign each item to the set with the smallest current total weight\n    for (const auto& [weight, idx] : items) {\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        assignment[idx] = min_set;\n        set_weights[min_set] += weight;\n    }\n    \n    // Try to improve the partition by swapping items between sets\n    for (int iter = 0; iter < 50; iter++) {\n        // Calculate the current variance\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        double variance = 0.0;\n        for (double w : set_weights) {\n            variance += (w - mean) * (w - mean);\n        }\n        variance /= D;\n        \n        // Try to find a swap that reduces the variance\n        bool improved = false;\n        \n        // Try a limited number of random swaps\n        for (int trial = 0; trial < 20; trial++) {\n            int i = rng() % N;\n            int j = rng() % N;\n            while (i == j) {\n                j = rng() % N;\n            }\n            \n            if (assignment[i] != assignment[j]) {\n                // Calculate the new variance if we swap items i and j\n                int set_i = assignment[i];\n                int set_j = assignment[j];\n                \n                double new_weight_i = set_weights[set_i] - estimated_weights[i] + estimated_weights[j];\n                double new_weight_j = set_weights[set_j] - estimated_weights[j] + estimated_weights[i];\n                \n                double new_variance = variance;\n                new_variance -= (set_weights[set_i] - mean) * (set_weights[set_i] - mean) / D;\n                new_variance -= (set_weights[set_j] - mean) * (set_weights[set_j] - mean) / D;\n                new_variance += (new_weight_i - mean) * (new_weight_i - mean) / D;\n                new_variance += (new_weight_j - mean) * (new_weight_j - mean) / D;\n                \n                if (new_variance < variance) {\n                    // Swap the items\n                    assignment[i] = set_j;\n                    assignment[j] = set_i;\n                    set_weights[set_i] = new_weight_i;\n                    set_weights[set_j] = new_weight_j;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Initialize estimated weights\n    vector<double> estimated_weights(N, 1.0);\n    \n    // Keep track of how many times each item has been compared\n    vector<int> compare_count(N, 0);\n    \n    // Use queries to estimate relative weights\n    for (int q = 0; q < Q; q++) {\n        if (q < Q / 2) {\n            // First half: Compare individual items\n            // Try to compare items that haven't been compared much\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            int i = -1, j = -1;\n            for (int idx : indices) {\n                if (compare_count[idx] < 3) {\n                    if (i == -1) {\n                        i = idx;\n                    } else {\n                        j = idx;\n                        break;\n                    }\n                }\n            }\n            \n            // If we couldn't find two items with low compare count, just pick random ones\n            if (i == -1 || j == -1) {\n                i = rng() % N;\n                j = rng() % N;\n                while (i == j) {\n                    j = rng() % N;\n                }\n            }\n            \n            char result = query(1, 1, {i}, {j});\n            compare_count[i]++;\n            compare_count[j]++;\n            \n            // Update estimates based on result\n            // Use a larger adjustment for items with low compare count\n            double adjustment = 0.1 * (1.0 + 0.1 * (3 - min(compare_count[i], compare_count[j])));\n            if (result == '>') {\n                estimated_weights[i] *= (1.0 + adjustment);\n                estimated_weights[j] *= (1.0 - adjustment);\n            } else if (result == '<') {\n                estimated_weights[i] *= (1.0 - adjustment);\n                estimated_weights[j] *= (1.0 + adjustment);\n            }\n        } else {\n            // Second half: Compare groups of items\n            // Try to create balanced groups based on current estimates\n            \n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            // Sort by estimated weight to group similar items\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return estimated_weights[a] < estimated_weights[b];\n            });\n            \n            int group_size = 2 + rng() % min(5, N / 4);\n            \n            // Pick a random starting point\n            int start = rng() % (N - 2 * group_size);\n            \n            vector<int> group1, group2;\n            for (int i = 0; i < group_size; i++) {\n                group1.push_back(indices[start + i]);\n                group2.push_back(indices[start + group_size + i]);\n            }\n            \n            char result = query(group_size, group_size, group1, group2);\n            \n            // Update estimates based on result\n            double adjustment = 0.05;\n            if (result == '>') {\n                for (int i : group1) {\n                    estimated_weights[i] *= (1.0 + adjustment);\n                }\n                for (int i : group2) {\n                    estimated_weights[i] *= (1.0 - adjustment);\n                }\n            } else if (result == '<') {\n                for (int i : group1) {\n                    estimated_weights[i] *= (1.0 - adjustment);\n                }\n                for (int i : group2) {\n                    estimated_weights[i] *= (1.0 + adjustment);\n                }\n            }\n            \n            for (int i : group1) compare_count[i]++;\n            for (int i : group2) compare_count[i]++;\n        }\n    }\n    \n    // Normalize estimated weights\n    double min_weight = *min_element(estimated_weights.begin(), estimated_weights.end());\n    for (int i = 0; i < N; i++) {\n        estimated_weights[i] /= min_weight;\n    }\n    \n    // Partition items into D sets\n    vector<int> assignment = partition_items(N, D, estimated_weights);\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <stack>\n#include <algorithm>\n#include <numeric>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> position(n + 1);  // position[v] = (stack_index, position_in_stack)\n    vector<int> stack_top(m, -1); // Top element of each stack\n    \n    // Read input and initialize data structures\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            position[stacks[i][j]] = i;\n        }\n        if (!stacks[i].empty()) {\n            stack_top[i] = stacks[i].back();\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    vector<bool> carried_out(n + 1, false);\n    \n    for (int v = 1; v <= n; v++) {\n        if (carried_out[v]) continue;\n        \n        int stack_idx = position[v];\n        auto& stack = stacks[stack_idx];\n        \n        // Find position of v in its stack\n        int pos_in_stack = -1;\n        for (int i = 0; i < stack.size(); i++) {\n            if (stack[i] == v) {\n                pos_in_stack = i;\n                break;\n            }\n        }\n        \n        // If v is not at the top, move boxes above it\n        while (pos_in_stack < stack.size() - 1) {\n            // Find best destination stack\n            int best_dest = -1;\n            int best_score = -1;\n            \n            for (int dest = 0; dest < m; dest++) {\n                if (dest == stack_idx) continue;\n                \n                int score = 0;\n                \n                // Prefer empty stacks\n                if (stacks[dest].empty()) {\n                    score = 1000;\n                } else {\n                    // Prefer stacks with larger bottom elements\n                    if (stacks[dest][0] > v) {\n                        score = 500;\n                    } else {\n                        // Among stacks that might block, prefer those with fewer boxes\n                        score = 100 - stacks[dest].size();\n                    }\n                }\n                \n                // Prefer stacks whose top is larger than boxes we're moving\n                if (!stacks[dest].empty() && stacks[dest].back() > v) {\n                    score += 200;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_dest = dest;\n                }\n            }\n            \n            // Move boxes above v to best_dest\n            int boxes_to_move = stack.size() - pos_in_stack - 1;\n            if (boxes_to_move > 0) {\n                vector<int> moved_boxes;\n                for (int i = pos_in_stack + 1; i < stack.size(); i++) {\n                    moved_boxes.push_back(stack[i]);\n                    position[stack[i]] = best_dest;\n                }\n                \n                // Update source stack\n                stack.resize(pos_in_stack + 1);\n                stack_top[stack_idx] = stack.back();\n                \n                // Update destination stack\n                stacks[best_dest].insert(stacks[best_dest].end(), \n                                        moved_boxes.begin(), moved_boxes.end());\n                stack_top[best_dest] = stacks[best_dest].back();\n                \n                // Record operation\n                operations.emplace_back(v, best_dest + 1);  // +1 for 1-indexing\n            }\n        }\n        \n        // Now v should be at the top, carry it out\n        if (!stack.empty() && stack.back() == v) {\n            stack.pop_back();\n            carried_out[v] = true;\n            stack_top[stack_idx] = stack.empty() ? -1 : stack.back();\n            operations.emplace_back(v, 0);\n        }\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <utility>\n#include <unordered_set>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    Point operator+(const Point& other) const {\n        return Point(i + other.i, j + other.j);\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<Point> {\n        size_t operator()(const Point& p) const {\n            return static_cast<size_t>(p.i) * 1000 + p.j;\n        }\n    };\n}\n\nclass Solution {\npublic:\n    int N;\n    vector<string> h, v;\n    vector<vector<int>> d;\n    vector<vector<bool>> visited;\n    vector<Point> path;\n    string route;\n    \n    // Directions: R, D, L, U\n    const vector<Point> directions = {Point(0, 1), Point(1, 0), Point(0, -1), Point(-1, 0)};\n    const string dir_chars = \"RDLU\";\n    \n    Solution(int n, const vector<string>& h, const vector<string>& v, const vector<vector<int>>& d)\n        : N(n), h(h), v(v), d(d), visited(n, vector<bool>(n, false)) {\n        // Initialize path with starting point\n        path.emplace_back(0, 0);\n    }\n    \n    bool can_move(const Point& from, const Point& to) const {\n        if (to.i < 0 || to.i >= N || to.j < 0 || to.j >= N) return false;\n        \n        // Check horizontal wall\n        if (from.i == to.i) {\n            int j = min(from.j, to.j);\n            if (v[from.i][j] == '1') return false;\n        }\n        // Check vertical wall\n        else if (from.j == to.j) {\n            int i = min(from.i, to.i);\n            if (h[i][from.j] == '1') return false;\n        }\n        return true;\n    }\n    \n    void dfs(Point p) {\n        visited[p.i][p.j] = true;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            Point next = p + directions[dir];\n            if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                !visited[next.i][next.j] && can_move(p, next)) {\n                path.push_back(next);\n                route += dir_chars[dir];\n                dfs(next);\n                path.push_back(p);\n                route += dir_chars[(dir + 2) % 4];\n            }\n        }\n    }\n    \n    vector<Point> bfs(const Point& start, const Point& end) {\n        vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n        vector<vector<bool>> bfs_visited(N, vector<bool>(N, false));\n        queue<Point> q;\n        \n        q.push(start);\n        bfs_visited[start.i][start.j] = true;\n        \n        while (!q.empty()) {\n            Point current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Point> result;\n                Point p = end;\n                while (p != start) {\n                    result.push_back(p);\n                    p = parent[p.i][p.j];\n                }\n                result.push_back(start);\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (const Point& dir : directions) {\n                Point next = current + dir;\n                if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                    !bfs_visited[next.i][next.j] && can_move(current, next)) {\n                    bfs_visited[next.i][next.j] = true;\n                    parent[next.i][next.j] = current;\n                    q.push(next);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    string get_route_string(const vector<Point>& path) {\n        string result;\n        for (size_t i = 1; i < path.size(); i++) {\n            Point from = path[i-1];\n            Point to = path[i];\n            for (int dir = 0; dir < 4; dir++) {\n                if (from + directions[dir] == to) {\n                    result += dir_chars[dir];\n                    break;\n                }\n            }\n        }\n        return result;\n    }\n    \n    void optimize_route() {\n        // Find cells with high dirt susceptibility\n        vector<pair<int, Point>> high_dirt_cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                high_dirt_cells.emplace_back(d[i][j], Point(i, j));\n            }\n        }\n        sort(high_dirt_cells.rbegin(), high_dirt_cells.rend());\n        \n        // Try to create shortcuts to high dirt cells\n        for (int iter = 0; iter < 100; iter++) {\n            if (route.length() > 90000) break; // Don't exceed the limit\n            \n            // Select a random high dirt cell\n            int idx = rng() % min(10, (int)high_dirt_cells.size());\n            Point target = high_dirt_cells[idx].second;\n            \n            // Find random positions in the current path\n            int pos1 = rng() % (path.size() - 1);\n            int pos2 = rng() % (path.size() - 1);\n            if (pos1 > pos2) swap(pos1, pos2);\n            \n            // Try to create a shortcut from pos1 to target and back to pos2\n            vector<Point> path1 = bfs(path[pos1], target);\n            vector<Point> path2 = bfs(target, path[pos2]);\n            \n            if (!path1.empty() && !path2.empty() && \n                path1.size() + path2.size() < pos2 - pos1) {\n                // Create new path\n                vector<Point> new_path;\n                for (int i = 0; i <= pos1; i++) {\n                    new_path.push_back(path[i]);\n                }\n                for (size_t i = 1; i < path1.size(); i++) {\n                    new_path.push_back(path1[i]);\n                }\n                for (size_t i = 1; i < path2.size(); i++) {\n                    new_path.push_back(path2[i]);\n                }\n                for (size_t i = pos2 + 1; i < path.size(); i++) {\n                    new_path.push_back(path[i]);\n                }\n                \n                // Update path and route\n                path = new_path;\n                route = get_route_string(path);\n            }\n        }\n        \n        // Ensure we return to (0,0)\n        if (path.back() != Point(0, 0)) {\n            vector<Point> return_path = bfs(path.back(), Point(0, 0));\n            for (size_t i = 1; i < return_path.size(); i++) {\n                path.push_back(return_path[i]);\n            }\n            route = get_route_string(path);\n        }\n        \n        // Ensure length constraint\n        if (route.length() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    \n    string solve() {\n        // Generate initial route using DFS\n        dfs(Point(0, 0));\n        \n        // Optimize the route\n        optimize_route();\n        \n        return route;\n    }\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> d(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    Solution solution(N, h, v, d);\n    string route = solution.solve();\n    cout << route << endl;\n    \n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    int s_i, s_j;\n    cin >> s_i >> s_j;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<string> targets(M);\n    set<string> target_set;\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n        target_set.insert(targets[i]);\n    }\n\n    map<string, int> prefix_count;\n    for (const string& t : targets) {\n        for (int len = 1; len <= 4; len++) {\n            string prefix = t.substr(0, len);\n            prefix_count[prefix]++;\n        }\n    }\n\n    vector<pair<int, int>> path;\n    path.emplace_back(s_i, s_j);\n    string last4 = string(1, grid[s_i][s_j]);\n    set<string> covered;\n\n    for (int step = 1; step < 5000; step++) {\n        int best_i = -1, best_j = -1;\n        string best_last4;\n        bool best_covered_one = false;\n        string best_candidate_str;\n        int best_cost_move = 0;\n        double best_score = -1e18;\n\n        int current_i = path.back().first;\n        int current_j = path.back().second;\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int cost_move = abs(current_i - i) + abs(current_j - j) + 1;\n                char c = grid[i][j];\n                string new_last4 = last4 + c;\n                if (new_last4.size() > 4) {\n                    new_last4 = new_last4.substr(new_last4.size() - 4);\n                }\n\n                bool covered_one = false;\n                string candidate_str;\n                if (last4.size() == 4) {\n                    candidate_str = last4 + c;\n                    if (target_set.find(candidate_str) != target_set.end() && covered.find(candidate_str) == covered.end()) {\n                        covered_one = true;\n                    }\n                }\n\n                int potential = 0;\n                if (prefix_count.find(new_last4) != prefix_count.end()) {\n                    potential = prefix_count[new_last4];\n                }\n\n                double score = -cost_move + 1000.0 * (covered_one ? 1 : 0) + 1.0 * potential;\n\n                if (score > best_score) {\n                    best_score = score;\n                    best_i = i;\n                    best_j = j;\n                    best_last4 = new_last4;\n                    best_covered_one = covered_one;\n                    best_candidate_str = candidate_str;\n                    best_cost_move = cost_move;\n                }\n            }\n        }\n\n        path.emplace_back(best_i, best_j);\n        last4 = best_last4;\n\n        if (best_covered_one) {\n            covered.insert(best_candidate_str);\n            for (int len = 1; len <= 4; len++) {\n                string prefix = best_candidate_str.substr(0, len);\n                if (prefix_count.find(prefix) != prefix_count.end()) {\n                    prefix_count[prefix]--;\n                }\n            }\n        }\n\n        if (covered.size() == M) {\n            break;\n        }\n    }\n\n    for (const auto& p : path) {\n        cout << p.first << \" \" << p.second << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        return tie(i, j) < tie(other.i, other.j);\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct OilField {\n    vector<Point> cells;\n    int size;\n};\n\nstruct GridInfo {\n    int N, M;\n    double epsilon;\n    vector<OilField> oil_fields;\n    vector<vector<int>> drilled_values;\n    vector<vector<double>> estimated_values;\n    set<Point> oil_squares;\n    \n    GridInfo(int N, int M, double epsilon) : N(N), M(M), epsilon(epsilon) {\n        drilled_values.assign(N, vector<int>(N, -1));\n        estimated_values.assign(N, vector<double>(N, 0.0));\n    }\n};\n\nvoid read_input(GridInfo& grid) {\n    cin >> grid.N >> grid.M >> grid.epsilon;\n    grid.oil_fields.resize(grid.M);\n    \n    for (int k = 0; k < grid.M; ++k) {\n        int d;\n        cin >> d;\n        grid.oil_fields[k].size = d;\n        grid.oil_fields[k].cells.resize(d);\n        for (int i = 0; i < d; ++i) {\n            cin >> grid.oil_fields[k].cells[i].i >> grid.oil_fields[k].cells[i].j;\n        }\n    }\n}\n\nint drill(GridInfo& grid, int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    grid.drilled_values[i][j] = value;\n    grid.estimated_values[i][j] = value;\n    if (value > 0) {\n        grid.oil_squares.insert(Point(i, j));\n    }\n    return value;\n}\n\nint divine(GridInfo& grid, const vector<Point>& squares) {\n    cout << \"q \" << squares.size();\n    for (const auto& p : squares) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    return value;\n}\n\nbool submit_answer(GridInfo& grid, const set<Point>& answer) {\n    cout << \"a \" << answer.size();\n    for (const auto& p : answer) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nvector<Point> get_region_points(int i1, int j1, int i2, int j2, int N) {\n    vector<Point> points;\n    for (int i = i1; i <= i2; ++i) {\n        for (int j = j1; j <= j2; ++j) {\n            if (i >= 0 && i < N && j >= 0 && j < N) {\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    return points;\n}\n\nvoid explore_grid(GridInfo& grid, int max_operations) {\n    int operations_used = 0;\n    \n    if (operations_used < max_operations) {\n        auto all_points = get_region_points(0, 0, grid.N-1, grid.N-1, grid.N);\n        if (all_points.size() >= 2) {\n            int total_oil_estimate = divine(grid, all_points);\n            operations_used++;\n            \n            double avg_oil = static_cast<double>(total_oil_estimate) / (grid.N * grid.N);\n            for (int i = 0; i < grid.N; ++i) {\n                for (int j = 0; j < grid.N; ++j) {\n                    grid.estimated_values[i][j] = avg_oil;\n                }\n            }\n        }\n    }\n    \n    queue<tuple<int, int, int, int>> regions;\n    regions.push({0, 0, grid.N-1, grid.N-1});\n    \n    while (!regions.empty() && operations_used < max_operations) {\n        auto [i1, j1, i2, j2] = regions.front();\n        regions.pop();\n        \n        auto points = get_region_points(i1, j1, i2, j2, grid.N);\n        if (points.size() < 2) continue;\n        \n        int oil_estimate = divine(grid, points);\n        operations_used++;\n        \n        if (oil_estimate > 0) {\n            int mid_i = (i1 + i2) / 2;\n            int mid_j = (j1 + j2) / 2;\n            \n            if (i2 - i1 > 1 || j2 - j1 > 1) {\n                regions.push({i1, j1, mid_i, mid_j});\n                regions.push({i1, mid_j + 1, mid_i, j2});\n                regions.push({mid_i + 1, j1, i2, mid_j});\n                regions.push({mid_i + 1, mid_j + 1, i2, j2});\n            } else {\n                for (const auto& p : points) {\n                    if (operations_used < max_operations) {\n                        drill(grid, p.i, p.j);\n                        operations_used++;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (operations_used < max_operations) {\n        vector<pair<double, Point>> candidates;\n        for (int i = 0; i < grid.N; ++i) {\n            for (int j = 0; j < grid.N; ++j) {\n                if (grid.drilled_values[i][j] == -1) {\n                    candidates.emplace_back(grid.estimated_values[i][j], Point(i, j));\n                }\n            }\n        }\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        for (const auto& [_, p] : candidates) {\n            if (operations_used >= max_operations) break;\n            drill(grid, p.i, p.j);\n            operations_used++;\n        }\n    }\n}\n\nvoid infer_oil_fields(GridInfo& grid) {\n    for (const auto& field : grid.oil_fields) {\n        vector<pair<int, Point>> possible_positions;\n        \n        for (int di = 0; di <= grid.N - field.cells.back().i; ++di) {\n            for (int dj = 0; dj <= grid.N - field.cells.back().j; ++dj) {\n                int score = 0;\n                for (const auto& cell : field.cells) {\n                    int i = di + cell.i;\n                    int j = dj + cell.j;\n                    if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                        if (grid.drilled_values[i][j] > 0) {\n                            score += grid.drilled_values[i][j];\n                        } else if (grid.drilled_values[i][j] == 0) {\n                            score = -1;\n                            break;\n                        }\n                    }\n                }\n                if (score > 0) {\n                    possible_positions.emplace_back(score, Point(di, dj));\n                }\n            }\n        }\n        \n        sort(possible_positions.rbegin(), possible_positions.rend());\n        \n        for (int idx = 0; idx < min(3, (int)possible_positions.size()); ++idx) {\n            const auto& [_, pos] = possible_positions[idx];\n            double weight = idx == 0 ? 1.0 : 0.5;\n            \n            for (const auto& cell : field.cells) {\n                int i = pos.i + cell.i;\n                int j = pos.j + cell.j;\n                if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                    if (grid.drilled_values[i][j] == -1) {\n                        grid.estimated_values[i][j] += weight;\n                    }\n                }\n            }\n        }\n    }\n}\n\nset<Point> determine_answer(GridInfo& grid) {\n    set<Point> answer;\n    \n    answer.insert(grid.oil_squares.begin(), grid.oil_squares.end());\n    \n    for (int i = 0; i < grid.N; ++i) {\n        for (int j = 0; j < grid.N; ++j) {\n            if (grid.drilled_values[i][j] == -1 && grid.estimated_values[i][j] > 0.5) {\n                answer.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return answer;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double epsilon;\n    cin >> N >> M >> epsilon;\n    \n    GridInfo grid(N, M, epsilon);\n    read_input(grid);\n    \n    int max_operations = 2 * N * N;\n    \n    explore_grid(grid, max_operations / 2);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations * 3 / 4);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations);\n    \n    set<Point> answer = determine_answer(grid);\n    \n    bool correct = submit_answer(grid, answer);\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <cassert>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    \n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int i0, int j0, int i1, int j1) : i0(i0), j0(j0), i1(i1), j1(j1) {}\n    \n    int area() const {\n        return (i1 - i0) * (j1 - j0);\n    }\n    \n    bool operator==(const Rectangle& other) const {\n        return i0 == other.i0 && j0 == other.j0 && i1 == other.i1 && j1 == other.j1;\n    }\n};\n\nstruct DayLayout {\n    vector<Rectangle> rectangles;\n    vector<vector<int>> horizontal_partitions;  // H_{d,i,j}\n    vector<vector<int>> vertical_partitions;    // V_{d,i,j}\n    \n    DayLayout(int W) {\n        horizontal_partitions.resize(W-1, vector<int>(W, 0));\n        vertical_partitions.resize(W, vector<int>(W-1, 0));\n    }\n    \n    void update_partitions(int W) {\n        // Reset partitions\n        for (auto& row : horizontal_partitions) fill(row.begin(), row.end(), 0);\n        for (auto& row : vertical_partitions) fill(row.begin(), row.end(), 0);\n        \n        // Set partitions based on rectangles\n        for (const auto& rect : rectangles) {\n            // Horizontal partitions (top and bottom edges)\n            if (rect.i0 > 0) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i0-1][j] = 1;\n                }\n            }\n            if (rect.i1 < W) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i1-1][j] = 1;\n                }\n            }\n            \n            // Vertical partitions (left and right edges)\n            if (rect.j0 > 0) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j0-1] = 1;\n                }\n            }\n            if (rect.j1 < W) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j1-1] = 1;\n                }\n            }\n        }\n    }\n};\n\nclass EventHallOptimizer {\nprivate:\n    int W, D, N;\n    vector<vector<int>> desired_areas;\n    vector<DayLayout> layouts;\n    mt19937 rng;\n    \npublic:\n    EventHallOptimizer(int W, int D, int N, const vector<vector<int>>& areas)\n        : W(W), D(D), N(N), desired_areas(areas) {\n        // Initialize random number generator\n        rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n        \n        layouts.reserve(D);\n        for (int d = 0; d < D; ++d) {\n            layouts.emplace_back(W);\n        }\n    }\n    \n    void solve() {\n        // Generate initial layout for day 0\n        generate_initial_layout(0);\n        layouts[0].update_partitions(W);\n        \n        // Generate layouts for subsequent days\n        for (int d = 1; d < D; ++d) {\n            // Start with previous day's layout as base\n            layouts[d] = layouts[d-1];\n            \n            // Optimize layout for day d\n            optimize_layout(d);\n            layouts[d].update_partitions(W);\n        }\n    }\n    \n    void generate_initial_layout(int day) {\n        vector<pair<int, int>> area_indices;\n        for (int k = 0; k < N; ++k) {\n            area_indices.emplace_back(desired_areas[day][k], k);\n        }\n        sort(area_indices.begin(), area_indices.end(), greater<pair<int, int>>());\n        \n        vector<Rectangle> rects(N);\n        vector<bool> used(N, false);\n        \n        // Use a space-filling curve approach\n        int current_i = 0, current_j = 0;\n        \n        for (const auto& [area, idx] : area_indices) {\n            // Find best fitting rectangle\n            Rectangle best_rect;\n            int best_score = -1;\n            \n            // Try different starting positions and sizes\n            for (int start_i = current_i; start_i < W - 1; ++start_i) {\n                for (int start_j = (start_i == current_i ? current_j : 0); start_j < W - 1; ++start_j) {\n                    // Try different aspect ratios\n                    for (int aspect = 1; aspect <= 4; ++aspect) {\n                        int height = sqrt(area * aspect);\n                        int width = area / height;\n                        if (width * height < area) width++;\n                        \n                        // Ensure rectangle fits\n                        if (start_i + height > W || start_j + width > W) continue;\n                        \n                        Rectangle rect(start_i, start_j, start_i + height, start_j + width);\n                        \n                        // Check for overlaps\n                        bool overlap = false;\n                        for (int k = 0; k < N; ++k) {\n                            if (used[k] && rectangles_overlap(rect, rects[k])) {\n                                overlap = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!overlap) {\n                            int score = rect.area();\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (best_score == -1) {\n                // Fallback: place at current position with minimum size\n                int side = ceil(sqrt(area));\n                best_rect = Rectangle(current_i, current_j, \n                                    min(current_i + side, W), \n                                    min(current_j + side, W));\n            }\n            \n            rects[idx] = best_rect;\n            used[idx] = true;\n            \n            // Update current position\n            current_j = best_rect.j1;\n            if (current_j >= W - 1) {\n                current_j = 0;\n                current_i = best_rect.i1;\n            }\n        }\n        \n        layouts[day].rectangles = rects;\n    }\n    \n    void optimize_layout(int day) {\n        const double initial_temp = 1000.0;\n        const double cooling_rate = 0.95;\n        const int iterations = 1000;\n        \n        double temp = initial_temp;\n        vector<Rectangle> current_rects = layouts[day].rectangles;\n        int current_cost = calculate_total_cost(day, current_rects);\n        \n        for (int iter = 0; iter < iterations; ++iter) {\n            // Generate neighbor solution\n            vector<Rectangle> neighbor_rects = current_rects;\n            apply_random_move(day, neighbor_rects);\n            \n            // Calculate cost\n            int neighbor_cost = calculate_total_cost(day, neighbor_rects);\n            \n            // Accept or reject\n            int delta = neighbor_cost - current_cost;\n            if (delta < 0 || exp(-delta / temp) > generate_random_double()) {\n                current_rects = neighbor_rects;\n                current_cost = neighbor_cost;\n            }\n            \n            // Cool down\n            temp *= cooling_rate;\n        }\n        \n        layouts[day].rectangles = current_rects;\n    }\n    \n    void apply_random_move(int day, vector<Rectangle>& rects) {\n        uniform_int_distribution<int> move_dist(0, 2);\n        int move_type = move_dist(rng);\n        \n        switch (move_type) {\n            case 0: // Resize rectangle\n                resize_random_rectangle(rects);\n                break;\n            case 1: // Move rectangle\n                move_random_rectangle(rects);\n                break;\n            case 2: // Swap two rectangles\n                swap_random_rectangles(rects);\n                break;\n        }\n        \n        // Ensure no overlaps\n        fix_overlaps(rects);\n    }\n    \n    void resize_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-10, 10);\n        int di0 = delta_dist(rng);\n        int dj0 = delta_dist(rng);\n        int di1 = delta_dist(rng);\n        int dj1 = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        rect.i0 = max(0, min(W-1, rect.i0 + di0));\n        rect.j0 = max(0, min(W-1, rect.j0 + dj0));\n        rect.i1 = max(rect.i0+1, min(W, rect.i1 + di1));\n        rect.j1 = max(rect.j0+1, min(W, rect.j1 + dj1));\n    }\n    \n    void move_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-5, 5);\n        int di = delta_dist(rng);\n        int dj = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        int height = rect.i1 - rect.i0;\n        int width = rect.j1 - rect.j0;\n        \n        rect.i0 = max(0, min(W - height, rect.i0 + di));\n        rect.j0 = max(0, min(W - width, rect.j0 + dj));\n        rect.i1 = rect.i0 + height;\n        rect.j1 = rect.j0 + width;\n    }\n    \n    void swap_random_rectangles(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx1 = rect_dist(rng);\n        int idx2 = rect_dist(rng);\n        \n        if (idx1 != idx2) {\n            swap(rects[idx1], rects[idx2]);\n        }\n    }\n    \n    void fix_overlaps(vector<Rectangle>& rects) {\n        // Simple overlap resolution: shrink overlapping rectangles\n        for (int i = 0; i < N; ++i) {\n            for (int j = i+1; j < N; ++j) {\n                if (rectangles_overlap(rects[i], rects[j])) {\n                    // Shrink the smaller rectangle\n                    if (rects[i].area() < rects[j].area()) {\n                        shrink_rectangle(rects[i], rects[j]);\n                    } else {\n                        shrink_rectangle(rects[j], rects[i]);\n                    }\n                }\n            }\n        }\n    }\n    \n    void shrink_rectangle(Rectangle& to_shrink, const Rectangle& other) {\n        // Find intersection and shrink accordingly\n        int left = max(to_shrink.j0, other.j0);\n        int right = min(to_shrink.j1, other.j1);\n        int top = max(to_shrink.i0, other.i0);\n        int bottom = min(to_shrink.i1, other.i1);\n        \n        if (left < right && top < bottom) {\n            // Calculate overlap sizes\n            int overlap_width = right - left;\n            int overlap_height = bottom - top;\n            \n            // Shrink in the direction with smaller overlap\n            if (overlap_width < overlap_height) {\n                if (other.j0 <= to_shrink.j0) {\n                    to_shrink.j0 = right;\n                } else {\n                    to_shrink.j1 = left;\n                }\n            } else {\n                if (other.i0 <= to_shrink.i0) {\n                    to_shrink.i0 = bottom;\n                } else {\n                    to_shrink.i1 = top;\n                }\n            }\n        }\n    }\n    \n    int calculate_total_cost(int day, const vector<Rectangle>& rects) {\n        int cost = 0;\n        \n        // Area penalty cost\n        for (int k = 0; k < N; ++k) {\n            int actual_area = rects[k].area();\n            if (actual_area < desired_areas[day][k]) {\n                cost += 100 * (desired_areas[day][k] - actual_area);\n            }\n        }\n        \n        // Partition change cost (except for day 0)\n        if (day > 0) {\n            // Create temporary layout to calculate partitions\n            DayLayout temp_layout(W);\n            temp_layout.rectangles = rects;\n            temp_layout.update_partitions(W);\n            \n            // Calculate partition differences\n            for (int i = 0; i < W-1; ++i) {\n                for (int j = 0; j < W; ++j) {\n                    if (layouts[day-1].horizontal_partitions[i][j] != temp_layout.horizontal_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n            \n            for (int i = 0; i < W; ++i) {\n                for (int j = 0; j < W-1; ++j) {\n                    if (layouts[day-1].vertical_partitions[i][j] != temp_layout.vertical_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n        }\n        \n        return cost;\n    }\n    \n    bool rectangles_overlap(const Rectangle& r1, const Rectangle& r2) {\n        return !(r1.i1 <= r2.i0 || r2.i1 <= r1.i0 || r1.j1 <= r2.j0 || r2.j1 <= r1.j0);\n    }\n    \n    double generate_random_double() {\n        return uniform_real_distribution<double>(0.0, 1.0)(rng);\n    }\n    \n    void output_solution() {\n        for (int d = 0; d < D; ++d) {\n            for (int k = 0; k < N; ++k) {\n                const auto& rect = layouts[d].rectangles[k];\n                cout << rect.i0 << \" \" << rect.j0 << \" \" << rect.i1 << \" \" << rect.j1 << \"\\n\";\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> desired_areas(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> desired_areas[d][k];\n        }\n    }\n    \n    EventHallOptimizer optimizer(W, D, N, desired_areas);\n    optimizer.solve();\n    optimizer.output_solution();\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<pair<int, pair<int, int>>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_improvement = -1;\n        int best_stamp = -1;\n        int best_p = -1;\n        int best_q = -1;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    int improvement = 0;\n                    \n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int v = board[p + i][q + j];\n                            int x = stamps[m][i][j];\n                            \n                            // Calculate the improvement\n                            int current_mod = v % MOD;\n                            int new_mod = (v + x) % MOD;\n                            int cell_improvement = new_mod - current_mod;\n                            if (cell_improvement < 0) cell_improvement += MOD;\n                            \n                            improvement += cell_improvement;\n                        }\n                    }\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_stamp = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_improvement <= 0) {\n            // No improvement, stop early\n            break;\n        }\n        \n        operations.push_back({best_stamp, {best_p, best_q}});\n        \n        // Apply the stamp\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_stamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << endl;\n    for (auto &op : operations) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <set>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 5;\n\nchar move_towards(int i0, int j0, int i1, int j1, int grid[N][N], int crane_pos[N][2], int crane_id, bool is_large, int crane_carrying[N]) {\n    vector<char> dirs = {'U', 'D', 'L', 'R'};\n    vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    int current_dist = abs(i0 - i1) + abs(j0 - j1);\n    vector<char> good_moves;\n    vector<char> ok_moves;\n\n    for (int idx = 0; idx < 4; idx++) {\n        int ni = i0 + moves[idx].first;\n        int nj = j0 + moves[idx].second;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n            continue;\n        }\n\n        if (crane_carrying[crane_id] != -1 && !is_large) {\n            if (grid[ni][nj] != -1) {\n                continue;\n            }\n        }\n\n        int new_dist = abs(ni - i1) + abs(nj - j1);\n        if (new_dist < current_dist) {\n            good_moves.push_back(dirs[idx]);\n        } else if (new_dist == current_dist) {\n            ok_moves.push_back(dirs[idx]);\n        }\n    }\n\n    if (!good_moves.empty()) {\n        return good_moves[0];\n    } else if (!ok_moves.empty()) {\n        return ok_moves[0];\n    } else {\n        return '.';\n    }\n}\n\nint main() {\n    int n_val;\n    cin >> n_val;\n    int A[N][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    int grid[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n\n    int crane_pos[N][2];\n    for (int i = 0; i < N; i++) {\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n    }\n\n    int crane_carrying[N];\n    for (int i = 0; i < N; i++) {\n        crane_carrying[i] = -1;\n    }\n\n    int next_container_index[N] = {0};\n    int next_dispatch[N];\n    for (int i = 0; i < N; i++) {\n        next_dispatch[i] = 5 * i;\n    }\n\n    bool bombed[N] = {false};\n    vector<string> crane_actions(N);\n\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) {\n            if (next_container_index[i] < N) {\n                bool crane_holding_at_gate = false;\n                for (int c = 0; c < N; c++) {\n                    if (!bombed[c] && crane_pos[c][0] == i && crane_pos[c][1] == 0 && crane_carrying[c] != -1) {\n                        crane_holding_at_gate = true;\n                        break;\n                    }\n                }\n                if (grid[i][0] == -1 && !crane_holding_at_gate) {\n                    grid[i][0] = A[i][next_container_index[i]];\n                    next_container_index[i]++;\n                }\n            }\n        }\n\n        vector<char> actions(N, '.');\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                actions[c] = '.';\n                continue;\n            }\n\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            int carrying = crane_carrying[c];\n\n            if (carrying != -1) {\n                int container_id = carrying;\n                int target_gate = container_id / N;\n\n                if (container_id == next_dispatch[target_gate]) {\n                    if (i0 == target_gate && j0 == N-1) {\n                        actions[c] = 'Q';\n                    } else {\n                        actions[c] = move_towards(i0, j0, target_gate, N-1, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (j0 >= 1 && j0 <= 3 && grid[i0][j0] == -1) {\n                        actions[c] = 'Q';\n                    } else {\n                        vector<pair<int, int>> candidates;\n                        for (int i = 0; i < N; i++) {\n                            for (int j = 1; j <= 3; j++) {\n                                if (grid[i][j] == -1) {\n                                    candidates.push_back({i, j});\n                                }\n                            }\n                        }\n                        if (!candidates.empty()) {\n                            auto best = candidates[0];\n                            int best_dist = abs(i0 - best.first) + abs(j0 - best.second);\n                            for (auto cand : candidates) {\n                                int dist = abs(i0 - cand.first) + abs(j0 - cand.second);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best = cand;\n                                }\n                            }\n                            actions[c] = move_towards(i0, j0, best.first, best.second, grid, crane_pos, c, (c==0), crane_carrying);\n                        } else {\n                            actions[c] = '.';\n                        }\n                    }\n                }\n            } else {\n                vector<tuple<int, int, int>> containers;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int cid = grid[i][j];\n                            if (cid / N == c) {\n                                containers.push_back(make_tuple(i, j, cid));\n                            }\n                        }\n                    }\n                }\n                if (!containers.empty()) {\n                    auto best = containers[0];\n                    int best_dist = abs(i0 - get<0>(best)) + abs(j0 - get<1>(best));\n                    for (auto cont : containers) {\n                        int dist = abs(i0 - get<0>(cont)) + abs(j0 - get<1>(cont));\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best = cont;\n                        }\n                    }\n                    int ti = get<0>(best), tj = get<1>(best);\n                    if (i0 == ti && j0 == tj) {\n                        actions[c] = 'P';\n                    } else {\n                        actions[c] = move_towards(i0, j0, ti, tj, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (i0 == c && j0 == 0) {\n                        actions[c] = '.';\n                    } else {\n                        actions[c] = move_towards(i0, j0, c, 0, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> next_pos(N);\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'U') {\n                next_pos[c] = {i0-1, j0};\n            } else if (act == 'D') {\n                next_pos[c] = {i0+1, j0};\n            } else if (act == 'L') {\n                next_pos[c] = {i0, j0-1};\n            } else if (act == 'R') {\n                next_pos[c] = {i0, j0+1};\n            } else {\n                next_pos[c] = {i0, j0};\n            }\n        }\n\n        set<int> involved;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == make_pair(crane_pos[j][0], crane_pos[j][1]) && \n                    next_pos[j] == make_pair(crane_pos[i][0], crane_pos[i][1])) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n\n        for (int c : involved) {\n            if (!bombed[c]) {\n                actions[c] = '.';\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'P') {\n                if (crane_carrying[c] == -1 && grid[i0][j0] != -1) {\n                    crane_carrying[c] = grid[i0][j0];\n                    grid[i0][j0] = -1;\n                }\n            } else if (act == 'Q') {\n                if (crane_carrying[c] != -1 && grid[i0][j0] == -1) {\n                    grid[i0][j0] = crane_carrying[c];\n                    crane_carrying[c] = -1;\n                }\n            } else if (act == 'B') {\n                if (crane_carrying[c] == -1) {\n                    bombed[c] = true;\n                }\n            } else if (act == 'U' || act == 'D' || act == 'L' || act == 'R') {\n                crane_pos[c][0] = next_pos[c].first;\n                crane_pos[c][1] = next_pos[c].second;\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container_id = grid[i][N-1];\n                grid[i][N-1] = -1;\n                next_dispatch[i] = container_id + 1;\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            crane_actions[c] += actions[c];\n        }\n\n        int total_dispatched = 0;\n        for (int i = 0; i < N; i++) {\n            total_dispatched += (next_dispatch[i] - 5*i);\n        }\n        if (total_dispatched == N*N) {\n            break;\n        }\n    }\n\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        if (crane_actions[i].size() > max_len) {\n            max_len = crane_actions[i].size();\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        while (crane_actions[i].size() < max_len) {\n            crane_actions[i] += '.';\n        }\n        cout << crane_actions[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <tuple>\n#include <string>\nusing namespace std;\n\nvector<string> get_manhattan_path(pair<int, int> start, pair<int, int> end) {\n    vector<string> path;\n    int x1 = start.first, y1 = start.second;\n    int x2 = end.first, y2 = end.second;\n    while (x1 < x2) {\n        path.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        path.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        path.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        path.push_back(\"L\");\n        y1--;\n    }\n    return path;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    long long base = 0;\n    vector<tuple<int, int, int>> sources;\n    vector<tuple<int, int, int>> sinks;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                sources.emplace_back(i, j, grid[i][j]);\n                base += grid[i][j];\n            } else if (grid[i][j] < 0) {\n                sinks.emplace_back(i, j, -grid[i][j]);\n                base += -grid[i][j];\n            }\n        }\n    }\n\n    long long total_soil = base / 2;\n\n    if (total_soil == 0) {\n        cout << endl;\n        return 0;\n    }\n\n    pair<int, int> best_hub;\n    long long best_cost = LLONG_MAX;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pair<int, int> hub = {i, j};\n\n            vector<tuple<int, int, int>> sorted_sources = sources;\n            sort(sorted_sources.begin(), sorted_sources.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            vector<tuple<int, int, int>> sorted_sinks = sinks;\n            sort(sorted_sinks.begin(), sorted_sinks.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            long long cost_transport = 0;\n            pair<int, int> current = {0, 0};\n            long long load = 0;\n\n            if (!sorted_sources.empty()) {\n                auto first = sorted_sources[0];\n                int d = abs(current.first - get<0>(first)) + abs(current.second - get<1>(first));\n                cost_transport += d * 100;\n                current = {get<0>(first), get<1>(first)};\n                load += get<2>(first);\n\n                for (int idx = 1; idx < sorted_sources.size(); idx++) {\n                    auto src = sorted_sources[idx];\n                    d = abs(current.first - get<0>(src)) + abs(current.second - get<1>(src));\n                    cost_transport += d * (100 + load);\n                    current = {get<0>(src), get<1>(src)};\n                    load += get<2>(src);\n                }\n\n                d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * (100 + load);\n            } else {\n                int d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * 100;\n            }\n\n            current = hub;\n            load = total_soil;\n\n            for (int idx = 0; idx < sorted_sinks.size(); idx++) {\n                auto sink = sorted_sinks[idx];\n                int d = abs(current.first - get<0>(sink)) + abs(current.second - get<1>(sink));\n                cost_transport += d * (100 + load);\n                current = {get<0>(sink), get<1>(sink)};\n                load -= get<2>(sink);\n            }\n\n            long long total_cost = base + cost_transport;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                best_hub = hub;\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> sorted_sources = sources;\n    sort(sorted_sources.begin(), sorted_sources.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<tuple<int, int, int>> sorted_sinks = sinks;\n    sort(sorted_sinks.begin(), sorted_sinks.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<string> operations;\n    pair<int, int> current_pos = {0, 0};\n\n    if (!sorted_sources.empty()) {\n        auto first = sorted_sources[0];\n        pair<int, int> first_pos = {get<0>(first), get<1>(first)};\n        vector<string> path = get_manhattan_path(current_pos, first_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"+\" + to_string(get<2>(first)));\n        current_pos = first_pos;\n\n        for (int idx = 1; idx < sorted_sources.size(); idx++) {\n            auto src = sorted_sources[idx];\n            pair<int, int> src_pos = {get<0>(src), get<1>(src)};\n            vector<string> path = get_manhattan_path(current_pos, src_pos);\n            operations.insert(operations.end(), path.begin(), path.end());\n            operations.push_back(\"+\" + to_string(get<2>(src)));\n            current_pos = src_pos;\n        }\n\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    } else {\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    }\n\n    for (auto sink : sorted_sinks) {\n        pair<int, int> sink_pos = {get<0>(sink), get<1>(sink)};\n        vector<string> path = get_manhattan_path(current_pos, sink_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"-\" + to_string(get<2>(sink)));\n        current_pos = sink_pos;\n    }\n\n    for (const string& op : operations) {\n        cout << op << endl;\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    // For each turn\n    for (int t = 0; t < T; t++) {\n        // Calculate scores for each seed\n        vector<pair<double, int>> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            // Calculate total value\n            int total_value = accumulate(X[i].begin(), X[i].end(), 0);\n            \n            // Find maximum value in any single criterion\n            int max_criterion = *max_element(X[i].begin(), X[i].end());\n            \n            // Calculate sum of top 5 criteria\n            vector<int> sorted_criteria = X[i];\n            sort(sorted_criteria.rbegin(), sorted_criteria.rend());\n            int top5_sum = accumulate(sorted_criteria.begin(), sorted_criteria.begin() + min(5, M), 0);\n            \n            // Combined score with weights\n            double score = 0.5 * total_value + 0.3 * max_criterion + 0.2 * top5_sum;\n            seed_scores[i] = {score, i};\n        }\n        \n        // Sort seeds by score in descending order\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Select top 36 seeds\n        vector<int> selected_seeds;\n        for (int i = 0; i < N * N; i++) {\n            selected_seeds.push_back(seed_scores[i].second);\n        }\n        \n        // Create grid arrangement\n        vector<vector<int>> A(N, vector<int>(N, 0));\n        \n        // Strategy: Place seeds with complementary strengths adjacent to each other\n        // Sort selected seeds by their strongest criterion\n        vector<pair<int, int>> seeds_by_max_criterion;\n        for (int seed : selected_seeds) {\n            int max_val = *max_element(X[seed].begin(), X[seed].end());\n            seeds_by_max_criterion.push_back({max_val, seed});\n        }\n        \n        // Sort by maximum criterion value\n        sort(seeds_by_max_criterion.rbegin(), seeds_by_max_criterion.rend());\n        \n        // Place in a checkerboard pattern, alternating high and medium seeds\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if ((i + j) % 2 == 0) {\n                    // Place a seed with high maximum criterion\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                } else {\n                    // Place a seed with balanced criteria\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                }\n            }\n        }\n        \n        // Output the arrangement\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds for next turn\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> X[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <climits>\nusing namespace std;\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s_grid(N);\n    vector<string> t_grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> s_grid[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t_grid[i];\n    }\n    \n    set<pair<int, int>> S;\n    set<pair<int, int>> T;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0') {\n                S.insert({i, j});\n            }\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0') {\n                T.insert({i, j});\n            }\n        }\n    }\n    \n    int V_prime = 2;\n    cout << V_prime << endl;\n    cout << \"0 1\" << endl;\n    int rx0 = (N-1)/2;\n    int ry0 = (N-1)/2;\n    cout << rx0 << \" \" << ry0 << endl;\n    \n    const vector<int> dx = {0, 1, 0, -1};\n    const vector<int> dy = {1, 0, -1, 0};\n    const vector<char> move_dir = {'R', 'D', 'L', 'U'};\n    \n    int rx = rx0;\n    int ry = ry0;\n    int dir = 0;\n    \n    auto manhattan_move = [&](int x1, int y1, int x2, int y2) -> vector<char> {\n        vector<char> moves;\n        while (x1 < x2) {\n            moves.push_back('D');\n            x1++;\n        }\n        while (x1 > x2) {\n            moves.push_back('U');\n            x1--;\n        }\n        while (y1 < y2) {\n            moves.push_back('R');\n            y1++;\n        }\n        while (y1 > y2) {\n            moves.push_back('L');\n            y1--;\n        }\n        return moves;\n    };\n    \n    while (!S.empty()) {\n        pair<int, int> best_pos;\n        pair<int, int> best_adj;\n        int best_dist = INT_MAX;\n        \n        for (const auto& pos : S) {\n            int a = pos.first;\n            int b = pos.second;\n            for (int d = 0; d < 4; d++) {\n                int x = a + dx[d];\n                int y = b + dy[d];\n                if (x < 0 || x >= N || y < 0 || y >= N) continue;\n                int dist = abs(rx - x) + abs(ry - y);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pos = {a, b};\n                    best_adj = {x, y};\n                }\n            }\n        }\n        \n        int a = best_pos.first;\n        int b = best_pos.second;\n        int x = best_adj.first;\n        int y = best_adj.second;\n        \n        vector<char> path = manhattan_move(rx, ry, x, y);\n        for (char move : path) {\n            string command = string(V_prime, '.');\n            command[0] = move;\n            cout << command << endl;\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        int desired_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (dx[d] == a - x && dy[d] == b - y) {\n                desired_dir = d;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd;\n            if (diff == 1 || diff == 3) {\n                rot_cmd = 'R';\n                dir = (dir + 1) % 4;\n            } else {\n                rot_cmd = 'L';\n                dir = (dir + 3) % 4;\n            }\n            string command = string(V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << endl;\n        }\n        \n        string grab_command = string(V_prime, '.');\n        grab_command[V_prime] = 'P';\n        cout << grab_command << endl;\n        S.erase({a, b});\n        \n        best_dist = INT_MAX;\n        pair<int, int> best_target;\n        pair<int, int> best_adj_target;\n        for (const auto& target : T) {\n            int c = target.first;\n            int d = target.second;\n            for (int dir_adj = 0; dir_adj < 4; dir_adj++) {\n                int x_target = c + dx[dir_adj];\n                int y_target = d + dy[dir_adj];\n                if (x_target < 0 || x_target >= N || y_target < 0 || y_target >= N) continue;\n                int dist = abs(rx - x_target) + abs(ry - y_target);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_target = {c, d};\n                    best_adj_target = {x_target, y_target};\n                }\n            }\n        }\n        \n        int c = best_target.first;\n        int d = best_target.second;\n        int x_target = best_adj_target.first;\n        int y_target = best_adj_target.second;\n        \n        path = manhattan_move(rx, ry, x_target, y_target);\n        for (char move : path) {\n            string command = string(V_prime, '.');\n            command[0] = move;\n            cout << command << endl;\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        desired_dir = -1;\n        for (int dir_val = 0; dir_val < 4; dir_val++) {\n            if (dx[dir_val] == c - x_target && dy[dir_val] == d - y_target) {\n                desired_dir = dir_val;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd;\n            if (diff == 1 || diff == 3) {\n                rot_cmd = 'R';\n                dir = (dir + 1) % 4;\n            } else {\n                rot_cmd = 'L';\n                dir = (dir + 3) % 4;\n            }\n            string command = string(V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << endl;\n        }\n        \n        string release_command = string(V_prime, '.');\n        release_command[V_prime] = 'P';\n        cout << release_command << endl;\n        T.erase({c, d});\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <chrono>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Point {\n    int x, y;\n    \n    bool operator<(const Point& other) const {\n        return tie(x, y) < tie(other.x, other.y);\n    }\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Polygon {\n    vector<Point> vertices;\n    \n    void add_vertex(const Point& p) {\n        vertices.push_back(p);\n    }\n    \n    double perimeter() const {\n        double perim = 0;\n        for (int i = 0; i < vertices.size(); ++i) {\n            int j = (i + 1) % vertices.size();\n            perim += abs(vertices[i].x - vertices[j].x) + abs(vertices[i].y - vertices[j].y);\n        }\n        return perim;\n    }\n    \n    // Point-in-polygon test for axis-aligned polygon\n    bool contains(const Point& p) const {\n        int n = vertices.size();\n        bool inside = false;\n        \n        for (int i = 0, j = n - 1; i < n; j = i++) {\n            const Point& vi = vertices[i];\n            const Point& vj = vertices[j];\n            \n            if ((vi.y == vj.y) && (p.y == vi.y) && \n                (p.x >= min(vi.x, vj.x)) && (p.x <= max(vi.x, vj.x))) {\n                // Point is on a horizontal edge\n                return true;\n            }\n            \n            if ((vi.x == vj.x) && (p.x == vi.x) && \n                (p.y >= min(vi.y, vj.y)) && (p.y <= max(vi.y, vj.y))) {\n                // Point is on a vertical edge\n                return true;\n            }\n            \n            if (((vi.y > p.y) != (vj.y > p.y)) &&\n                (p.x < (vj.x - vi.x) * (p.y - vi.y) / (vj.y - vi.y) + vi.x)) {\n                inside = !inside;\n            }\n        }\n        \n        return inside;\n    }\n};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<Point> mackerels(N);\n    vector<Point> sardines(N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].x >> mackerels[i].y;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].x >> sardines[i].y;\n    }\n    \n    // Find clusters of mackerels\n    const int cluster_size = 50; // Number of mackerels per cluster\n    vector<vector<Point>> mackerel_clusters;\n    \n    // Simple clustering: group nearby mackerels\n    vector<bool> used(N, false);\n    for (int i = 0; i < N; ++i) {\n        if (!used[i]) {\n            vector<Point> cluster;\n            cluster.push_back(mackerels[i]);\n            used[i] = true;\n            \n            // Find nearby mackerels\n            for (int j = i + 1; j < N && cluster.size() < cluster_size; ++j) {\n                if (!used[j]) {\n                    int dx = mackerels[i].x - mackerels[j].x;\n                    int dy = mackerels[i].y - mackerels[j].y;\n                    if (dx * dx + dy * dy < 10000 * 10000) { // Within 10000 units\n                        cluster.push_back(mackerels[j]);\n                        used[j] = true;\n                    }\n                }\n            }\n            \n            if (cluster.size() >= 10) { // Only consider clusters with at least 10 mackerels\n                mackerel_clusters.push_back(cluster);\n            }\n        }\n    }\n    \n    // Sort clusters by size (descending)\n    sort(mackerel_clusters.begin(), mackerel_clusters.end(), \n         [](const vector<Point>& a, const vector<Point>& b) {\n             return a.size() > b.size();\n         });\n    \n    // Calculate the bounding box for each cluster\n    vector<tuple<int, int, int, int>> cluster_boxes;\n    for (const auto& cluster : mackerel_clusters) {\n        int min_x = 100000, max_x = 0;\n        int min_y = 100000, max_y = 0;\n        \n        for (const auto& p : cluster) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        cluster_boxes.emplace_back(min_x, min_y, max_x, max_y);\n    }\n    \n    // Try to create polygons for each cluster\n    Polygon best_polygon;\n    int best_score = 0;\n    \n    auto calculate_score = [](const Polygon& poly, const vector<Point>& macks, const vector<Point>& sards) {\n        int a = 0, b = 0;\n        for (const auto& p : macks) {\n            if (poly.contains(p)) {\n                a++;\n            }\n        }\n        for (const auto& p : sards) {\n            if (poly.contains(p)) {\n                b++;\n            }\n        }\n        return max(0, a - b + 1);\n    };\n    \n    // Try individual clusters\n    for (size_t i = 0; i < min(mackerel_clusters.size(), size_t(10)); ++i) {\n        const auto& box = cluster_boxes[i];\n        int min_x = get<0>(box);\n        int min_y = get<1>(box);\n        int max_x = get<2>(box);\n        int max_y = get<3>(box);\n        \n        // Create a polygon around this cluster\n        Polygon polygon;\n        polygon.add_vertex({min_x, min_y});\n        polygon.add_vertex({max_x, min_y});\n        polygon.add_vertex({max_x, max_y});\n        polygon.add_vertex({min_x, max_y});\n        \n        // Try to expand the polygon while maintaining a good score\n        const int max_expansions = 10;\n        for (int expansion = 0; expansion < max_expansions; ++expansion) {\n            // Try expanding in each direction\n            vector<Polygon> expansions;\n            \n            // Expand left\n            Polygon left_poly = polygon;\n            if (left_poly.vertices[0].x > 0) {\n                left_poly.vertices[0].x = max(0, left_poly.vertices[0].x - 1000);\n                left_poly.vertices[3].x = left_poly.vertices[0].x;\n                expansions.push_back(left_poly);\n            }\n            \n            // Expand right\n            Polygon right_poly = polygon;\n            if (right_poly.vertices[1].x < 100000) {\n                right_poly.vertices[1].x = min(100000, right_poly.vertices[1].x + 1000);\n                right_poly.vertices[2].x = right_poly.vertices[1].x;\n                expansions.push_back(right_poly);\n            }\n            \n            // Expand down\n            Polygon down_poly = polygon;\n            if (down_poly.vertices[0].y > 0) {\n                down_poly.vertices[0].y = max(0, down_poly.vertices[0].y - 1000);\n                down_poly.vertices[1].y = down_poly.vertices[0].y;\n                expansions.push_back(down_poly);\n            }\n            \n            // Expand up\n            Polygon up_poly = polygon;\n            if (up_poly.vertices[2].y < 100000) {\n                up_poly.vertices[2].y = min(100000, up_poly.vertices[2].y + 1000);\n                up_poly.vertices[3].y = up_poly.vertices[2].y;\n                expansions.push_back(up_poly);\n            }\n            \n            // Find the best expansion\n            Polygon best_expansion = polygon;\n            int best_expansion_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& exp : expansions) {\n                if (exp.perimeter() <= 400000) {\n                    int score = calculate_score(exp, mackerels, sardines);\n                    if (score > best_expansion_score) {\n                        best_expansion = exp;\n                        best_expansion_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_expansion;\n        }\n        \n        // Try to refine the polygon by adding notches to exclude sardines\n        const int max_notches = 50;\n        for (int notch = 0; notch < max_notches && polygon.vertices.size() < 1000; ++notch) {\n            // Find a sardine inside the polygon\n            vector<Point> inside_sardines;\n            for (const auto& p : sardines) {\n                if (polygon.contains(p)) {\n                    inside_sardines.push_back(p);\n                }\n            }\n            \n            if (inside_sardines.empty()) {\n                break; // No more sardines to exclude\n            }\n            \n            // Randomly select a sardine to exclude\n            uniform_int_distribution<int> dist(0, inside_sardines.size() - 1);\n            Point target = inside_sardines[dist(rng)];\n            \n            // Find the edge closest to the target sardine\n            int best_edge = -1;\n            double best_dist = numeric_limits<double>::max();\n            \n            for (int i = 0; i < polygon.vertices.size(); ++i) {\n                int j = (i + 1) % polygon.vertices.size();\n                const Point& v1 = polygon.vertices[i];\n                const Point& v2 = polygon.vertices[j];\n                \n                double dist;\n                if (v1.x == v2.x) { // Vertical edge\n                    dist = abs(target.x - v1.x);\n                } else { // Horizontal edge\n                    dist = abs(target.y - v1.y);\n                }\n                \n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_edge = i;\n                }\n            }\n            \n            if (best_edge != -1) {\n                int i = best_edge;\n                int j = (i + 1) % polygon.vertices.size();\n                const Point& v1 = polygon.vertices[i];\n                const Point& v2 = polygon.vertices[j];\n                \n                // Create a notch to exclude the sardine\n                Polygon new_polygon = polygon;\n                Point notch1, notch2;\n                \n                if (v1.x == v2.x) { // Vertical edge\n                    int x = v1.x;\n                    int y1 = min(v1.y, v2.y);\n                    int y2 = max(v1.y, v2.y);\n                    \n                    if (target.x < x) {\n                        notch1 = {x - 1000, y1 + (y2 - y1) / 3};\n                        notch2 = {x - 1000, y1 + 2 * (y2 - y1) / 3};\n                    } else {\n                        notch1 = {x + 1000, y1 + (y2 - y1) / 3};\n                        notch2 = {x + 1000, y1 + 2 * (y2 - y1) / 3};\n                    }\n                } else { // Horizontal edge\n                    int y = v1.y;\n                    int x1 = min(v1.x, v2.x);\n                    int x2 = max(v1.x, v2.x);\n                    \n                    if (target.y < y) {\n                        notch1 = {x1 + (x2 - x1) / 3, y - 1000};\n                        notch2 = {x1 + 2 * (x2 - x1) / 3, y - 1000};\n                    } else {\n                        notch1 = {x1 + (x2 - x1) / 3, y + 1000};\n                        notch2 = {x1 + 2 * (x2 - x1) / 3, y + 1000};\n                    }\n                }\n                \n                // Insert the notches\n                new_polygon.vertices.insert(new_polygon.vertices.begin() + j, notch2);\n                new_polygon.vertices.insert(new_polygon.vertices.begin() + j, notch1);\n                \n                // Check constraints\n                if (new_polygon.perimeter() <= 400000) {\n                    int score = calculate_score(new_polygon, mackerels, sardines);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_polygon = new_polygon;\n                    }\n                    polygon = new_polygon;\n                }\n            }\n        }\n        \n        // Update the best polygon\n        int score = calculate_score(polygon, mackerels, sardines);\n        if (score > best_score) {\n            best_score = score;\n            best_polygon = polygon;\n        }\n    }\n    \n    // If no good cluster was found, create a simple polygon\n    if (best_polygon.vertices.empty()) {\n        best_polygon.add_vertex({0, 0});\n        best_polygon.add_vertex({100000, 0});\n        best_polygon.add_vertex({100000, 100000});\n        best_polygon.add_vertex({0, 100000});\n    }\n    \n    // Output the best polygon\n    cout << best_polygon.vertices.size() << \"\\n\";\n    for (const auto& p : best_polygon.vertices) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <cctype>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<tuple<double, double, double, double, int>> placed_rectangles;\n        double current_width = 0.0;\n        double current_height = 0.0;\n        double penalty = 0.0;\n        vector<tuple<int, int, char, int>> sequence;\n\n        for (int i = 0; i < N; i++) {\n            tuple<int, int, char, int, double, double, double, double> best_option;\n            double best_cost = 1e18;\n            bool found = false;\n\n            double cost_skip = current_width + current_height + penalty + (w_est[i] + h_est[i]);\n\n            for (int rotation : {0, 1}) {\n                double w_i = (rotation == 0) ? w_est[i] : h_est[i];\n                double h_i = (rotation == 0) ? h_est[i] : w_est[i];\n\n                for (char direction : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (const auto& rect : placed_rectangles) {\n                        refs.push_back(get<4>(rect));\n                    }\n\n                    for (int ref : refs) {\n                        double x0, y0;\n                        if (direction == 'U') {\n                            if (ref == -1) {\n                                x0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                x0 = get<0>(*it) + get<2>(*it);\n                            }\n                            y0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_x, x0) < min(r_x + r_w, x0 + w_i)) {\n                                    double candidate = r_y + r_h;\n                                    if (candidate > y0) {\n                                        y0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        } else {\n                            if (ref == -1) {\n                                y0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                y0 = get<1>(*it) + get<3>(*it);\n                            }\n                            x0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_y, y0) < min(r_y + r_h, y0 + h_i)) {\n                                    double candidate = r_x + r_w;\n                                    if (candidate > x0) {\n                                        x0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (found && best_cost < cost_skip) {\n                auto [i_opt, rot_opt, dir_opt, ref_opt, x0_opt, y0_opt, w_i_opt, h_i_opt] = best_option;\n                current_width = max(current_width, x0_opt + w_i_opt);\n                current_height = max(current_height, y0_opt + h_i_opt);\n                placed_rectangles.emplace_back(x0_opt, y0_opt, w_i_opt, h_i_opt, i_opt);\n                sequence.emplace_back(i_opt, rot_opt, dir_opt, ref_opt);\n            } else {\n                penalty += (w_est[i] + h_est[i]);\n            }\n        }\n\n        cout << sequence.size() << '\\n';\n        for (const auto& [i, rot, dir, ref] : sequence) {\n            cout << i << ' ' << rot << ' ' << dir << ' ' << ref << '\\n';\n        }\n        cout << flush;\n\n        if (turn < T - 1) {\n            int W_prime, H_prime;\n            cin >> W_prime >> H_prime;\n\n            double width_factor = 1.0;\n            if (current_width > 0) {\n                width_factor = static_cast<double>(W_prime) / current_width;\n            }\n            double height_factor = 1.0;\n            if (current_height > 0) {\n                height_factor = static_cast<double>(H_prime) / current_height;\n            }\n\n            double alpha = 0.2;\n            width_factor = 1.0 + alpha * (width_factor - 1.0);\n            height_factor = 1.0 + alpha * (height_factor - 1.0);\n\n            for (const auto& rect : placed_rectangles) {\n                int idx = get<4>(rect);\n                w_est[idx] *= width_factor;\n                h_est[idx] *= height_factor;\n                w_est[idx] = max(1.0, min(1e9, w_est[idx]));\n                h_est[idx] = max(1.0, min(1e9, h_est[idx]));\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nstruct Vertex {\n    int id;\n    int x, y;\n    int beauty;\n    vector<int> neighbors;\n    int parent;\n    int height;\n    int root;\n};\n\nint H;  // Global height limit\n\n// Function to calculate attractiveness of a solution\nlong long calculate_attractiveness(const vector<Vertex>& vertices) {\n    long long attractiveness = 0;\n    for (const auto& v : vertices) {\n        attractiveness += (long long)(v.height + 1) * v.beauty;\n    }\n    return attractiveness;\n}\n\n// Function to update heights after changing a parent\nvoid update_heights(vector<Vertex>& vertices, int v) {\n    if (vertices[v].parent == -1) {\n        vertices[v].height = 0;\n        vertices[v].root = v;\n    } else {\n        vertices[v].height = vertices[vertices[v].parent].height + 1;\n        vertices[v].root = vertices[vertices[v].parent].root;\n    }\n    \n    // Recursively update children\n    for (int u : vertices[v].neighbors) {\n        if (vertices[u].parent == v) {\n            update_heights(vertices, u);\n        }\n    }\n}\n\n// Function to check if a parent assignment is valid (height <= H)\nbool is_valid_parent(const vector<Vertex>& vertices, int v, int parent) {\n    if (parent == -1) return true;\n    \n    int height = 1;  // At least height 1 if it has a parent\n    int current = parent;\n    \n    while (current != -1 && height <= H) {\n        current = vertices[current].parent;\n        height++;\n    }\n    \n    return height <= H;\n}\n\n// Function to calculate Euclidean distance between two vertices\ndouble distance(const Vertex& a, const Vertex& b) {\n    double dx = a.x - b.x;\n    double dy = a.y - b.y;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Function to find the best parent for a vertex\nint find_best_parent(const vector<Vertex>& vertices, int v, const vector<bool>& is_root) {\n    int best_parent = -1;\n    long long best_gain = 0;\n    \n    // Consider neighbors that are roots or from different trees\n    for (int u : vertices[v].neighbors) {\n        if (is_root[u] || vertices[u].root != vertices[v].root) {\n            if (is_valid_parent(vertices, v, u)) {\n                // Calculate the gain in attractiveness if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                // Prefer parents that allow for deeper nesting in the future\n                if (new_height < H) {\n                    gain += vertices[v].beauty / 2;  // Bonus for potential future gains\n                }\n                \n                // Add a spatial component: prefer closer parents\n                double dist = distance(vertices[v], vertices[u]);\n                double spatial_factor = 1.0 / (1.0 + dist / 100.0);  // Normalize distance\n                gain = (long long)(gain * spatial_factor);\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n    }\n    \n    return best_parent;\n}\n\n// Function to perform local search\nvoid local_search(vector<Vertex>& vertices, const vector<vector<int>>& adj, int max_iterations) {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> vertex_dist(0, vertices.size() - 1);\n    \n    long long current_attractiveness = calculate_attractiveness(vertices);\n    vector<bool> is_root(vertices.size(), false);\n    for (const auto& v : vertices) {\n        if (v.parent == -1) {\n            is_root[v.id] = true;\n        }\n    }\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        int v = vertex_dist(gen);\n        \n        // Try to find a better parent for v\n        int current_parent = vertices[v].parent;\n        int best_parent = current_parent;\n        long long best_gain = 0;\n        \n        for (int u : adj[v]) {\n            if (u != current_parent && vertices[u].parent != v &&  // Avoid creating cycles\n                is_valid_parent(vertices, v, u)) {\n                \n                // Calculate the gain if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n        \n        // If we found a better parent, update the solution\n        if (best_parent != current_parent && best_gain > 0) {\n            // Remove v from its current parent's children\n            if (current_parent != -1) {\n                // No need to explicitly remove, just update parent pointer\n            }\n            \n            // Add v to its new parent\n            vertices[v].parent = best_parent;\n            update_heights(vertices, v);\n            \n            // Update root status\n            if (current_parent == -1) {\n                is_root[v] = false;\n            }\n            \n            current_attractiveness += best_gain;\n        }\n        \n        // Occasionally try to make a vertex a root\n        if (iter % 100 == 0 && vertices[v].parent != -1) {\n            int old_parent = vertices[v].parent;\n            vertices[v].parent = -1;\n            update_heights(vertices, v);\n            \n            long long new_attractiveness = calculate_attractiveness(vertices);\n            if (new_attractiveness > current_attractiveness) {\n                current_attractiveness = new_attractiveness;\n                is_root[v] = true;\n            } else {\n                // Revert the change\n                vertices[v].parent = old_parent;\n                update_heights(vertices, v);\n            }\n        }\n        \n        // Occasionally try to swap parent-child relationships\n        if (iter % 200 == 0 && vertices[v].parent != -1) {\n            int parent = vertices[v].parent;\n            \n            // Check if we can swap parent and child\n            if (vertices[parent].parent != v && is_valid_parent(vertices, parent, v)) {\n                // Temporarily swap\n                int old_v_parent = vertices[v].parent;\n                int old_parent_parent = vertices[parent].parent;\n                \n                vertices[v].parent = old_parent_parent;\n                vertices[parent].parent = v;\n                \n                update_heights(vertices, v);\n                update_heights(vertices, parent);\n                \n                long long new_attractiveness = calculate_attractiveness(vertices);\n                if (new_attractiveness > current_attractiveness) {\n                    current_attractiveness = new_attractiveness;\n                    if (old_parent_parent == -1) {\n                        is_root[v] = true;\n                    }\n                    is_root[parent] = false;\n                } else {\n                    // Revert the swap\n                    vertices[v].parent = old_v_parent;\n                    vertices[parent].parent = old_parent_parent;\n                    update_heights(vertices, v);\n                    update_heights(vertices, parent);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M >> H;\n    \n    vector<Vertex> vertices(N);\n    for (int i = 0; i < N; i++) {\n        vertices[i].id = i;\n        cin >> vertices[i].beauty;\n    }\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        vertices[u].neighbors.push_back(v);\n        vertices[v].neighbors.push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].x >> vertices[i].y;\n    }\n    \n    // Initialize with each vertex as its own tree\n    for (auto& v : vertices) {\n        v.parent = -1;\n        v.height = 0;\n        v.root = v.id;\n    }\n    \n    // Sort vertices by beauty (lower beauty first)\n    vector<int> vertex_ids(N);\n    for (int i = 0; i < N; i++) {\n        vertex_ids[i] = i;\n    }\n    sort(vertex_ids.begin(), vertex_ids.end(), [&](int a, int b) {\n        return vertices[a].beauty < vertices[b].beauty;\n    });\n    \n    // Greedily assign parents\n    vector<bool> is_root(N, true);\n    for (int v : vertex_ids) {\n        // Only try to assign parents to vertices that can gain from having a parent\n        if (vertices[v].beauty > 30) {  // Threshold can be adjusted\n            int best_parent = find_best_parent(vertices, v, is_root);\n            if (best_parent != -1) {\n                vertices[v].parent = best_parent;\n                is_root[v] = false;\n                update_heights(vertices, v);\n            }\n        }\n    }\n    \n    // Perform local search\n    local_search(vertices, adj, 20000);  // Increased iterations for better results\n    \n    // Output the solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertices[i].parent;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <climits>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    set<pair<int, int>> oni_set;\n    set<pair<int, int>> fuku_set;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_set.insert({i, j});\n            } else if (grid[i][j] == 'o') {\n                fuku_set.insert({i, j});\n            }\n        }\n    }\n\n    vector<pair<char, int>> moves;\n\n    while (!oni_set.empty()) {\n        int best_cost = INT_MAX;\n        pair<int, int> best_oni;\n        char best_dir;\n        int best_index;\n\n        for (auto oni : oni_set) {\n            int i = oni.first;\n            int j = oni.second;\n\n            bool safe_up = true;\n            for (int r = 0; r < i; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_up = false;\n                    break;\n                }\n            }\n\n            bool safe_down = true;\n            for (int r = i+1; r < N; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_down = false;\n                    break;\n                }\n            }\n\n            bool safe_left = true;\n            for (int c = 0; c < j; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_left = false;\n                    break;\n                }\n            }\n\n            bool safe_right = true;\n            for (int c = j+1; c < N; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_right = false;\n                    break;\n                }\n            }\n\n            if (safe_up) {\n                int cost = i + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'U';\n                    best_index = j;\n                }\n            }\n            if (safe_down) {\n                int cost = N - i;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'D';\n                    best_index = j;\n                }\n            }\n            if (safe_left) {\n                int cost = j + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'L';\n                    best_index = i;\n                }\n            }\n            if (safe_right) {\n                int cost = N - j;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'R';\n                    best_index = i;\n                }\n            }\n        }\n\n        if (best_cost == INT_MAX) {\n            break;\n        }\n\n        for (int step = 0; step < best_cost; step++) {\n            moves.push_back({best_dir, best_index});\n\n            if (best_dir == 'U') {\n                char top = grid[0][best_index];\n                grid[0][best_index] = '.';\n                if (top == 'x') {\n                    oni_set.erase({0, best_index});\n                } else if (top == 'o') {\n                    fuku_set.erase({0, best_index});\n                }\n\n                for (int r = 1; r < N; r++) {\n                    char c = grid[r][best_index];\n                    grid[r-1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r-1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r-1, best_index});\n                    }\n                }\n                grid[N-1][best_index] = '.';\n            } else if (best_dir == 'D') {\n                char bottom = grid[N-1][best_index];\n                grid[N-1][best_index] = '.';\n                if (bottom == 'x') {\n                    oni_set.erase({N-1, best_index});\n                } else if (bottom == 'o') {\n                    fuku_set.erase({N-1, best_index});\n                }\n\n                for (int r = N-2; r >= 0; r--) {\n                    char c = grid[r][best_index];\n                    grid[r+1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r+1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r+1, best_index});\n                    }\n                }\n                grid[0][best_index] = '.';\n            } else if (best_dir == 'L') {\n                char leftmost = grid[best_index][0];\n                grid[best_index][0] = '.';\n                if (leftmost == 'x') {\n                    oni_set.erase({best_index, 0});\n                } else if (leftmost == 'o') {\n                    fuku_set.erase({best_index, 0});\n                }\n\n                for (int c = 1; c < N; c++) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c-1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c-1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c-1});\n                    }\n                }\n                grid[best_index][N-1] = '.';\n            } else if (best_dir == 'R') {\n                char rightmost = grid[best_index][N-1];\n                grid[best_index][N-1] = '.';\n                if (rightmost == 'x') {\n                    oni_set.erase({best_index, N-1});\n                } else if (rightmost == 'o') {\n                    fuku_set.erase({best_index, N-1});\n                }\n\n                for (int c = N-2; c >= 0; c--) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c+1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c+1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c+1});\n                    }\n                }\n                grid[best_index][0] = '.';\n            }\n        }\n    }\n\n    for (auto move : moves) {\n        cout << move.first << \" \" << move.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    srand(0);\n    int N = 100;\n    int L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<long long, int>> candidates;\n        for (int j = 0; j < N; j++) {\n            if (j == i) continue;\n            candidates.push_back({T[j], j});\n        }\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, int>>());\n        if (candidates.size() >= 2) {\n            a[i] = candidates[0].second;\n            b[i] = candidates[1].second;\n        } else if (candidates.size() == 1) {\n            a[i] = candidates[0].second;\n            b[i] = i;\n        } else {\n            a[i] = i;\n            b[i] = i;\n        }\n    }\n\n    auto simulate = [&](const vector<int>& a_vec, const vector<int>& b_vec) {\n        vector<long long> count(N, 0);\n        int current = 0;\n        count[0] = 1;\n        for (int week = 1; week < L; week++) {\n            int next;\n            if (count[current] & 1) {\n                next = a_vec[current];\n            } else {\n                next = b_vec[current];\n            }\n            count[next]++;\n            current = next;\n        }\n        long long error = 0;\n        for (int i = 0; i < N; i++) {\n            error += abs(count[i] - T[i]);\n        }\n        return error;\n    };\n\n    long long best_error = simulate(a, b);\n    vector<int> best_a = a;\n    vector<int> best_b = b;\n\n    for (int iter = 0; iter < 100; iter++) {\n        int i = rand() % N;\n        int old_a = a[i];\n        int old_b = b[i];\n\n        a[i] = rand() % N;\n        b[i] = rand() % N;\n\n        long long new_error = simulate(a, b);\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n        } else {\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <iomanip>\n#include <sstream>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\n\nstruct City {\n    int id;\n    double cx, cy;  // estimated center coordinates\n    int lx, rx, ly, ry;  // given rectangle bounds\n    double uncertainty;  // size of the rectangle, representing uncertainty\n};\n\nstruct Edge {\n    int u, v;\n    int weight;  // estimated or actual weight\n    double estimated_dist;  // estimated distance based on center coordinates\n    \n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nstruct QueryResult {\n    vector<pair<int, int>> edges;  // edges in the MST\n};\n\nclass Solution {\npublic:\n    int N, M, Q, L, W;\n    vector<int> G;\n    vector<City> cities;\n    vector<vector<int>> groups;\n    vector<vector<Edge>> group_edges;\n    int query_count = 0;\n    \n    void read_input() {\n        cin >> N >> M >> Q >> L >> W;\n        G.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> G[i];\n        }\n        \n        cities.resize(N);\n        for (int i = 0; i < N; i++) {\n            cities[i].id = i;\n            cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n            cities[i].cx = (cities[i].lx + cities[i].rx) / 2.0;\n            cities[i].cy = (cities[i].ly + cities[i].ry) / 2.0;\n            // Calculate uncertainty as the diagonal of the rectangle\n            cities[i].uncertainty = sqrt(pow(cities[i].rx - cities[i].lx, 2) + \n                                        pow(cities[i].ry - cities[i].ly, 2));\n        }\n    }\n    \n    double estimated_distance(int i, int j) {\n        double dx = cities[i].cx - cities[j].cx;\n        double dy = cities[i].cy - cities[j].cy;\n        return sqrt(dx * dx + dy * dy);\n    }\n    \n    void group_cities() {\n        // Sort cities by their estimated center coordinates\n        vector<int> city_ids(N);\n        for (int i = 0; i < N; i++) {\n            city_ids[i] = i;\n        }\n        \n        // We'll use a simple approach: divide the sorted list into groups of the required sizes\n        sort(city_ids.begin(), city_ids.end(), [this](int a, int b) {\n            if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n            return cities[a].cy < cities[b].cy;\n        });\n        \n        // Divide into groups of specified sizes\n        groups.resize(M);\n        int start_idx = 0;\n        for (int i = 0; i < M; i++) {\n            groups[i].resize(G[i]);\n            for (int j = 0; j < G[i]; j++) {\n                groups[i][j] = city_ids[start_idx + j];\n            }\n            start_idx += G[i];\n        }\n    }\n    \n    QueryResult query_mst(const vector<int>& city_subset) {\n        assert(city_subset.size() >= 2 && city_subset.size() <= L);\n        assert(query_count < Q);\n        \n        cout << \"? \" << city_subset.size();\n        for (int city : city_subset) {\n            cout << \" \" << city;\n        }\n        cout << endl;\n        cout.flush();\n        \n        QueryResult result;\n        result.edges.resize(city_subset.size() - 1);\n        for (int i = 0; i < city_subset.size() - 1; i++) {\n            cin >> result.edges[i].first >> result.edges[i].second;\n            if (result.edges[i].first > result.edges[i].second) {\n                swap(result.edges[i].first, result.edges[i].second);\n            }\n        }\n        \n        query_count++;\n        return result;\n    }\n    \n    void gather_mst_info() {\n        group_edges.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            // For each group, perform queries to gather MST information\n            int group_size = G[i];\n            \n            // If the group is small enough, query the entire group at once\n            if (group_size <= L) {\n                vector<int> subset = groups[i];\n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n                continue;\n            }\n            \n            // For larger groups, we'll use a more sophisticated approach\n            // First, sort cities within the group by their estimated positions\n            vector<int> sorted_group = groups[i];\n            sort(sorted_group.begin(), sorted_group.end(), [this](int a, int b) {\n                if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n                return cities[a].cy < cities[b].cy;\n            });\n            \n            // We'll create a list of potential edges, sorted by estimated distance\n            vector<pair<double, pair<int, int>>> potential_edges;\n            for (int u = 0; u < group_size; u++) {\n                for (int v = u + 1; v < group_size; v++) {\n                    double dist = estimated_distance(sorted_group[u], sorted_group[v]);\n                    potential_edges.emplace_back(dist, make_pair(u, v));\n                }\n            }\n            \n            sort(potential_edges.begin(), potential_edges.end());\n            \n            // We'll select subsets for querying based on the shortest potential edges\n            set<int> selected_cities;\n            vector<vector<int>> subsets;\n            \n            // Start with the cities connected by the shortest edges\n            for (const auto& [dist, edge] : potential_edges) {\n                if (query_count >= Q) break;\n                \n                int u = edge.first;\n                int v = edge.second;\n                \n                // If both cities are already in a subset, skip\n                if (selected_cities.count(u) && selected_cities.count(v)) continue;\n                \n                // Create a new subset containing these cities and some nearby ones\n                vector<int> subset;\n                subset.push_back(sorted_group[u]);\n                subset.push_back(sorted_group[v]);\n                selected_cities.insert(u);\n                selected_cities.insert(v);\n                \n                // Add nearby cities until we reach the maximum subset size\n                for (const auto& [dist2, edge2] : potential_edges) {\n                    if (subset.size() >= L) break;\n                    \n                    int u2 = edge2.first;\n                    int v2 = edge2.second;\n                    \n                    if (u2 == u || u2 == v || v2 == u || v2 == v) {\n                        int new_city = (selected_cities.count(u2) == 0) ? u2 : v2;\n                        if (selected_cities.count(new_city) == 0) {\n                            subset.push_back(sorted_group[new_city]);\n                            selected_cities.insert(new_city);\n                        }\n                    }\n                }\n                \n                subsets.push_back(subset);\n                \n                // If we've selected all cities, we're done\n                if (selected_cities.size() >= group_size) break;\n            }\n            \n            // If we haven't selected all cities, add the remaining ones\n            for (int j = 0; j < group_size; j++) {\n                if (selected_cities.count(j) == 0) {\n                    // Create a subset with this city and some nearby ones\n                    vector<int> subset;\n                    subset.push_back(sorted_group[j]);\n                    selected_cities.insert(j);\n                    \n                    // Add the closest cities\n                    for (const auto& [dist, edge] : potential_edges) {\n                        if (subset.size() >= L) break;\n                        \n                        int u = edge.first;\n                        int v = edge.second;\n                        \n                        if (u == j || v == j) {\n                            int other = (u == j) ? v : u;\n                            if (selected_cities.count(other) == 0) {\n                                subset.push_back(sorted_group[other]);\n                                selected_cities.insert(other);\n                            }\n                        }\n                    }\n                    \n                    subsets.push_back(subset);\n                }\n            }\n            \n            // Query each subset\n            for (const auto& subset : subsets) {\n                if (query_count >= Q) break;\n                if (subset.size() < 2) continue;\n                \n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n            }\n            \n            if (query_count >= Q) break;  // We've used all our queries\n        }\n    }\n    \n    void construct_final_msts() {\n        // For each group, we'll use the edges we've gathered to construct a connected graph\n        // If we don't have enough edges to form a spanning tree, we'll add more\n        \n        for (int i = 0; i < M; i++) {\n            // We need G[i] - 1 edges to connect G[i] cities\n            \n            // First, let's create a graph from the edges we've gathered\n            vector<vector<int>> graph(G[i]);\n            map<pair<int, int>, int> edge_to_index;\n            \n            for (int j = 0; j < group_edges[i].size(); j++) {\n                const Edge& e = group_edges[i][j];\n                int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                \n                graph[u_idx].push_back(v_idx);\n                graph[v_idx].push_back(u_idx);\n                \n                edge_to_index[{min(u_idx, v_idx), max(u_idx, v_idx)}] = j;\n            }\n            \n            // Check if the graph is connected\n            vector<bool> visited(G[i], false);\n            queue<int> q;\n            q.push(0);\n            visited[0] = true;\n            int visited_count = 1;\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                for (int v : graph[u]) {\n                    if (!visited[v]) {\n                        visited[v] = true;\n                        visited_count++;\n                        q.push(v);\n                    }\n                }\n            }\n            \n            if (visited_count == G[i]) {\n                // The graph is already connected, so we can use a subset of the edges\n                // We'll use Kruskal's algorithm to find the MST\n                vector<Edge> mst_edges;\n                vector<int> parent(G[i]);\n                for (int j = 0; j < G[i]; j++) {\n                    parent[j] = j;\n                }\n                \n                function<int(int)> find = [&](int x) {\n                    if (parent[x] != x) {\n                        parent[x] = find(parent[x]);\n                    }\n                    return parent[x];\n                };\n                \n                auto unite = [&](int x, int y) {\n                    x = find(x);\n                    y = find(y);\n                    if (x != y) {\n                        parent[x] = y;\n                        return true;\n                    }\n                    return false;\n                };\n                \n                // Sort edges by estimated distance\n                sort(group_edges[i].begin(), group_edges[i].end(), \n                    [](const Edge& a, const Edge& b) {\n                        return a.estimated_dist < b.estimated_dist;\n                    });\n                \n                for (const Edge& e : group_edges[i]) {\n                    int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                    int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                    \n                    if (unite(u_idx, v_idx)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == G[i] - 1) break;\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            } else {\n                // The graph is not connected, so we need to add more edges\n                // We'll use Prim's algorithm starting from the visited component\n                \n                // First, let's create a complete graph with estimated distances\n                vector<vector<pair<int, double>>> complete_graph(G[i]);\n                for (int u = 0; u < G[i]; u++) {\n                    for (int v = u + 1; v < G[i]; v++) {\n                        double dist = estimated_distance(groups[i][u], groups[i][v]);\n                        complete_graph[u].emplace_back(v, dist);\n                        complete_graph[v].emplace_back(u, dist);\n                    }\n                }\n                \n                // Use Prim's algorithm to find the MST\n                vector<bool> in_mst(G[i], false);\n                vector<Edge> mst_edges;\n                priority_queue<pair<double, pair<int, int>>, \n                              vector<pair<double, pair<int, int>>>, \n                              greater<pair<double, pair<int, int>>>> pq;\n                \n                // Start with the visited component\n                for (int u = 0; u < G[i]; u++) {\n                    if (visited[u]) {\n                        in_mst[u] = true;\n                        for (const auto& [v, dist] : complete_graph[u]) {\n                            if (!in_mst[v]) {\n                                pq.emplace(dist, make_pair(u, v));\n                            }\n                        }\n                    }\n                }\n                \n                while (!pq.empty() && mst_edges.size() < G[i] - 1) {\n                    auto [dist, edge] = pq.top();\n                    pq.pop();\n                    int u = edge.first;\n                    int v = edge.second;\n                    \n                    if (!in_mst[v]) {\n                        in_mst[v] = true;\n                        Edge e;\n                        e.u = groups[i][u];\n                        e.v = groups[i][v];\n                        e.weight = 0;\n                        e.estimated_dist = dist;\n                        mst_edges.push_back(e);\n                        \n                        for (const auto& [next_v, next_dist] : complete_graph[v]) {\n                            if (!in_mst[next_v]) {\n                                pq.emplace(next_dist, make_pair(v, next_v));\n                            }\n                        }\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            }\n        }\n    }\n    \n    void output_solution() {\n        cout << \"!\" << endl;\n        \n        for (int i = 0; i < M; i++) {\n            // Output the cities in the group\n            for (int j = 0; j < G[i]; j++) {\n                if (j > 0) cout << \" \";\n                cout << groups[i][j];\n            }\n            cout << endl;\n            \n            // Output the edges\n            for (const auto& edge : group_edges[i]) {\n                cout << edge.u << \" \" << edge.v << endl;\n            }\n        }\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        group_cities();\n        gather_mst_info();\n        construct_final_msts();\n        output_solution();\n    }\n};\n\nint main() {\n    Solution solution;\n    solution.solve();\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <array>\n#include <string>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int MAX_ACTIONS = 2 * N * M;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> blocks;\n    vector<string> actions;\n    \n    State(int i, int j) : i(i), j(j), blocks(N, vector<bool>(N, false)) {}\n    \n    bool is_valid(int ni, int nj) const {\n        return ni >= 0 && ni < N && nj >= 0 && nj < N;\n    }\n    \n    bool can_move(int dir) const {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        return is_valid(ni, nj) && !blocks[ni][nj];\n    }\n    \n    State move(int dir) const {\n        State new_state = *this;\n        new_state.i += di[dir];\n        new_state.j += dj[dir];\n        new_state.actions.push_back(string(1, 'M') + dir_chars[dir]);\n        return new_state;\n    }\n    \n    pair<State, int> slide(int dir) const {\n        State new_state = *this;\n        int ni = i, nj = j;\n        int steps = 0;\n        \n        while (true) {\n            int nni = ni + di[dir];\n            int nnj = nj + dj[dir];\n            \n            if (!is_valid(nni, nnj) || blocks[nni][nnj]) {\n                break;\n            }\n            \n            ni = nni;\n            nj = nnj;\n            steps++;\n        }\n        \n        if (steps > 0) {\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.actions.push_back(string(1, 'S') + dir_chars[dir]);\n        }\n        \n        return {new_state, steps};\n    }\n    \n    State alter(int dir) const {\n        State new_state = *this;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (is_valid(ni, nj)) {\n            new_state.blocks[ni][nj] = !blocks[ni][nj];\n            new_state.actions.push_back(string(1, 'A') + dir_chars[dir]);\n        }\n        \n        return new_state;\n    }\n    \n    int manhattan_distance(int ti, int tj) const {\n        return abs(i - ti) + abs(j - tj);\n    }\n    \n    vector<string> find_path(int target_i, int target_j) const {\n        queue<tuple<int, int, vector<string>>> q;\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n        \n        q.push({i, j, vector<string>()});\n        visited[i][j] = true;\n        \n        while (!q.empty()) {\n            auto [ci, cj, path] = q.front();\n            q.pop();\n            \n            if (ci == target_i && cj == target_j) {\n                vector<string> result;\n                while (ci != i || cj != j) {\n                    auto [pi, pj] = parent[ci][cj];\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (pi + di[dir] == ci && pj + dj[dir] == cj) {\n                            result.push_back(string(1, 'M') + dir_chars[dir]);\n                            break;\n                        }\n                    }\n                    ci = pi;\n                    cj = pj;\n                }\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ci + di[dir];\n                int nj = cj + dj[dir];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj] && !blocks[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent[ni][nj] = {ci, cj};\n                    vector<string> new_path = path;\n                    new_path.push_back(string(1, 'M') + dir_chars[dir]);\n                    q.push({ni, nj, new_path});\n                }\n            }\n        }\n        \n        return vector<string>();\n    }\n    \n    bool try_slide_to_target(int target_i, int target_j, int max_moves = 10) {\n        int initial_manhattan = manhattan_distance(target_i, target_j);\n        \n        for (int primary_dir = 0; primary_dir < 4; primary_dir++) {\n            State temp_state = *this;\n            \n            auto [slide_state, slide_steps] = temp_state.slide(primary_dir);\n            temp_state = slide_state;\n            \n            if (temp_state.manhattan_distance(target_i, target_j) < initial_manhattan) {\n                for (int secondary_dir = 0; secondary_dir < 4; secondary_dir++) {\n                    if (secondary_dir == primary_dir || secondary_dir == (primary_dir ^ 1)) {\n                        continue;\n                    }\n                    \n                    State temp_state2 = temp_state;\n                    \n                    int stop_i = target_i + di[secondary_dir];\n                    int stop_j = target_j + dj[secondary_dir];\n                    \n                    if (temp_state2.is_valid(stop_i, stop_j) && !temp_state2.blocks[stop_i][stop_j]) {\n                        auto path_to_block = temp_state2.find_path(stop_i - di[secondary_dir], stop_j - dj[secondary_dir]);\n                        if (path_to_block.size() <= max_moves) {\n                            for (const auto& action : path_to_block) {\n                                for (int dir = 0; dir < 4; dir++) {\n                                    if (action[1] == dir_chars[dir]) {\n                                        temp_state2 = temp_state2.move(dir);\n                                        break;\n                                    }\n                                }\n                            }\n                            \n                            temp_state2 = temp_state2.alter(secondary_dir);\n                            \n                            auto [slide_state2, slide_steps2] = temp_state2.slide(secondary_dir);\n                            temp_state2 = slide_state2;\n                            \n                            auto path = temp_state2.find_path(target_i, target_j);\n                            if (path.size() <= max_moves) {\n                                for (const auto& action : path) {\n                                    for (int dir = 0; dir < 4; dir++) {\n                                        if (action[1] == dir_chars[dir]) {\n                                            temp_state2 = temp_state2.move(dir);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                if (temp_state2.i == target_i && temp_state2.j == target_j) {\n                                    *this = temp_state2;\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return false;\n    }\n    \n    void optimize_blocks(const vector<pair<int, int>>& targets, int current_target_idx) {\n        for (int future = current_target_idx + 1; future < min(current_target_idx + 5, (int)targets.size()); future++) {\n            int future_i = targets[future].first;\n            int future_j = targets[future].second;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int block_i = future_i + di[dir];\n                int block_j = future_j + dj[dir];\n                \n                if (is_valid(block_i, block_j) && !blocks[block_i][block_j]) {\n                    int current_to_future_dir = -1;\n                    if (abs(i - future_i) > abs(j - future_j)) {\n                        current_to_future_dir = (i < future_i) ? 1 : 0;\n                    } else {\n                        current_to_future_dir = (j < future_j) ? 3 : 2;\n                    }\n                    \n                    if (dir == current_to_future_dir) {\n                        if (manhattan_distance(block_i, block_j) <= 5) {\n                            auto path_to_block = find_path(block_i - di[dir], block_j - dj[dir]);\n                            if (path_to_block.size() <= 5) {\n                                for (const auto& action : path_to_block) {\n                                    for (int d = 0; d < 4; d++) {\n                                        if (action[1] == dir_chars[d]) {\n                                            *this = move(d);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                *this = alter(dir);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<pair<int, int>> targets(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    State current(targets[0].first, targets[0].second);\n    \n    for (int k = 1; k < m; k++) {\n        int target_i = targets[k].first;\n        int target_j = targets[k].second;\n        \n        int manhattan = current.manhattan_distance(target_i, target_j);\n        \n        if (manhattan <= 4) {\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n        } else {\n            if (!current.try_slide_to_target(target_i, target_j)) {\n                auto path = current.find_path(target_i, target_j);\n                for (const auto& action : path) {\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (action[1] == dir_chars[dir]) {\n                            current = current.move(dir);\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        current.optimize_blocks(targets, k);\n    }\n    \n    for (const auto& action : current.actions) {\n        cout << action[0] << \" \" << action[1] << '\\n';\n    }\n    \n    return 0;\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;  // (a, b) and (c, d) are diagonal vertices\n    \n    Rectangle(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {\n        if (a > c) swap(a, c);\n        if (b > d) swap(b, d);\n    }\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(int x, int y) const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n    \n    int overlap_area(const Rectangle& other) const {\n        int overlap_a = max(a, other.a);\n        int overlap_b = max(b, other.b);\n        int overlap_c = min(c, other.c);\n        int overlap_d = min(d, other.d);\n        \n        if (overlap_a >= overlap_c || overlap_b >= overlap_d) return 0;\n        return (overlap_c - overlap_a) * (overlap_d - overlap_b);\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rectangle rect;\n    \n    double satisfaction() const {\n        int s = rect.area();\n        if (!rect.contains(x, y)) return 0.0;\n        \n        double min_val = min(r, s);\n        double max_val = max(r, s);\n        return 1.0 - pow(1.0 - min_val / max_val, 2);\n    }\n};\n\nvector<Rectangle> solve(int n, const vector<pair<int, int>>& points, const vector<int>& rs) {\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        companies[i].x = points[i].first;\n        companies[i].y = points[i].second;\n        companies[i].r = rs[i];\n    }\n    \n    // Sort companies by desired area (largest first)\n    vector<int> indices(n);\n    for (int i = 0; i < n; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return companies[i].r > companies[j].r;\n    });\n    \n    // Create a space-filling curve based initial placement\n    vector<pair<int, int>> space_order;\n    for (int y = 0; y < 100; ++y) {\n        for (int x = 0; x < 100; ++x) {\n            space_order.emplace_back(x, y);\n        }\n    }\n    \n    // Shuffle the space order for better distribution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(space_order.begin(), space_order.end(), rng);\n    \n    // Initialize rectangles\n    vector<Rectangle> placed_rectangles;\n    for (int i : indices) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Find dimensions that give area close to r\n        int w = min(10000, static_cast<int>(sqrt(r)) + 1);\n        int h = r / w;\n        if (w * h < r) h++;\n        \n        // Try to place the rectangle at different positions\n        Rectangle best_rect;\n        double best_score = -1.0;\n        \n        // Try positions based on the space order\n        for (const auto& pos : space_order) {\n            int base_x = pos.first * 100;\n            int base_y = pos.second * 100;\n            \n            // Try to place the rectangle with the desired point inside\n            int a = max(0, min(base_x, x - w/2));\n            int c = min(10000, a + w);\n            if (c - a < w) a = c - w;\n            \n            int b = max(0, min(base_y, y - h/2));\n            int d = min(10000, b + h);\n            if (d - b < h) b = d - h;\n            \n            Rectangle rect(a, b, c, d);\n            \n            // Check if the rectangle contains the desired point\n            if (!rect.contains(x, y)) continue;\n            \n            // Check for overlaps with already placed rectangles\n            bool has_overlap = false;\n            for (const auto& placed : placed_rectangles) {\n                if (rect.overlaps(placed)) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            \n            if (!has_overlap) {\n                // Calculate a score based on how close the area is to the desired area\n                int area = rect.area();\n                double score = 1.0 - abs(area - r) / max(area, r);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect;\n                }\n            }\n        }\n        \n        // If we couldn't find a non-overlapping position, use a minimal rectangle\n        if (best_score < 0) {\n            best_rect = Rectangle(x, y, x + 1, y + 1);\n        }\n        \n        companies[i].rect = best_rect;\n        placed_rectangles.push_back(best_rect);\n    }\n    \n    // Resolve overlaps iteratively\n    const int MAX_ITERATIONS = 100;\n    for (int iter = 0; iter < MAX_ITERATIONS; ++iter) {\n        bool has_overlap = false;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = i + 1; j < n; ++j) {\n                if (companies[i].rect.overlaps(companies[j].rect)) {\n                    has_overlap = true;\n                    \n                    // Calculate overlap area\n                    int overlap_area = companies[i].rect.overlap_area(companies[j].rect);\n                    \n                    // Resolve overlap by shrinking the rectangle with smaller desired area\n                    if (companies[i].r < companies[j].r) {\n                        // Shrink company i's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_i.a < rect_j.a) {\n                                rect_i.c = min(rect_i.c, rect_j.a);\n                            } else {\n                                rect_i.a = max(rect_i.a, rect_j.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_i.b < rect_j.b) {\n                                rect_i.d = min(rect_i.d, rect_j.b);\n                            } else {\n                                rect_i.b = max(rect_i.b, rect_j.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                            // Try a different approach\n                            rect_i = companies[i].rect;\n                            if (rect_j.a < rect_i.a) {\n                                rect_i.a = rect_j.c;\n                            } else {\n                                rect_i.c = rect_j.a;\n                            }\n                            \n                            if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_i = Rectangle(companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1);\n                            }\n                        }\n                    } else {\n                        // Shrink company j's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_j.a < rect_i.a) {\n                                rect_j.c = min(rect_j.c, rect_i.a);\n                            } else {\n                                rect_j.a = max(rect_j.a, rect_i.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_j.b < rect_i.b) {\n                                rect_j.d = min(rect_j.d, rect_i.b);\n                            } else {\n                                rect_j.b = max(rect_j.b, rect_i.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                            // Try a different approach\n                            rect_j = companies[j].rect;\n                            if (rect_i.a < rect_j.a) {\n                                rect_j.a = rect_i.c;\n                            } else {\n                                rect_j.c = rect_i.a;\n                            }\n                            \n                            if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_j = Rectangle(companies[j].x, companies[j].y, companies[j].x + 1, companies[j].y + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!has_overlap) break;\n    }\n    \n    // Final optimization using simulated annealing\n    rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n    double temperature = 100.0;\n    const double COOLING_RATE = 0.95;\n    const int SA_ITERATIONS = 1000;\n    \n    double current_score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        current_score += companies[i].satisfaction();\n    }\n    \n    for (int iter = 0; iter < SA_ITERATIONS; ++iter) {\n        temperature *= COOLING_RATE;\n        \n        // Choose a random company to modify\n        int i = rng() % n;\n        Rectangle old_rect = companies[i].rect;\n        double old_satisfaction = companies[i].satisfaction();\n        \n        // Choose a random modification\n        int mod_type = rng() % 8;\n        \n        switch (mod_type) {\n            case 0: {  // Move left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                companies[i].rect.c -= delta;\n                break;\n            }\n            case 1: {  // Move right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.a += delta;\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 2: {  // Move up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                companies[i].rect.d -= delta;\n                break;\n            }\n            case 3: {  // Move down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.b += delta;\n                companies[i].rect.d += delta;\n                break;\n            }\n            case 4: {  // Expand left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                break;\n            }\n            case 5: {  // Expand right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 6: {  // Expand up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                break;\n            }\n            case 7: {  // Expand down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.d += delta;\n                break;\n            }\n        }\n        \n        // Check constraints\n        bool valid = true;\n        \n        // Check if the rectangle still contains the desired point\n        if (!companies[i].rect.contains(companies[i].x, companies[i].y)) {\n            valid = false;\n        }\n        \n        // Check for overlaps\n        if (valid) {\n            for (int j = 0; j < n; ++j) {\n                if (i != j && companies[i].rect.overlaps(companies[j].rect)) {\n                    valid = false;\n                    break;\n                }\n            }\n        }\n        \n        if (valid) {\n            double new_satisfaction = companies[i].satisfaction();\n            double delta_score = new_satisfaction - old_satisfaction;\n            \n            // Accept or reject the move based on simulated annealing\n            if (delta_score > 0 || exp(delta_score / temperature) > (rng() % 1000) / 1000.0) {\n                current_score += delta_score;\n            } else {\n                companies[i].rect = old_rect;\n            }\n        } else {\n            companies[i].rect = old_rect;\n        }\n    }\n    \n    // Extract the final rectangles\n    vector<Rectangle> result;\n    for (int i = 0; i < n; ++i) {\n        result.push_back(companies[i].rect);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<pair<int, int>> points(n);\n    vector<int> rs(n);\n    \n    for (int i = 0; i < n; ++i) {\n        cin >> points[i].first >> points[i].second >> rs[i];\n    }\n    \n    vector<Rectangle> solution = solve(n, points, rs);\n    \n    for (const auto& rect : solution) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Tile {\n    int id;\n    vector<pair<int, int>> squares;\n    int total_value;\n    set<int> adjacent_tiles;\n    bool is_1x1;\n    pair<int, int> other_square;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tiles(50, vector<int>(50));\n    vector<vector<int>> points(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tiles[i][j];\n        }\n    }\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> points[i][j];\n        }\n    }\n    \n    // Build tile information\n    map<int, Tile> tile_map;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int tile_id = tiles[i][j];\n            if (tile_map.find(tile_id) == tile_map.end()) {\n                tile_map[tile_id] = {tile_id, {}, 0, {}, true, {-1, -1}};\n            }\n            tile_map[tile_id].squares.emplace_back(i, j);\n            tile_map[tile_id].total_value += points[i][j];\n        }\n    }\n    \n    // Determine tile types and other square\n    for (auto& [id, tile] : tile_map) {\n        if (tile.squares.size() == 2) {\n            tile.is_1x1 = false;\n            if (tile.squares[0].first == tile.squares[1].first) {\n                // 1x2 tile\n                if (tile.squares[0].second < tile.squares[1].second) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            } else {\n                // 2x1 tile\n                if (tile.squares[0].first < tile.squares[1].first) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            }\n        }\n    }\n    \n    // Build adjacency information\n    for (auto& [id, tile] : tile_map) {\n        for (auto& [i, j] : tile.squares) {\n            vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n            for (auto& [di, dj] : directions) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int neighbor_tile_id = tiles[ni][nj];\n                    if (neighbor_tile_id != id) {\n                        tile.adjacent_tiles.insert(neighbor_tile_id);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Start tile\n    int start_tile_id = tiles[si][sj];\n    set<int> visited_tiles;\n    visited_tiles.insert(start_tile_id);\n    int current_i = si, current_j = sj;\n    string path;\n    \n    // If starting tile is 1x2 or 2x1, move to the other square\n    if (!tile_map[start_tile_id].is_1x1) {\n        auto [oi, oj] = tile_map[start_tile_id].other_square;\n        if (oi < current_i) {\n            path += 'U';\n            current_i = oi;\n        } else if (oi > current_i) {\n            path += 'D';\n            current_i = oi;\n        } else if (oj < current_j) {\n            path += 'L';\n            current_j = oj;\n        } else if (oj > current_j) {\n            path += 'R';\n            current_j = oj;\n        }\n    }\n    \n    // Greedy walk with probabilistic selection\n    random_device rd;\n    mt19937 gen(rd());\n    \n    while (true) {\n        vector<pair<int, pair<char, pair<int, int>>>> candidates;\n        \n        vector<pair<char, pair<int, int>>> directions = {\n            {'U', {-1, 0}}, {'D', {1, 0}}, {'L', {0, -1}}, {'R', {0, 1}}\n        };\n        \n        for (auto& [dir, delta] : directions) {\n            int ni = current_i + delta.first;\n            int nj = current_j + delta.second;\n            \n            if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                int next_tile_id = tiles[ni][nj];\n                \n                if (visited_tiles.find(next_tile_id) == visited_tiles.end()) {\n                    int score = tile_map[next_tile_id].total_value;\n                    \n                    // Consider connectivity\n                    int adjacent_unvisited = 0;\n                    for (int adj_id : tile_map[next_tile_id].adjacent_tiles) {\n                        if (visited_tiles.find(adj_id) == visited_tiles.end()) {\n                            adjacent_unvisited++;\n                        }\n                    }\n                    \n                    score += adjacent_unvisited * 10;  // Weight for connectivity\n                    candidates.emplace_back(score, make_pair(dir, make_pair(ni, nj)));\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Probabilistic selection\n        vector<double> probabilities;\n        for (int i = 0; i < candidates.size(); ++i) {\n            probabilities.push_back(pow(0.8, i));\n        }\n        \n        double sum_probs = accumulate(probabilities.begin(), probabilities.end(), 0.0);\n        for (double& prob : probabilities) {\n            prob /= sum_probs;\n        }\n        \n        uniform_real_distribution<> dis(0.0, 1.0);\n        double r = dis(gen);\n        double cumulative = 0.0;\n        int selected_idx = 0;\n        \n        for (int i = 0; i < probabilities.size(); ++i) {\n            cumulative += probabilities[i];\n            if (r <= cumulative) {\n                selected_idx = i;\n                break;\n            }\n        }\n        \n        auto& [score, move_info] = candidates[selected_idx];\n        auto& [dir, next_pos] = move_info;\n        auto& [ni, nj] = next_pos;\n        \n        int next_tile_id = tiles[ni][nj];\n        \n        path += dir;\n        visited_tiles.insert(next_tile_id);\n        current_i = ni;\n        current_j = nj;\n        \n        // If tile is 1x2 or 2x1, move to the other square\n        if (!tile_map[next_tile_id].is_1x1) {\n            auto [oi, oj] = tile_map[next_tile_id].other_square;\n            if (oi != ni || oj != nj) {\n                if (oi < ni) {\n                    path += 'U';\n                    current_i = oi;\n                } else if (oi > ni) {\n                    path += 'D';\n                    current_i = oi;\n                } else if (oj < nj) {\n                    path += 'L';\n                    current_j = oj;\n                } else if (oj > nj) {\n                    path += 'R';\n                    current_j = oj;\n                }\n            }\n        }\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <functional>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\nint main() {\n    vector<vector<double>> hor_est(N, vector<double>(N-1, 5000.0));\n    vector<vector<double>> ver_est(N-1, vector<double>(N, 5000.0));\n\n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        vector<vector<double>> dist(N, vector<double>(N, 1e18));\n        vector<vector<tuple<int, int, char>>> parent(N, vector<tuple<int, int, char>>(N, make_tuple(-1, -1, ' ')));\n        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (i == ti && j == tj) {\n                break;\n            }\n            if (d > dist[i][j]) {\n                continue;\n            }\n\n            if (i > 0) {\n                double w = ver_est[i-1][j];\n                if (d + w < dist[i-1][j]) {\n                    dist[i-1][j] = d + w;\n                    parent[i-1][j] = make_tuple(i, j, 'U');\n                    pq.push({dist[i-1][j], i-1, j});\n                }\n            }\n            if (i < N-1) {\n                double w = ver_est[i][j];\n                if (d + w < dist[i+1][j]) {\n                    dist[i+1][j] = d + w;\n                    parent[i+1][j] = make_tuple(i, j, 'D');\n                    pq.push({dist[i+1][j], i+1, j});\n                }\n            }\n            if (j > 0) {\n                double w = hor_est[i][j-1];\n                if (d + w < dist[i][j-1]) {\n                    dist[i][j-1] = d + w;\n                    parent[i][j-1] = make_tuple(i, j, 'L');\n                    pq.push({dist[i][j-1], i, j-1});\n                }\n            }\n            if (j < N-1) {\n                double w = hor_est[i][j];\n                if (d + w < dist[i][j+1]) {\n                    dist[i][j+1] = d + w;\n                    parent[i][j+1] = make_tuple(i, j, 'R');\n                    pq.push({dist[i][j+1], i, j+1});\n                }\n            }\n        }\n\n        string path_str = \"\";\n        int i = ti, j = tj;\n        while (i != si || j != sj) {\n            auto [pi, pj, dir] = parent[i][j];\n            path_str += dir;\n            i = pi;\n            j = pj;\n        }\n        reverse(path_str.begin(), path_str.end());\n\n        cout << path_str << endl;\n        cout.flush();\n\n        int y;\n        cin >> y;\n\n        double L_est = 0.0;\n        vector<double*> edges_in_path;\n        i = si; j = sj;\n        for (char c : path_str) {\n            if (c == 'U') {\n                L_est += ver_est[i-1][j];\n                edges_in_path.push_back(&ver_est[i-1][j]);\n                i--;\n            } else if (c == 'D') {\n                L_est += ver_est[i][j];\n                edges_in_path.push_back(&ver_est[i][j]);\n                i++;\n            } else if (c == 'L') {\n                L_est += hor_est[i][j-1];\n                edges_in_path.push_back(&hor_est[i][j-1]);\n                j--;\n            } else if (c == 'R') {\n                L_est += hor_est[i][j];\n                edges_in_path.push_back(&hor_est[i][j]);\n                j++;\n            }\n        }\n\n        int m = edges_in_path.size();\n        double error = y - L_est;\n        for (double* ptr : edges_in_path) {\n            *ptr += 0.1 * error / m;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <array>\n\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int N = 20;\nconstexpr char EMPTY = '.';\nconstexpr array<char, 8> CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Problem {\n    int M;\n    vector<string> strings;\n    vector<array<array<int, 8>, N>> char_freq;\n    vector<int> string_importance;\n    \n    Problem(int M, const vector<string>& strings) : M(M), strings(strings) {\n        char_freq.resize(N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char_freq[i][j].fill(0);\n            }\n        }\n        \n        string_importance.resize(M);\n        for (int i = 0; i < M; i++) {\n            string_importance[i] = strings[i].size();\n        }\n        \n        for (int idx = 0; idx < M; idx++) {\n            const auto& s = strings[idx];\n            int k = s.size();\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int p = 0; p < min(k, N); p++) {\n                        int c = s[p] - 'A';\n                        char_freq[i][(j + p) % N][c] += string_importance[idx];\n                        char_freq[(i + p) % N][j][c] += string_importance[idx];\n                    }\n                }\n            }\n        }\n    }\n};\n\nstruct Solution {\n    vector<string> matrix;\n    vector<bool> satisfied;\n    int score;\n    int satisfied_count;\n    int empty_count;\n    \n    Solution() : matrix(N, string(N, EMPTY)), score(0), satisfied_count(0), empty_count(N*N) {}\n    \n    void fill_based_on_freq(const Problem& problem) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == EMPTY) {\n                    int max_freq = -1;\n                    char best_char = EMPTY;\n                    for (int c = 0; c < 8; c++) {\n                        if (problem.char_freq[i][j][c] > max_freq) {\n                            max_freq = problem.char_freq[i][j][c];\n                            best_char = 'A' + c;\n                        }\n                    }\n                    if (best_char != EMPTY) {\n                        matrix[i][j] = best_char;\n                    }\n                }\n            }\n        }\n        empty_count = 0;\n    }\n    \n    void random_partial_fill(double fill_ratio) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        int fill_count = static_cast<int>(N * N * fill_ratio);\n        vector<pair<int, int>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                positions.emplace_back(i, j);\n            }\n        }\n        shuffle(positions.begin(), positions.end(), rng);\n        for (int k = 0; k < fill_count; k++) {\n            auto [i, j] = positions[k];\n            matrix[i][j] = CHARS[char_dist(rng)];\n        }\n        empty_count = N * N - fill_count;\n    }\n    \n    bool is_subsequence(const string& s) const {\n        int k = s.size();\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                bool match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[i][(j + p) % N] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n                \n                match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[(i + p) % N][j] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    int calculate_score(const Problem& problem) {\n        satisfied.resize(problem.M);\n        satisfied_count = 0;\n        for (int i = 0; i < problem.M; i++) {\n            satisfied[i] = is_subsequence(problem.strings[i]);\n            if (satisfied[i]) {\n                satisfied_count++;\n            }\n        }\n        \n        if (satisfied_count < problem.M) {\n            score = static_cast<int>(round(1e8 * static_cast<double>(satisfied_count) / problem.M));\n        } else {\n            score = static_cast<int>(round(1e8 * (2.0 * N * N) / (2.0 * N * N - empty_count)));\n        }\n        \n        return score;\n    }\n    \n    void mutate(const Problem& problem) {\n        uniform_int_distribution<int> pos_dist(0, N-1);\n        uniform_int_distribution<int> char_dist(0, 7);\n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        double r = real_dist(rng);\n        \n        if (r < 0.6) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            if (matrix[i][j] != EMPTY) {\n                matrix[i][j] = CHARS[char_dist(rng)];\n            }\n        } else if (r < 0.8) {\n            int i1 = pos_dist(rng);\n            int j1 = pos_dist(rng);\n            int i2 = pos_dist(rng);\n            int j2 = pos_dist(rng);\n            swap(matrix[i1][j1], matrix[i2][j2]);\n        } else if (r < 0.9) {\n            if (real_dist(rng) < 0.5) {\n                int i = pos_dist(rng);\n                int shift = pos_dist(rng);\n                rotate(matrix[i].begin(), matrix[i].begin() + shift, matrix[i].end());\n            } else {\n                int j = pos_dist(rng);\n                int shift = pos_dist(rng);\n                vector<char> column(N);\n                for (int i = 0; i < N; i++) {\n                    column[i] = matrix[i][j];\n                }\n                rotate(column.begin(), column.begin() + shift, column.end());\n                for (int i = 0; i < N; i++) {\n                    matrix[i][j] = column[i];\n                }\n            }\n        } else {\n            vector<int> unsatisfied;\n            for (int i = 0; i < problem.M; i++) {\n                if (!satisfied[i]) {\n                    unsatisfied.push_back(i);\n                }\n            }\n            \n            if (!unsatisfied.empty()) {\n                uniform_int_distribution<int> unsat_dist(0, unsatisfied.size()-1);\n                int idx = unsatisfied[unsat_dist(rng)];\n                const string& s = problem.strings[idx];\n                int k = s.size();\n                \n                int i = pos_dist(rng);\n                int j = pos_dist(rng);\n                if (real_dist(rng) < 0.5) {\n                    for (int p = 0; p < k; p++) {\n                        matrix[i][(j + p) % N] = s[p];\n                    }\n                } else {\n                    for (int p = 0; p < k; p++) {\n                        matrix[(i + p) % N][j] = s[p];\n                    }\n                }\n            }\n        }\n    }\n    \n    void print() const {\n        for (const auto& row : matrix) {\n            cout << row << endl;\n        }\n    }\n};\n\nSolution solve(const Problem& problem) {\n    Solution best_solution;\n    int best_score = 0;\n    \n    vector<int> sorted_indices(problem.M);\n    for (int i = 0; i < problem.M; i++) {\n        sorted_indices[i] = i;\n    }\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return problem.string_importance[a] > problem.string_importance[b];\n    });\n    \n    for (int trial = 0; trial < 5; trial++) {\n        Solution solution;\n        \n        double fill_ratio = 0.3 + 0.1 * trial;\n        solution.random_partial_fill(fill_ratio);\n        solution.fill_based_on_freq(problem);\n        \n        for (int i = 0; i < min(30, problem.M); i++) {\n            int idx = sorted_indices[i];\n            const string& s = problem.strings[idx];\n            int k = s.size();\n            \n            uniform_int_distribution<int> pos_dist(0, N-1);\n            uniform_real_distribution<double> real_dist(0.0, 1.0);\n            int row = pos_dist(rng);\n            int col = pos_dist(rng);\n            \n            if (real_dist(rng) < 0.5) {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[row][(col + p) % N] = s[p];\n                }\n            } else {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[(row + p) % N][col] = s[p];\n                }\n            }\n        }\n        \n        solution.empty_count = 0;\n        int current_score = solution.calculate_score(problem);\n        \n        double temperature = 100.0;\n        double cooling_rate = 0.995;\n        int iterations = 15000;\n        \n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            Solution new_solution = solution;\n            new_solution.mutate(problem);\n            int new_score = new_solution.calculate_score(problem);\n            \n            if (new_score > current_score || real_dist(rng) < exp((new_score - current_score) / temperature)) {\n                solution = new_solution;\n                current_score = new_score;\n                \n                if (current_score > best_score) {\n                    best_solution = solution;\n                    best_score = current_score;\n                }\n            }\n            \n            temperature *= cooling_rate;\n            \n            if (iter % 1000 == 0) {\n                temperature = max(temperature, 1.0);\n            }\n        }\n    }\n    \n    if (best_solution.satisfied_count < problem.M) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_solution.matrix[i][j] == EMPTY) {\n                    best_solution.matrix[i][j] = CHARS[char_dist(rng)];\n                }\n            }\n        }\n        best_solution.empty_count = 0;\n        best_solution.calculate_score(problem);\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    cin >> M;\n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Problem problem(M, strings);\n    Solution solution = solve(problem);\n    solution.print();\n    \n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <list>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <unordered_map>\n#include <unordered_set>\n#include <string>\n#include <utility>\n#include <array>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    Point(int i_=0, int j_=0) : i(i_), j(j_) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n};\n\nstruct Segment {\n    bool is_horizontal;\n    int fixed_index;\n    int start, end;\n    Segment(bool h, int idx, int s, int e) : is_horizontal(h), fixed_index(idx), start(s), end(e) {}\n    bool operator==(const Segment& other) const {\n        return is_horizontal == other.is_horizontal && fixed_index == other.fixed_index && start == other.start && end == other.end;\n    }\n    bool operator<(const Segment& other) const {\n        if (is_horizontal != other.is_horizontal) return is_horizontal < other.is_horizontal;\n        if (fixed_index != other.fixed_index) return fixed_index < other.fixed_index;\n        if (start != other.start) return start < other.start;\n        return end < other.end;\n    }\n};\n\nvector<Point> dial_shortest_path(const vector<vector<int>>& grid_cost, int N, Point start, Point end) {\n    int max_cost = 9 * N * N;\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n    vector<list<Point>> buckets(max_cost + 1);\n\n    dist[start.i][start.j] = 0;\n    buckets[0].push_back(start);\n\n    for (int idx = 0; idx <= max_cost; idx++) {\n        while (!buckets[idx].empty()) {\n            Point p = buckets[idx].front();\n            buckets[idx].pop_front();\n            if (dist[p.i][p.j] < idx) continue;\n            if (p == end) break;\n            for (auto [di, dj] : {array<int,2>{-1,0}, {1,0}, {0,-1}, {0,1}}) {\n                int ni = p.i + di;\n                int nj = p.j + dj;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid_cost[ni][nj] == -1) continue;\n                int new_cost = dist[p.i][p.j] + grid_cost[ni][nj];\n                if (new_cost < dist[ni][nj]) {\n                    dist[ni][nj] = new_cost;\n                    parent[ni][nj] = p;\n                    if (new_cost <= max_cost) {\n                        buckets[new_cost].push_front(Point(ni, nj));\n                    }\n                }\n            }\n        }\n    }\n\n    vector<Point> path;\n    if (dist[end.i][end.j] == INF) {\n        return path;\n    }\n    Point cur = end;\n    while (cur != start) {\n        path.push_back(cur);\n        cur = parent[cur.i][cur.j];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<int> bipartite_matching(const vector<vector<int>>& graph, int nH, int nV) {\n    vector<int> matchH(nH, -1);\n    vector<int> matchV(nV, -1);\n    vector<bool> visited;\n\n    function<bool(int)> dfs = [&](int u) {\n        visited[u] = true;\n        for (int v : graph[u]) {\n            if (matchV[v] == -1 || (!visited[matchV[v]] && dfs(matchV[v]))) {\n                matchH[u] = v;\n                matchV[v] = u;\n                return true;\n            }\n        }\n        return false;\n    };\n\n    for (int u = 0; u < nH; u++) {\n        visited.assign(nH, false);\n        dfs(u);\n    }\n\n    vector<int> matching(nH, -1);\n    for (int u = 0; u < nH; u++) {\n        if (matchH[u] != -1) {\n            matching[u] = matchH[u];\n        }\n    }\n    return matching;\n}\n\nvector<Segment> konig_vertex_cover(const vector<vector<int>>& graph, const vector<int>& matching, int nH, int nV) {\n    vector<vector<int>> residual_graph(nH + nV);\n    for (int u = 0; u < nH; u++) {\n        for (int v : graph[u]) {\n            if (matching[u] == v) {\n                residual_graph[nH + v].push_back(u);\n            } else {\n                residual_graph[u].push_back(nH + v);\n            }\n        }\n    }\n\n    vector<bool> marked(nH + nV, false);\n    queue<int> q;\n    for (int u = 0; u < nH; u++) {\n        if (matching[u] == -1) {\n            marked[u] = true;\n            q.push(u);\n        }\n    }\n\n    while (!q.empty()) {\n        int node = q.front();\n        q.pop();\n        for (int neighbor : residual_graph[node]) {\n            if (!marked[neighbor]) {\n                marked[neighbor] = true;\n                q.push(neighbor);\n            }\n        }\n    }\n\n    vector<Segment> vertex_cover;\n    for (int u = 0; u < nH; u++) {\n        if (!marked[u]) {\n            vertex_cover.push_back(Segment(true, u, 0, 0));\n        }\n    }\n    for (int v = 0; v < nV; v++) {\n        if (marked[nH + v]) {\n            vertex_cover.push_back(Segment(false, v, 0, 0));\n        }\n    }\n    return vertex_cover;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid_str[i];\n    }\n\n    vector<vector<int>> grid_cost(N, vector<int>(N, -1));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                grid_cost[i][j] = grid_str[i][j] - '0';\n            }\n        }\n    }\n\n    vector<Segment> h_segments, v_segments;\n    vector<vector<Segment*>> h_segment_ptr(N, vector<Segment*>(N, nullptr));\n    vector<vector<Segment*>> v_segment_ptr(N, vector<Segment*>(N, nullptr));\n\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid_str[i][j] == '#') {\n                j++;\n                continue;\n            }\n            int start = j;\n            while (j < N && grid_str[i][j] != '#') {\n                j++;\n            }\n            int end = j - 1;\n            h_segments.emplace_back(true, i, start, end);\n            Segment* seg = &h_segments.back();\n            for (int k = start; k <= end; k++) {\n                h_segment_ptr[i][k] = seg;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid_str[i][j] == '#') {\n                i++;\n                continue;\n            }\n            int start = i;\n            while (i < N && grid_str[i][j] != '#') {\n                i++;\n            }\n            int end = i - 1;\n            v_segments.emplace_back(false, j, start, end);\n            Segment* seg = &v_segments.back();\n            for (int k = start; k <= end; k++) {\n                v_segment_ptr[k][j] = seg;\n            }\n        }\n    }\n\n    unordered_map<Segment*, int> h_segment_to_id;\n    unordered_map<Segment*, int> v_segment_to_id;\n    for (int i = 0; i < h_segments.size(); i++) {\n        h_segment_to_id[&h_segments[i]] = i;\n    }\n    for (int i = 0; i < v_segments.size(); i++) {\n        v_segment_to_id[&v_segments[i]] = i;\n    }\n\n    vector<vector<int>> bipartite_graph(h_segments.size());\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                Segment* h_seg = h_segment_ptr[i][j];\n                Segment* v_seg = v_segment_ptr[i][j];\n                int h_id = h_segment_to_id[h_seg];\n                int v_id = v_segment_to_id[v_seg];\n                bipartite_graph[h_id].push_back(v_id);\n            }\n        }\n    }\n\n    vector<int> matching = bipartite_matching(bipartite_graph, h_segments.size(), v_segments.size());\n    vector<Segment> vertex_cover_segments = konig_vertex_cover(bipartite_graph, matching, h_segments.size(), v_segments.size());\n\n    Segment* h_start_seg = h_segment_ptr[si][sj];\n    Segment* v_start_seg = v_segment_ptr[si][sj];\n    vector<Segment> segments_to_cover;\n    for (const Segment& seg : vertex_cover_segments) {\n        if (seg.is_horizontal) {\n            if (&h_segments[seg.fixed_index] != h_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        } else {\n            if (&v_segments[seg.fixed_index] != v_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        }\n    }\n\n    vector<Point> candidate_points;\n    for (const Segment& seg : segments_to_cover) {\n        if (seg.is_horizontal) {\n            candidate_points.emplace_back(seg.fixed_index, seg.start);\n        } else {\n            candidate_points.emplace_back(seg.start, seg.fixed_index);\n        }\n    }\n\n    vector<Point> P;\n    P.emplace_back(si, sj);\n    P.insert(P.end(), candidate_points.begin(), candidate_points.end());\n    int total_points = P.size();\n\n    vector<vector<int>> dist_matrix(total_points, vector<int>(total_points, INF));\n    vector<vector<vector<Point>>> paths(total_points, vector<vector<Point>>(total_points));\n\n    for (int i = 0; i < total_points; i++) {\n        vector<Point> path_to_end = dial_shortest_path(grid_cost, N, P[i], P[i]);\n        for (int j = 0; j < total_points; j++) {\n            if (i == j) {\n                dist_matrix[i][j] = 0;\n                paths[i][j] = {P[i]};\n                continue;\n            }\n            vector<Point> path_ij = dial_shortest_path(grid_cost, N, P[i], P[j]);\n            if (path_ij.empty()) {\n                dist_matrix[i][j] = INF;\n                paths[i][j] = {};\n            } else {\n                int total_cost = 0;\n                Point cur = P[i];\n                for (const Point& p : path_ij) {\n                    total_cost += grid_cost[p.i][p.j];\n                }\n                dist_matrix[i][j] = total_cost;\n                paths[i][j] = path_ij;\n            }\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited(total_points, false);\n    visited[0] = true;\n    tour.push_back(0);\n    int current = 0;\n    for (int step = 1; step < total_points; step++) {\n        int best_next = -1;\n        int best_dist = INF;\n        for (int j = 0; j < total_points; j++) {\n            if (!visited[j] && dist_matrix[current][j] < best_dist) {\n                best_dist = dist_matrix[current][j];\n                best_next = j;\n            }\n        }\n        if (best_next == -1) break;\n        visited[best_next] = true;\n        tour.push_back(best_next);\n        current = best_next;\n    }\n    tour.push_back(0);\n\n    vector<Point> full_route;\n    full_route.push_back(P[0]);\n    for (int idx = 0; idx < tour.size() - 1; idx++) {\n        int i = tour[idx];\n        int j = tour[idx+1];\n        if (i == j) continue;\n        vector<Point>& path_segment = paths[i][j];\n        full_route.insert(full_route.end(), path_segment.begin(), path_segment.end());\n    }\n\n    string moves;\n    for (int i = 0; i < full_route.size() - 1; i++) {\n        Point a = full_route[i];\n        Point b = full_route[i+1];\n        if (b.i < a.i) moves += 'U';\n        else if (b.i > a.i) moves += 'D';\n        else if (b.j < a.j) moves += 'L';\n        else if (b.j > a.j) moves += 'R';\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n#include <cstring>\n#include <sys/select.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(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    vector<vector<int>> prerequisites(N);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        prerequisites[v].push_back(u);\n    }\n\n    vector<int> task_status(N, -1);\n    vector<int> member_status(M, -1);\n    vector<int> start_day(N, 0);\n\n    vector<vector<int>> S(M, vector<int>(K, 0));\n\n    int current_day = 1;\n\n    while (true) {\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        vector<int> tokens;\n        char* cstr = new char[line.length() + 1];\n        strcpy(cstr, line.c_str());\n        char* p = strtok(cstr, \" \");\n        while (p != nullptr) {\n            tokens.push_back(atoi(p));\n            p = strtok(nullptr, \" \");\n        }\n        delete[] cstr;\n\n        int n = tokens[0];\n        vector<int> completed_members;\n        for (int i = 1; i <= n; ++i) {\n            completed_members.push_back(tokens[i]);\n        }\n\n        for (int idx = 0; idx < n; ++idx) {\n            int j0 = completed_members[idx];\n            int j = j0 - 1;\n            if (member_status[j] == -1) {\n                continue;\n            }\n            int task_i = member_status[j];\n            task_status[task_i] = 1;\n            member_status[j] = -1;\n\n            int t_taken = current_day - start_day[task_i];\n\n            if (t_taken == 1) {\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        S[j][k] = d[task_i][k];\n                    }\n                }\n            } else {\n                int current_w = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        current_w += d[task_i][k] - S[j][k];\n                    }\n                }\n\n                if (current_w > t_taken + 3) {\n                    int reduction_needed = current_w - (t_taken + 3);\n                    vector<pair<int, int>> deficits;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task_i][k] > S[j][k]) {\n                            int deficit_k = d[task_i][k] - S[j][k];\n                            deficits.emplace_back(deficit_k, k);\n                        }\n                    }\n                    sort(deficits.begin(), deficits.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                        return a.first > b.first;\n                    });\n                    for (auto& def : deficits) {\n                        if (reduction_needed <= 0) break;\n                        int deficit_k = def.first;\n                        int k = def.second;\n                        int increase = min(deficit_k, reduction_needed);\n                        S[j][k] += increase;\n                        reduction_needed -= increase;\n                    }\n                }\n            }\n        }\n\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] != -1) continue;\n            bool available = true;\n            for (int pre : prerequisites[i]) {\n                if (task_status[pre] != 1) {\n                    available = false;\n                    break;\n                }\n            }\n            if (available) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> free_team_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_status[j] == -1) {\n                free_team_members.push_back(j);\n            }\n        }\n\n        vector<pair<int, int>> assignments;\n        if (!available_tasks.empty() && !free_team_members.empty()) {\n            vector<pair<int, int>> task_list;\n            for (int i : available_tasks) {\n                int min_exp = -1;\n                for (int j : free_team_members) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (min_exp == -1 || exp_time < min_exp) {\n                        min_exp = exp_time;\n                    }\n                }\n                task_list.emplace_back(min_exp, i);\n            }\n\n            sort(task_list.begin(), task_list.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                return a.first > b.first;\n            });\n\n            set<int> free_set(free_team_members.begin(), free_team_members.end());\n            for (auto& p : task_list) {\n                if (free_set.empty()) break;\n                int i = p.second;\n                int best_j = -1;\n                int best_exp = -1;\n                for (int j : free_set) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (best_j == -1 || exp_time < best_exp) {\n                        best_j = j;\n                        best_exp = exp_time;\n                    }\n                }\n                assignments.emplace_back(best_j, i);\n                free_set.erase(best_j);\n            }\n        }\n\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        for (auto& p : assignments) {\n            int j = p.first;\n            int i = p.second;\n            task_status[i] = 0;\n            member_status[j] = i;\n            start_day[i] = current_day;\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <set>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Order {\n    int id;\n    int a, b;  // restaurant\n    int c, d;  // destination\n};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    \n    int manhattan_distance(const Point& other) const {\n        return abs(x - other.x) + abs(y - other.y);\n    }\n};\n\nvector<Order> orders;\nvector<int> selected_orders;\nvector<Point> route;\n\nmt19937 rng;\n\nint calculate_total_distance(const vector<Point>& route) {\n    int total = 0;\n    for (size_t i = 0; i < route.size() - 1; i++) {\n        total += route[i].manhattan_distance(route[i + 1]);\n    }\n    return total;\n}\n\nbool is_valid_route(const vector<int>& selected, const vector<Point>& route) {\n    vector<pair<int, int>> positions(1001, {-1, -1});\n    \n    for (size_t i = 0; i < route.size(); i++) {\n        for (int order_id : selected) {\n            const auto& order = orders[order_id];\n            if (route[i].x == order.a && route[i].y == order.b) {\n                if (positions[order_id].first == -1) {\n                    positions[order_id].first = i;\n                }\n            } else if (route[i].x == order.c && route[i].y == order.d) {\n                if (positions[order_id].second == -1) {\n                    positions[order_id].second = i;\n                }\n            }\n        }\n    }\n    \n    for (int order_id : selected) {\n        if (positions[order_id].first == -1 || positions[order_id].second == -1) {\n            return false;\n        }\n        if (positions[order_id].first >= positions[order_id].second) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nvector<Point> construct_greedy_route(const vector<int>& selected) {\n    vector<Point> route = {Point(400, 400)};\n    set<int> remaining_orders(selected.begin(), selected.end());\n    \n    while (!remaining_orders.empty()) {\n        int best_order = -1;\n        int best_pos = -1;\n        int best_increase = 1e9;\n        \n        for (int order_id : remaining_orders) {\n            const auto& order = orders[order_id];\n            \n            // Try inserting restaurant and destination in all possible positions\n            for (size_t i = 0; i <= route.size(); i++) {\n                for (size_t j = i + 1; j <= route.size(); j++) {\n                    vector<Point> temp_route = route;\n                    temp_route.insert(temp_route.begin() + i, Point(order.a, order.b));\n                    temp_route.insert(temp_route.begin() + j, Point(order.c, order.d));\n                    \n                    int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n                    \n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_order = order_id;\n                        best_pos = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_order == -1) break;\n        \n        const auto& best_order_data = orders[best_order];\n        size_t insert_dest_pos = best_pos + 1;\n        \n        // Find best position for destination\n        for (size_t j = best_pos + 1; j <= route.size(); j++) {\n            vector<Point> temp_route = route;\n            temp_route.insert(temp_route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n            temp_route.insert(temp_route.begin() + j, Point(best_order_data.c, best_order_data.d));\n            \n            int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n            \n            if (increase < best_increase) {\n                best_increase = increase;\n                insert_dest_pos = j;\n            }\n        }\n        \n        route.insert(route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n        route.insert(route.begin() + insert_dest_pos, Point(best_order_data.c, best_order_data.d));\n        remaining_orders.erase(best_order);\n    }\n    \n    route.push_back(Point(400, 400));\n    \n    assert(is_valid_route(selected, route));\n    return route;\n}\n\nvector<int> select_initial_orders() {\n    // Calculate center of mass for all orders\n    double center_x = 0, center_y = 0;\n    for (const auto& order : orders) {\n        center_x += (order.a + order.c) / 2.0;\n        center_y += (order.b + order.d) / 2.0;\n    }\n    center_x /= orders.size();\n    center_y /= orders.size();\n    \n    // Calculate distances from center for each order\n    vector<pair<double, int>> order_distances;\n    for (size_t i = 0; i < orders.size(); i++) {\n        const auto& order = orders[i];\n        double mid_x = (order.a + order.c) / 2.0;\n        double mid_y = (order.b + order.d) / 2.0;\n        double dist = abs(mid_x - center_x) + abs(mid_y - center_y);\n        order_distances.emplace_back(dist, i);\n    }\n    \n    // Sort by distance and select the closest 50\n    sort(order_distances.begin(), order_distances.end());\n    vector<int> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(order_distances[i].second);\n    }\n    \n    return selected;\n}\n\nvector<Point> simulated_annealing(const vector<int>& initial_selected, const vector<Point>& initial_route) {\n    vector<int> current_selected = initial_selected;\n    vector<Point> current_route = initial_route;\n    int current_distance = calculate_total_distance(current_route);\n    \n    vector<int> best_selected = current_selected;\n    vector<Point> best_route = current_route;\n    int best_distance = current_distance;\n    \n    const double initial_temp = 1000.0;\n    const double final_temp = 1.0;\n    const int iterations = 100000;\n    \n    double temp = initial_temp;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        temp = initial_temp * pow(final_temp / initial_temp, (double)iter / iterations);\n        \n        // Choose a random operation\n        int operation = uniform_int_distribution<int>(0, 2)(rng);\n        \n        if (operation == 0) {\n            // Swap two points in the route\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            int j = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            \n            if (i == j) continue;\n            \n            vector<Point> new_route = current_route;\n            swap(new_route[i], new_route[j]);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else if (operation == 1) {\n            // Reverse a segment\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 3)(rng);\n            int j = uniform_int_distribution<int>(i + 1, current_route.size() - 2)(rng);\n            \n            vector<Point> new_route = current_route;\n            reverse(new_route.begin() + i, new_route.begin() + j + 1);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else {\n            // Swap an order in the selected set with one not in the set\n            vector<int> unselected;\n            for (size_t i = 0; i < orders.size(); i++) {\n                if (find(current_selected.begin(), current_selected.end(), i) == current_selected.end()) {\n                    unselected.push_back(i);\n                }\n            }\n            \n            if (unselected.empty()) continue;\n            \n            int idx_to_remove = uniform_int_distribution<int>(0, current_selected.size() - 1)(rng);\n            int idx_to_add = uniform_int_distribution<int>(0, unselected.size() - 1)(rng);\n            \n            vector<int> new_selected = current_selected;\n            new_selected[idx_to_remove] = unselected[idx_to_add];\n            sort(new_selected.begin(), new_selected.end());\n            \n            vector<Point> new_route = construct_greedy_route(new_selected);\n            int new_distance = calculate_total_distance(new_route);\n            int delta = new_distance - current_distance;\n            \n            if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_selected = new_selected;\n                current_route = new_route;\n                current_distance = new_distance;\n                \n                if (current_distance < best_distance) {\n                    best_selected = current_selected;\n                    best_route = current_route;\n                    best_distance = current_distance;\n                }\n            }\n        }\n    }\n    \n    return best_route;\n}\n\nvoid solve() {\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n    \n    // Initialize random number generator\n    rng = mt19937(high_resolution_clock::now().time_since_epoch().count());\n    \n    // Select initial orders\n    selected_orders = select_initial_orders();\n    \n    // Construct initial route\n    route = construct_greedy_route(selected_orders);\n    \n    // Optimize with simulated annealing\n    route = simulated_annealing(selected_orders, route);\n    \n    // Output the result\n    cout << selected_orders.size();\n    for (int order_id : selected_orders) {\n        cout << \" \" << order_id + 1;  // Convert to 1-based indexing\n    }\n    cout << endl;\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << endl;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\nusing namespace std;\n\nclass DSU {\nprivate:\n    vector<int> parent;\n    vector<int> rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n\n    void union_set(int x, int y) {\n        int rx = find(x);\n        int ry = find(y);\n        if (rx == ry) {\n            return;\n        }\n        if (rank[rx] < rank[ry]) {\n            parent[rx] = ry;\n        } else if (rank[rx] > rank[ry]) {\n            parent[ry] = rx;\n        } else {\n            parent[ry] = rx;\n            rank[rx]++;\n        }\n    }\n};\n\nstruct Edge {\n    int u, v;\n    double d;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N = 400;\n    int M = 1995;\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        edges[i].index = i;\n        int u = edges[i].u, v = edges[i].v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        edges[i].d = round(dist);\n    }\n\n    vector<int> tree_id(M, -1);\n    vector<Edge> remaining_edges = edges;\n    for (int t = 0; t < 5; t++) {\n        sort(remaining_edges.begin(), remaining_edges.end(), [](const Edge& a, const Edge& b) {\n            return a.d < b.d;\n        });\n\n        DSU dsu_temp(N);\n        vector<Edge> tree_edges;\n        vector<Edge> new_remaining;\n\n        for (Edge& e : remaining_edges) {\n            int u = e.u, v = e.v;\n            if (dsu_temp.find(u) != dsu_temp.find(v)) {\n                dsu_temp.union_set(u, v);\n                tree_edges.push_back(e);\n                tree_id[e.index] = t+1;\n            } else {\n                new_remaining.push_back(e);\n            }\n        }\n\n        remaining_edges = new_remaining;\n    }\n\n    DSU dsu_online(N);\n    vector<vector<int>> comp_edge_count(N, vector<int>(N, 0));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].u, v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n        if (a != b) {\n            comp_edge_count[a][b]++;\n            comp_edge_count[b][a]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n\n        if (a != b) {\n            comp_edge_count[a][b]--;\n            comp_edge_count[b][a]--;\n        }\n\n        if (a == b) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n\n        if (comp_edge_count[a][b] == 0) {\n            dsu_online.union_set(u, v);\n            int root_a = dsu_online.find(u);\n            int root_b = dsu_online.find(v);\n            for (int c = 0; c < N; c++) {\n                if (c == root_a) continue;\n                if (comp_edge_count[root_b][c] > 0) {\n                    comp_edge_count[root_a][c] += comp_edge_count[root_b][c];\n                    comp_edge_count[c][root_a] += comp_edge_count[c][root_b];\n                    comp_edge_count[root_b][c] = 0;\n                    comp_edge_count[c][root_b] = 0;\n                }\n            }\n            comp_edge_count[root_a][root_b] = 0;\n            comp_edge_count[root_b][root_a] = 0;\n\n            cout << 1 << endl;\n            cout.flush();\n        } else {\n            double progress = static_cast<double>(i) / M;\n            double base_threshold = 1.0;\n            double max_threshold = 3.0;\n            double factor = (6.0 - tree_id[i]) / 5.0;\n            double threshold = base_threshold + progress * (max_threshold - base_threshold) * factor;\n\n            if (l_i <= threshold * edges[i].d) {\n                dsu_online.union_set(u, v);\n                int root_a = dsu_online.find(u);\n                int root_b = dsu_online.find(v);\n                for (int c = 0; c < N; c++) {\n                    if (c == root_a) continue;\n                    if (comp_edge_count[root_b][c] > 0) {\n                        comp_edge_count[root_a][c] += comp_edge_count[root_b][c];\n                        comp_edge_count[c][root_a] += comp_edge_count[c][root_b];\n                        comp_edge_count[root_b][c] = 0;\n                        comp_edge_count[c][root_b] = 0;\n                    }\n                }\n                comp_edge_count[root_a][root_b] = 0;\n                comp_edge_count[root_b][root_a] = 0;\n\n                cout << 1 << endl;\n                cout.flush();\n            } else {\n                cout << 0 << endl;\n                cout.flush();\n            }\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\n#include <cstring>\n#include <iomanip>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\n\nstruct Position {\n    int x, y;\n    Position(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Position& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nbool adjacent(const Position& a, const Position& b) {\n    return (abs(a.x - b.x) + abs(a.y - b.y) == 1);\n}\n\nbool is_buildable(int x, int y, const vector<Position>& pets, const vector<Position>& humans) {\n    for (const auto& pet : pets) {\n        if (pet.x == x && pet.y == y) {\n            return false;\n        }\n    }\n    for (const auto& human : humans) {\n        if (human.x == x && human.y == y) {\n            return false;\n        }\n    }\n\n    vector<pair<int,int>> adj = {{x-1,y}, {x+1,y}, {x,y-1}, {x,y+1}};\n    for (const auto& [ax, ay] : adj) {\n        if (ax < 1 || ax > 30 || ay < 1 || ay > 30) {\n            continue;\n        }\n        for (const auto& pet : pets) {\n            if (pet.x == ax && pet.y == ay) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nbool is_safe_to_move(int x, int y, bool grid[31][31], const set<Position>& building_set) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) {\n        return false;\n    }\n    if (!grid[x][y]) {\n        return false;\n    }\n    if (building_set.find(Position(x,y)) != building_set.end()) {\n        return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M;\n    cin >> N;\n    vector<Position> pets(N);\n    vector<int> pet_types(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n    }\n    cin >> M;\n    vector<Position> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n\n    bool grid[31][31];\n    for (int i = 1; i <= 30; i++) {\n        for (int j = 1; j <= 30; j++) {\n            grid[i][j] = true;\n        }\n    }\n\n    vector<Position> perimeter;\n    for (int y = 10; y <= 20; y++) {\n        perimeter.push_back(Position(10, y));\n    }\n    for (int x = 11; x <= 20; x++) {\n        perimeter.push_back(Position(x, 20));\n    }\n    for (int y = 19; y >= 10; y--) {\n        perimeter.push_back(Position(20, y));\n    }\n    for (int x = 19; x >= 11; x--) {\n        perimeter.push_back(Position(x, 10));\n    }\n\n    vector<queue<Position>> human_queues(M);\n    int segment_size = perimeter.size() / M;\n    int extra = perimeter.size() % M;\n    int index = 0;\n    for (int i = 0; i < M; i++) {\n        int size = segment_size + (i < extra ? 1 : 0);\n        for (int j = 0; j < size; j++) {\n            human_queues[i].push(perimeter[index++]);\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n\n        if (turn < 20) {\n            for (int i = 0; i < M; i++) {\n                int x = humans[i].x;\n                int y = humans[i].y;\n                if (x >= 10 && x <= 20 && y >= 10 && y <= 20) {\n                    actions[i] = '.';\n                } else {\n                    int dx = 15 - x;\n                    int dy = 15 - y;\n                    if (abs(dx) > abs(dy)) {\n                        actions[i] = (dx > 0) ? 'D' : 'U';\n                    } else {\n                        actions[i] = (dy > 0) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            set<Position> building_set;\n            vector<bool> will_build(M, false);\n\n            for (int i = 0; i < M; i++) {\n                if (human_queues[i].empty()) continue;\n                Position target = human_queues[i].front();\n                if (adjacent(humans[i], target) && is_buildable(target.x, target.y, pets, humans)) {\n                    building_set.insert(target);\n                    will_build[i] = true;\n                }\n            }\n\n            for (int i = 0; i < M; i++) {\n                if (will_build[i]) {\n                    Position target = human_queues[i].front();\n                    int dx = humans[i].x - target.x;\n                    int dy = humans[i].y - target.y;\n                    if (dx == -1) actions[i] = 'd';\n                    else if (dx == 1) actions[i] = 'u';\n                    else if (dy == -1) actions[i] = 'r';\n                    else if (dy == 1) actions[i] = 'l';\n                    human_queues[i].pop();\n                } else {\n                    if (human_queues[i].empty()) {\n                        actions[i] = '.';\n                    } else {\n                        Position target = human_queues[i].front();\n                        if (adjacent(humans[i], target)) {\n                            human_queues[i].pop();\n                            human_queues[i].push(target);\n                            actions[i] = '.';\n                        } else {\n                            vector<pair<int,int>> move_deltas = {{-1,0},{1,0},{0,-1},{0,1}};\n                            vector<char> move_dirs = {'U','D','L','R'};\n                            char best_move = '.';\n                            int best_dist = 1000000;\n                            for (int j = 0; j < 4; j++) {\n                                int nx = humans[i].x + move_deltas[j].first;\n                                int ny = humans[i].y + move_deltas[j].second;\n                                if (!is_safe_to_move(nx, ny, grid, building_set)) {\n                                    continue;\n                                }\n                                int d = abs(nx - target.x) + abs(ny - target.y);\n                                if (d < best_dist) {\n                                    best_dist = d;\n                                    best_move = move_dirs[j];\n                                }\n                            }\n                            actions[i] = best_move;\n                        }\n                    }\n                }\n            }\n\n            for (const auto& pos : building_set) {\n                grid[pos.x][pos.y] = false;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == '.') break;\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    string path;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\"});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            break;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj]});\n            }\n        }\n    }\n    \n    string shortest_path = paths[ti][tj];\n    if (shortest_path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    int L = shortest_path.size();\n    int r = 1;\n    const double threshold = 0.95;\n    while (r <= 200) {\n        double prob = 1.0 - pow(p, r);\n        if (prob >= threshold) {\n            break;\n        }\n        r++;\n    }\n    \n    if (r > 200 / L) {\n        r = 200 / L;\n    }\n    if (r < 1) {\n        r = 1;\n    }\n    \n    string robust_path;\n    for (char c : shortest_path) {\n        robust_path += string(r, c);\n    }\n    \n    cout << robust_path << endl;\n    \n    return 0;\n}","ahc010":"","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <unordered_set>\n#include <tuple>\n#include <cmath>\n#include <climits>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nconst int dx[] = {0, 0, -1, 1};\nconst int dy[] = {-1, 1, 0, 0};\nconst char dir_char[] = {'L', 'R', 'U', 'D'};\n\nstruct State {\n    vector<vector<int>> board;\n    int empty_x, empty_y;\n    int last_move;\n    int connections;\n    int max_component;\n    string moves;\n};\n\nbool are_connected(int tile1, int tile2, int direction) {\n    if (direction == 0) return (tile1 & 1) && (tile2 & 4);\n    if (direction == 1) return (tile1 & 4) && (tile2 & 1);\n    if (direction == 2) return (tile1 & 2) && (tile2 & 8);\n    if (direction == 3) return (tile1 & 8) && (tile2 & 2);\n    return false;\n}\n\nint count_connections_full(const vector<vector<int>>& board, int N) {\n    int connections = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            if (i < N - 1 && board[i+1][j] != 0) {\n                if (are_connected(tile, board[i+1][j], 3)) {\n                    connections++;\n                }\n            }\n            if (j < N - 1 && board[i][j+1] != 0) {\n                if (are_connected(tile, board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint compute_components(vector<vector<int>>& board, int N) {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_comp = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int comp_size = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                comp_size++;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d];\n                    int ny = y + dy[d];\n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && board[nx][ny] != 0) {\n                        if (are_connected(board[x][y], board[nx][ny], d)) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            max_comp = max(max_comp, comp_size);\n        }\n    }\n    return max_comp;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(0));\n\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int empty_x = -1, empty_y = -1;\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            if (c == '0') {\n                initial_board[i][j] = 0;\n                empty_x = i;\n                empty_y = j;\n            } else {\n                if (c >= '0' && c <= '9') {\n                    initial_board[i][j] = c - '0';\n                } else {\n                    initial_board[i][j] = 10 + (c - 'a');\n                }\n            }\n        }\n    }\n\n    vector<State> best_states;\n    int num_iterations = 2;\n    double gamma = 1.0;\n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        State current;\n        current.board = initial_board;\n        current.empty_x = empty_x;\n        current.empty_y = empty_y;\n        current.last_move = -1;\n        current.connections = count_connections_full(current.board, N);\n        current.max_component = compute_components(current.board, N);\n        current.moves = \"\";\n\n        for (int step = 0; step < T; ++step) {\n            if (step % 10 == 0) {\n                current.max_component = compute_components(current.board, N);\n                if (current.max_component == N * N - 1) {\n                    break;\n                }\n            }\n\n            int best_delta = -1000000;\n            int best_move = -1;\n            int best_new_connections = -1;\n\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == (current.last_move ^ 1)) continue;\n\n                int nx = current.empty_x + dx[dir];\n                int ny = current.empty_y + dy[dir];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n\n                int new_connections = current.connections;\n                int tile = current.board[nx][ny];\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = nx + dx[d];\n                    int y = ny + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections--;\n                        }\n                    }\n                }\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = current.empty_x + dx[d];\n                    int y = current.empty_y + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (x == nx && y == ny) continue;\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections++;\n                        }\n                    }\n                }\n\n                double delta = new_connections - current.connections;\n                delta += gamma * (current.max_component * 0.01);\n                delta += (rand() % 100) * 0.001;\n\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_move = dir;\n                    best_new_connections = new_connections;\n                }\n            }\n\n            if (best_move == -1) break;\n\n            int nx = current.empty_x + dx[best_move];\n            int ny = current.empty_y + dy[best_move];\n            swap(current.board[current.empty_x][current.empty_y], current.board[nx][ny]);\n            current.empty_x = nx;\n            current.empty_y = ny;\n            current.connections = best_new_connections;\n            current.moves += dir_char[best_move];\n            current.last_move = best_move;\n        }\n\n        current.max_component = compute_components(current.board, N);\n        best_states.push_back(current);\n    }\n\n    sort(best_states.begin(), best_states.end(), [](const State& a, const State& b) {\n        if (a.max_component != b.max_component) {\n            return a.max_component > b.max_component;\n        }\n        return a.moves.size() < b.moves.size();\n    });\n\n    cout << best_states[0].moves << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <set>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nusing Point = pair<long long, long long>;\nusing Line = pair<Point, Point>;\n\nconst long long RADIUS = 10000;\nconst long long RADIUS_SQ = 100000000;\n\nstruct Solution {\n    vector<Line> lines;\n    double score;\n};\n\nlong long cross(const Point& O, const Point& A, const Point& B) {\n    return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);\n}\n\nlong long side(const Line& line, const Point& P) {\n    const Point& A = line.first;\n    const Point& B = line.second;\n    return cross(A, B, P);\n}\n\nbool is_inside_circle(const Point& p) {\n    return p.first * p.first + p.second * p.second < RADIUS_SQ;\n}\n\ndouble calculate_score(const vector<int>& a, const vector<int>& b) {\n    int total_distributed = 0;\n    int total_attendees = 0;\n    \n    for (int d = 1; d <= 10; d++) {\n        total_distributed += min(a[d-1], b[d-1]);\n        total_attendees += a[d-1];\n    }\n    \n    return 1000000.0 * total_distributed / total_attendees;\n}\n\nvector<int> count_strawberries(const vector<Point>& strawberries, const vector<Line>& lines) {\n    if (lines.empty()) {\n        return {static_cast<int>(strawberries.size())};\n    }\n    \n    unordered_map<string, int> region_counts;\n    \n    for (const auto& strawberry : strawberries) {\n        string signature;\n        bool on_line = false;\n        \n        for (const auto& line : lines) {\n            long long s = side(line, strawberry);\n            if (s == 0) {\n                on_line = true;\n                break;\n            }\n            signature += (s > 0) ? '1' : '0';\n        }\n        \n        if (!on_line) {\n            region_counts[signature]++;\n        }\n    }\n    \n    vector<int> distribution(10, 0);\n    for (const auto& [_, count] : region_counts) {\n        if (count >= 1 && count <= 10) {\n            distribution[count-1]++;\n        }\n    }\n    \n    return distribution;\n}\n\nvector<Line> generate_candidate_lines(const vector<Point>& strawberries, mt19937& rng, int num_candidates = 20) {\n    vector<Line> candidates;\n    int n = strawberries.size();\n    \n    // Random lines through two strawberries\n    for (int i = 0; i < num_candidates / 2 && i < n * n / 2; i++) {\n        int idx1 = rng() % n;\n        int idx2 = rng() % n;\n        if (idx1 != idx2) {\n            candidates.push_back({strawberries[idx1], strawberries[idx2]});\n        }\n    }\n    \n    // Random lines in random directions\n    uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n    for (int i = 0; i < num_candidates / 2; i++) {\n        Point p1 = {coord_dist(rng), coord_dist(rng)};\n        Point p2 = {coord_dist(rng), coord_dist(rng)};\n        candidates.push_back({p1, p2});\n    }\n    \n    return candidates;\n}\n\nSolution solve(int N, int K, const vector<int>& a, const vector<Point>& strawberries) {\n    mt19937 rng(12345);\n    \n    Solution best_solution;\n    best_solution.lines = {};\n    vector<int> initial_dist = count_strawberries(strawberries, {});\n    best_solution.score = calculate_score(a, initial_dist);\n    \n    vector<Line> current_lines;\n    double current_score = best_solution.score;\n    \n    int no_improve_count = 0;\n    int max_no_improve = 5; // Stop after 5 consecutive non-improving iterations\n    \n    for (int iter = 0; iter < min(K, 50); iter++) { // Limit to 50 iterations\n        vector<Line> candidates = generate_candidate_lines(strawberries, rng);\n        \n        Line best_line;\n        double best_score = current_score;\n        bool improved = false;\n        \n        for (const auto& line : candidates) {\n            vector<Line> new_lines = current_lines;\n            new_lines.push_back(line);\n            \n            vector<int> distribution = count_strawberries(strawberries, new_lines);\n            double score = calculate_score(a, distribution);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = line;\n                improved = true;\n            }\n        }\n        \n        if (improved) {\n            current_lines.push_back(best_line);\n            current_score = best_score;\n            no_improve_count = 0;\n            \n            if (current_score > best_solution.score) {\n                best_solution.lines = current_lines;\n                best_solution.score = current_score;\n            }\n        } else {\n            no_improve_count++;\n            if (no_improve_count >= max_no_improve) {\n                break;\n            }\n            // Add a random line anyway to continue exploring\n            uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n            Point p1 = {coord_dist(rng), coord_dist(rng)};\n            Point p2 = {coord_dist(rng), coord_dist(rng)};\n            current_lines.push_back({p1, p2});\n        }\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(10);\n    for (int i = 0; i < 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].first >> strawberries[i].second;\n    }\n    \n    Solution solution = solve(N, K, a, strawberries);\n    \n    cout << solution.lines.size() << \"\\n\";\n    for (const auto& line : solution.lines) {\n        cout << line.first.first << \" \" << line.first.second << \" \"\n             << line.second.first << \" \" << line.second.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    int c = (N - 1) / 2;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> col_dots(N);\n    vector<set<int>> row_dots(N);\n    set<tuple<int, int, int, int>> segments;\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    while (true) {\n        vector<pair<int, int>> non_dot_points;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    non_dot_points.emplace_back(x, y);\n                }\n            }\n        }\n\n        if (non_dot_points.empty()) {\n            break;\n        }\n\n        sort(non_dot_points.begin(), non_dot_points.end(), \n            [c](const pair<int, int>& a, const pair<int, int>& b) {\n                int wa = (a.first - c) * (a.first - c) + (a.second - c) * (a.second - c) + 1;\n                int wb = (b.first - c) * (b.first - c) + (b.second - c) * (b.second - c) + 1;\n                return wa > wb;\n            });\n\n        tuple<int, int, int, int, int, int, int, int> best_op;\n        vector<tuple<int, int, int, int>> best_segments_list;\n        int best_weight = -1;\n        bool found = false;\n\n        for (auto [x, y] : non_dot_points) {\n            int weight = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n            bool found_axis = false;\n            for (int x2 = 0; x2 < N; x2++) {\n                if (x2 == x) continue;\n                if (!grid[x2][y]) continue;\n\n                if (col_dots[x].size() <= col_dots[x2].size()) {\n                    for (int y2 : col_dots[x]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x2].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                } else {\n                    for (int y2 : col_dots[x2]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                }\n            }\n\n            bool found_diamond = false;\n            for (int role = 0; role < 4; role++) {\n                int max_a;\n                if (role == 0) {\n                    max_a = min({(N - 1 - x) / 2, (N - 1 - y), y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x + a;\n                        int cy = y;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + 2 * a - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + i;\n                            int x2 = x + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a + i;\n                            int y1 = y + a - i;\n                            int x2 = x + a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + 2 * a - i;\n                            int y1 = y - i;\n                            int x2 = x + 2 * a - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a + i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 1) {\n                    max_a = min({x, N - 1 - x, y / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y - a;\n                        int Ax = cx - a, Ay = cy;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - 2 * a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y - i;\n                            int x2 = x + i + 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - 2 * a + i;\n                            int x2 = x - i - 1;\n                            int y2 = y - 2 * a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y - a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Dx, Dy, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 2) {\n                    max_a = min({x / 2, y, N - 1 - y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x - a;\n                        int cy = y;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - 2 * a + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - i;\n                            int x2 = x - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a - i;\n                            int y1 = y - a + i;\n                            int x2 = x - a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - 2 * a + i;\n                            int y1 = y + i;\n                            int x2 = x - 2 * a + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a - i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Ax, Ay, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 3) {\n                    max_a = min({x, N - 1 - x, (N - 1 - y) / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y + a;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + 2 * a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y + i;\n                            int x2 = x - i - 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + 2 * a - i;\n                            int x2 = x + i + 1;\n                            int y2 = y + 2 * a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y + a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                }\n            }\n        }\n\n        if (!found) {\n            break;\n        }\n\n        auto [x, y, x1, y1, x2, y2, x3, y3] = best_op;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n        for (auto& seg : best_segments_list) {\n            segments.insert(seg);\n        }\n        operations.push_back(best_op);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        auto [x, y, x1, y1, x2, y2, x3, y3] = op;\n        cout << x << \" \" << y << \" \" << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \" \" << x3 << \" \" << y3 << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> cells;\n    int rows, cols;\n    \n    Grid(int r = 10, int c = 10) : rows(r), cols(c), cells(r, vector<int>(c, 0)) {}\n    \n    bool is_valid(int r, int c) const {\n        return r >= 0 && r < rows && c >= 0 && c < cols;\n    }\n    \n    int get_empty_count() const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) count++;\n            }\n        }\n        return count;\n    }\n    \n    pair<int, int> get_nth_empty(int n) const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) {\n                    count++;\n                    if (count == n) return {r, c};\n                }\n            }\n        }\n        return {-1, -1}; // Should not happen\n    }\n    \n    void tilt(char direction) {\n        if (direction == 'F') { // Forward (up)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = 0;\n                for (int r = 0; r < rows; ++r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'B') { // Backward (down)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = rows - 1;\n                for (int r = rows - 1; r >= 0; --r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        } else if (direction == 'L') { // Left\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = 0;\n                for (int c = 0; c < cols; ++c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'R') { // Right\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = cols - 1;\n                for (int c = cols - 1; c >= 0; --c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    void place(int r, int c, int flavor) {\n        cells[r][c] = flavor;\n    }\n    \n    double calculate_score() const {\n        vector<bool> visited(rows * cols, false);\n        vector<int> component_sizes;\n        \n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0 && !visited[r * cols + c]) {\n                    int flavor = cells[r][c];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    visited[r * cols + c] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int dr = -1; dr <= 1; ++dr) {\n                            for (int dc = -1; dc <= 1; ++dc) {\n                                if (abs(dr) + abs(dc) != 1) continue;\n                                int nr = cr + dr;\n                                int nc = cc + dc;\n                                if (is_valid(nr, nc) && cells[nr][nc] == flavor && \n                                    !visited[nr * cols + nc]) {\n                                    visited[nr * cols + nc] = true;\n                                    q.push({nr, nc});\n                                }\n                            }\n                        }\n                    }\n                    \n                    component_sizes.push_back(size);\n                }\n            }\n        }\n        \n        double sum_squares = 0;\n        for (int size : component_sizes) {\n            sum_squares += size * size;\n        }\n        \n        array<int, 4> flavor_counts = {0, 0, 0, 0};\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0) {\n                    flavor_counts[cells[r][c]]++;\n                }\n            }\n        }\n        \n        double denominator = 0;\n        for (int i = 1; i <= 3; ++i) {\n            denominator += flavor_counts[i] * flavor_counts[i];\n        }\n        \n        return sum_squares / denominator;\n    }\n    \n    pair<int, int> get_tilted_position(int r, int c, char direction) const {\n        if (direction == 'F') { // Forward (up)\n            while (r > 0 && cells[r - 1][c] == 0) {\n                r--;\n            }\n        } else if (direction == 'B') { // Backward (down)\n            while (r < rows - 1 && cells[r + 1][c] == 0) {\n                r++;\n            }\n        } else if (direction == 'L') { // Left\n            while (c > 0 && cells[r][c - 1] == 0) {\n                c--;\n            }\n        } else if (direction == 'R') { // Right\n            while (c < cols - 1 && cells[r][c + 1] == 0) {\n                c++;\n            }\n        }\n        return {r, c};\n    }\n    \n    int count_same_flavor_neighbors(int r, int c, int flavor) const {\n        int count = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n    \n    bool would_break_cluster(int r, int c, int flavor, char direction) const {\n        // Check if tilting would disconnect this candy from its current cluster\n        int neighbors = count_same_flavor_neighbors(r, c, flavor);\n        if (neighbors <= 1) return false; // Can't break a cluster if already isolated or only one neighbor\n        \n        // Simulate the tilt and check if it disconnects the candy\n        auto [new_r, new_c] = get_tilted_position(r, c, direction);\n        if (new_r == r && new_c == c) return false; // No movement\n        \n        // After movement, check if it still has neighbors\n        int new_neighbors = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = new_r + dr;\n                int nc = new_c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    // Check if this neighbor would also move to a position adjacent to the candy\n                    auto [neighbor_new_r, neighbor_new_c] = get_tilted_position(nr, nc, direction);\n                    if (abs(neighbor_new_r - new_r) + abs(neighbor_new_c - new_c) == 1) {\n                        new_neighbors++;\n                    }\n                }\n            }\n        }\n        \n        return new_neighbors == 0;\n    }\n    \n    int count_flavor_in_area(int r, int c, int flavor, int radius) const {\n        int count = 0;\n        for (int dr = -radius; dr <= radius; ++dr) {\n            for (int dc = -radius; dc <= radius; ++dc) {\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nclass CandyClustering {\nprivate:\n    Grid grid;\n    vector<int> flavors;\n    array<int, 4> flavor_counts = {0, 0, 0, 0};\n    vector<pair<int, int>> flavor_region_centers; // Fixed centers based on regions\n    vector<pair<int, int>> flavor_centers; // Dynamic centers of mass\n    vector<vector<int>> flavor_regions; // Which region each cell belongs to\n    \npublic:\n    CandyClustering(const vector<int>& f) : flavors(f) {\n        // Count flavors\n        for (int f : flavors) {\n            flavor_counts[f]++;\n        }\n        \n        // Initialize regions and centers\n        initialize_flavor_regions();\n        initialize_flavor_centers();\n    }\n    \n    void initialize_flavor_regions() {\n        flavor_regions.assign(grid.rows, vector<int>(grid.cols, 0));\n        \n        // Sort flavors by count (descending)\n        vector<pair<int, int>> sorted_flavors;\n        for (int i = 1; i <= 3; ++i) {\n            sorted_flavors.emplace_back(flavor_counts[i], i);\n        }\n        sort(sorted_flavors.rbegin(), sorted_flavors.rend());\n        \n        // Assign regions proportional to flavor counts\n        int total = grid.rows * grid.cols;\n        int assigned = 0;\n        \n        for (auto [count, flavor] : sorted_flavors) {\n            if (count == 0) continue;\n            \n            // Calculate how many cells this flavor should get\n            int cells_needed = round(static_cast<double>(count) / 100 * total);\n            \n            // Assign contiguous blocks\n            int rows_needed = (cells_needed + grid.cols - 1) / grid.cols;\n            \n            // Start from the top-left and assign rows\n            for (int r = assigned / grid.cols; r < grid.rows && rows_needed > 0; ++r) {\n                for (int c = 0; c < grid.cols; ++c) {\n                    if (flavor_regions[r][c] == 0) {\n                        flavor_regions[r][c] = flavor;\n                        cells_needed--;\n                        if (cells_needed <= 0) break;\n                    }\n                }\n                if (cells_needed <= 0) break;\n                rows_needed--;\n            }\n            \n            assigned += count;\n        }\n    }\n    \n    void initialize_flavor_centers() {\n        flavor_region_centers.resize(4);\n        flavor_centers.resize(4);\n        \n        // Calculate the center of each flavor's region\n        array<vector<pair<int, int>>, 4> region_positions;\n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (flavor_regions[r][c] != 0) {\n                    region_positions[flavor_regions[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!region_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : region_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_region_centers[f] = {sum_r / region_positions[f].size(), \n                                          sum_c / region_positions[f].size()};\n                flavor_centers[f] = flavor_region_centers[f];\n            }\n        }\n    }\n    \n    char decide_direction(int step, int pos) {\n        auto [r, c] = grid.get_nth_empty(pos);\n        int flavor = flavors[step - 1];\n        grid.place(r, c, flavor);\n        \n        if (step == 100) return ' ';\n        \n        // Update centers more frequently\n        if (step % 5 == 0) {\n            update_flavor_centers();\n        }\n        \n        char best_dir = 'F';\n        double best_score = -1e9;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid temp_grid = grid;\n            temp_grid.tilt(dir);\n            \n            double score = calculate_direction_score(temp_grid, flavor, r, c, dir, step);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        grid.tilt(best_dir);\n        return best_dir;\n    }\n    \n    void update_flavor_centers() {\n        array<vector<pair<int, int>>, 4> flavor_positions;\n        \n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (grid.cells[r][c] != 0) {\n                    flavor_positions[grid.cells[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!flavor_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : flavor_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_centers[f] = {sum_r / flavor_positions[f].size(), \n                                     sum_c / flavor_positions[f].size()};\n            }\n        }\n    }\n    \n    double calculate_direction_score(const Grid& g, int flavor, int r, int c, char dir, int step) {\n        double score = 0;\n        \n        // Get new position after tilting\n        auto [new_r, new_c] = g.get_tilted_position(r, c, dir);\n        \n        // Distance to dynamic center (center of mass)\n        auto center = flavor_centers[flavor];\n        double distance_before = sqrt(pow(r - center.first, 2) + pow(c - center.second, 2));\n        double distance_after = sqrt(pow(new_r - center.first, 2) + pow(new_c - center.second, 2));\n        score += (distance_before - distance_after) * 15;\n        \n        // Distance to fixed region center\n        auto region_center = flavor_region_centers[flavor];\n        double region_distance_before = sqrt(pow(r - region_center.first, 2) + pow(c - region_center.second, 2));\n        double region_distance_after = sqrt(pow(new_r - region_center.first, 2) + pow(new_c - region_center.second, 2));\n        score += (region_distance_before - region_distance_after) * 5;\n        \n        // Same-flavor neighbors\n        int same_flavor_neighbors = g.count_same_flavor_neighbors(new_r, new_c, flavor);\n        score += same_flavor_neighbors * 100;\n        \n        // Density of same flavor in the area\n        int density = g.count_flavor_in_area(new_r, new_c, flavor, 2);\n        score += density * 10;\n        \n        // Penalty for isolation\n        if (same_flavor_neighbors == 0) {\n            score -= 30;\n        }\n        \n        // Penalty for breaking clusters\n        if (grid.would_break_cluster(r, c, flavor, dir)) {\n            score -= 50;\n        }\n        \n        // Stage-specific scoring\n        if (step < 30) {\n            // Early stage: prioritize moving to region\n            score += (region_distance_before - region_distance_after) * 10;\n        } else if (step < 70) {\n            // Middle stage: balance between region and clustering\n            score += (distance_before - distance_after) * 10;\n        } else {\n            // Late stage: prioritize clustering and overall score\n            double current_score = grid.calculate_score();\n            double new_score = g.calculate_score();\n            score += (new_score - current_score) * 5000;\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n    \n    CandyClustering solver(flavors);\n    \n    for (int t = 1; t <= 100; ++t) {\n        int pos;\n        cin >> pos;\n        \n        char direction = solver.decide_direction(t, pos);\n        \n        if (t < 100) {\n            cout << direction << endl;\n            cout.flush();\n        }\n    }\n    \n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n#include <utility>\n#include <iomanip>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    int N;\n    if (M <= 98) {\n        N = M + 1;\n    } else {\n        N = 100;\n    }\n\n    vector<vector<double>> expected_seqs(M);\n    if (M <= 98) {\n        for (int k = 0; k < M; k++) {\n            int c = k + 2;\n            vector<double> exp_deg(N);\n            double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n            double exp_iso = eps * (N - 1);\n            for (int i = 0; i < N - c; i++) {\n                exp_deg[i] = exp_iso;\n            }\n            for (int i = N - c; i < N; i++) {\n                exp_deg[i] = exp_clique;\n            }\n            sort(exp_deg.begin(), exp_deg.end());\n            expected_seqs[k] = exp_deg;\n        }\n    } else {\n        if (M == 99) {\n            for (int k = 0; k < 99; k++) {\n                int c = k + 2;\n                vector<double> exp_deg(N);\n                double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n                double exp_iso = eps * (N - 1);\n                for (int i = 0; i < N - c; i++) {\n                    exp_deg[i] = exp_iso;\n                }\n                for (int i = N - c; i < N; i++) {\n                    exp_deg[i] = exp_clique;\n                }\n                sort(exp_deg.begin(), exp_deg.end());\n                expected_seqs[k] = exp_deg;\n            }\n        } else {\n            for (int k = 0; k < 99; k++) {\n                int c = k + 2;\n                vector<double> exp_deg(N);\n                double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n                double exp_iso = eps * (N - 1);\n                for (int i = 0; i < N - c; i++) {\n                    exp_deg[i] = exp_iso;\n                }\n                for (int i = N - c; i < N; i++) {\n                    exp_deg[i] = exp_clique;\n                }\n                sort(exp_deg.begin(), exp_deg.end());\n                expected_seqs[k] = exp_deg;\n            }\n            vector<double> exp_deg(N);\n            exp_deg[0] = 99 * (1 - eps);\n            for (int i = 1; i < N; i++) {\n                exp_deg[i] = 1 + 97 * eps;\n            }\n            sort(exp_deg.begin(), exp_deg.end());\n            expected_seqs[99] = exp_deg;\n        }\n    }\n\n    cout << N << endl;\n    if (M <= 98) {\n        for (int k = 0; k < M; k++) {\n            int c = k + 2;\n            string s;\n            s.reserve(N * (N - 1) / 2);\n            for (int i = 0; i < N; i++) {\n                for (int j = i + 1; j < N; j++) {\n                    if (i < c && j < c) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n            cout << s << endl;\n        }\n    } else {\n        if (M == 99) {\n            for (int k = 0; k < 99; k++) {\n                int c = k + 2;\n                string s;\n                s.reserve(N * (N - 1) / 2);\n                for (int i = 0; i < N; i++) {\n                    for (int j = i + 1; j < N; j++) {\n                        if (i < c && j < c) {\n                            s += '1';\n                        } else {\n                            s += '0';\n                        }\n                    }\n                }\n                cout << s << endl;\n            }\n        } else {\n            for (int k = 0; k < 99; k++) {\n                int c = k + 2;\n                string s;\n                s.reserve(N * (N - 1) / 2);\n                for (int i = 0; i < N; i++) {\n                    for (int j = i + 1; j < N; j++) {\n                        if (i < c && j < c) {\n                            s += '1';\n                        } else {\n                            s += '0';\n                        }\n                    }\n                }\n                cout << s << endl;\n            }\n            string s;\n            s.reserve(N * (N - 1) / 2);\n            for (int i = 0; i < N; i++) {\n                for (int j = i + 1; j < N; j++) {\n                    if (i == 0) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n            cout << s << endl;\n        }\n    }\n    cout.flush();\n\n    for (int q = 0; q < 100; q++) {\n        string H;\n        cin >> H;\n\n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = i + 1; j < N; j++) {\n                if (H[idx] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                idx++;\n            }\n        }\n\n        sort(deg.begin(), deg.end());\n\n        int best_index = -1;\n        double best_dist_sq = numeric_limits<double>::max();\n\n        for (int t = 0; t < M; t++) {\n            double dist_sq = 0.0;\n            for (int i = 0; i < N; i++) {\n                double diff = deg[i] - expected_seqs[t][i];\n                dist_sq += diff * diff;\n            }\n            if (dist_sq < best_dist_sq) {\n                best_dist_sq = dist_sq;\n                best_index = t;\n            }\n        }\n\n        cout << best_index << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int index;\n};\n\nusing ll = long long;\n\nll compute_alt(int u, int v, const Edge& e, const vector<vector<pair<int, int>>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, LLONG_MAX);\n    dist[u] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n    pq.push({0, u});\n\n    while (!pq.empty()) {\n        auto [d, node] = pq.top();\n        pq.pop();\n        if (d != dist[node]) continue;\n        if (node == v) return d;\n        for (auto [neighbor, weight] : adj[node]) {\n            if ((node == e.u && neighbor == e.v) || (node == e.v && neighbor == e.u)) {\n                continue;\n            }\n            ll new_dist = d + weight;\n            if (new_dist < dist[neighbor]) {\n                dist[neighbor] = new_dist;\n                pq.push({new_dist, neighbor});\n            }\n        }\n    }\n    return dist[v];\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].index = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    vector<vector<ll>> original_dist(N, vector<ll>(N, LLONG_MAX));\n    for (int i = 0; i < N; i++) {\n        vector<ll> dist(N, LLONG_MAX);\n        dist[i] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n        pq.push({0, i});\n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist[node]) continue;\n            for (auto [neighbor, weight] : adj[node]) {\n                ll new_dist = d + weight;\n                if (new_dist < dist[neighbor]) {\n                    dist[neighbor] = new_dist;\n                    pq.push({new_dist, neighbor});\n                }\n            }\n        }\n        for (int j = 0; j < N; j++) {\n            original_dist[i][j] = dist[j];\n        }\n    }\n\n    vector<double> criticality(M, 0.0);\n    for (int idx = 0; idx < M; idx++) {\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        int w = e.w;\n        ll alt_dist = compute_alt(u, v, e, adj);\n        if (alt_dist == LLONG_MAX) {\n            alt_dist = 1000000000;\n        }\n        ll increase = alt_dist - w;\n        if (increase < 0) increase = 0;\n\n        int count_S1 = 0;\n        for (int i = 0; i < N; i++) {\n            if (original_dist[i][u] == LLONG_MAX || original_dist[i][v] == LLONG_MAX) continue;\n            if (original_dist[i][u] + w == original_dist[i][v]) {\n                count_S1++;\n            }\n        }\n\n        int count_S2 = 0;\n        for (int j = 0; j < N; j++) {\n            if (original_dist[u][j] == LLONG_MAX || original_dist[v][j] == LLONG_MAX) continue;\n            if (original_dist[u][j] == original_dist[v][j] + w) {\n                count_S2++;\n            }\n        }\n\n        int count_T1 = 0;\n        for (int i = 0; i < N; i++) {\n            if (original_dist[i][v] == LLONG_MAX || original_dist[i][u] == LLONG_MAX) continue;\n            if (original_dist[i][v] + w == original_dist[i][u]) {\n                count_T1++;\n            }\n        }\n\n        int count_T2 = 0;\n        for (int j = 0; j < N; j++) {\n            if (original_dist[v][j] == LLONG_MAX || original_dist[u][j] == LLONG_MAX) continue;\n            if (original_dist[v][j] == original_dist[u][j] + w) {\n                count_T2++;\n            }\n        }\n\n        ll total_count = (ll)count_S1 * count_S2 + (ll)count_T1 * count_T2;\n        criticality[idx] = (double)increase * total_count;\n    }\n\n    vector<int> edge_indices(M);\n    for (int i = 0; i < M; i++) {\n        edge_indices[i] = i;\n    }\n\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return criticality[a] > criticality[b];\n    });\n\n    double max_crit = 0.0;\n    for (int i = 0; i < M; i++) {\n        if (criticality[i] > max_crit) {\n            max_crit = criticality[i];\n        }\n    }\n\n    vector<int> assignment(M, -1);\n    vector<double> day_criticality(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<vector<int>> vertex_day_count(N, vector<int>(D, 0));\n\n    for (int i = 0; i < M; i++) {\n        int idx = edge_indices[i];\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        double min_cost = 1e20;\n        int best_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict_count = vertex_day_count[u][d] + vertex_day_count[v][d];\n            double norm_crit = (max_crit > 0) ? (criticality[idx] / max_crit) : 0.0;\n            double cost = conflict_count + 10.0 * norm_crit;\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_day = d;\n            }\n        }\n        assignment[idx] = best_day;\n        day_criticality[best_day] += criticality[idx];\n        day_count[best_day]++;\n        vertex_day_count[u][best_day]++;\n        vertex_day_count[v][best_day]++;\n    }\n\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] + 1;\n        if (i < M - 1) {\n            cout << \" \";\n        } else {\n            cout << endl;\n        }\n    }\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n#include <map>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[6] = {1, 0, 0, -1, 0, 0};\nconst int dy[6] = {0, 1, 0, 0, -1, 0};\nconst int dz[6] = {0, 0, 1, 0, 0, -1};\n\nusing Point = tuple<int, int, int>;\n\nvector<set<Point>> get_connected_components_from_set(const set<Point>& points) {\n    set<Point> visited;\n    vector<set<Point>> components;\n    for (const auto& p : points) {\n        if (visited.find(p) == visited.end()) {\n            set<Point> comp;\n            queue<Point> q;\n            q.push(p);\n            visited.insert(p);\n            while (!q.empty()) {\n                auto [x, y, z] = q.front(); q.pop();\n                comp.insert({x, y, z});\n                for (int dir = 0; dir < 6; dir++) {\n                    int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                    Point np = {nx, ny, nz};\n                    if (points.find(np) != points.end() && visited.find(np) == visited.end()) {\n                        visited.insert(np);\n                        q.push(np);\n                    }\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\nvector<set<Point>> get_connected_components_from_grid(const vector<vector<vector<bool>>>& grid, int D) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<set<Point>> components;\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (grid[z][x][y] && !visited[z][x][y]) {\n                    set<Point> comp;\n                    queue<Point> q;\n                    q.push({x, y, z});\n                    visited[z][x][y] = true;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.insert({cx, cy, cz});\n                        for (int dir = 0; dir < 6; dir++) {\n                            int nx = cx + dx[dir], ny = cy + dy[dir], nz = cz + dz[dir];\n                            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) \n                                continue;\n                            if (grid[nz][nx][ny] && !visited[nz][nx][ny]) {\n                                visited[nz][nx][ny] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n    return components;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> cand1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> cand2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> Common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (f1[z][x] == '1' && r1[z][y] == '1') {\n                    cand1[z][x][y] = true;\n                }\n                if (f2[z][x] == '1' && r2[z][y] == '1') {\n                    cand2[z][x][y] = true;\n                }\n                if (cand1[z][x][y] && cand2[z][x][y]) {\n                    Common[z][x][y] = true;\n                }\n            }\n        }\n    }\n\n    auto process_object = [&](const vector<string>& f, const vector<string>& r, \n                              const vector<vector<vector<bool>>>& cand, \n                              const vector<vector<vector<bool>>>& common) {\n        set<Point> additional_set;\n        vector<vector<bool>> covered_front(D, vector<bool>(D, false));\n        vector<vector<bool>> covered_right(D, vector<bool>(D, false));\n\n        // Mark requirements covered by common cells\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (common[z][x][y]) {\n                        covered_front[z][x] = true;\n                        covered_right[z][y] = true;\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered front requirements\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (f[z][x] == '1' && !covered_front[z][x]) {\n                    bool found = false;\n                    for (int y = 0; y < D; y++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int y = 0; y < D; y++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered right requirements\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (r[z][y] == '1' && !covered_right[z][y]) {\n                    bool found = false;\n                    for (int x = 0; x < D; x++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int x = 0; x < D; x++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return additional_set;\n    };\n\n    set<Point> A1_set = process_object(f1, r1, cand1, Common);\n    set<Point> B1_set = process_object(f2, r2, cand2, Common);\n\n    auto common_components = get_connected_components_from_grid(Common, D);\n    auto a1_components = get_connected_components_from_set(A1_set);\n    auto b1_components = get_connected_components_from_set(B1_set);\n\n    int n = common_components.size() + a1_components.size() + b1_components.size();\n    vector<int> arr1(D*D*D, 0);\n    vector<int> arr2(D*D*D, 0);\n\n    int block_id = 1;\n    for (const auto& comp : common_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : a1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : b1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    cout << n << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr1[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr2[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <queue>\n#include <unordered_set>\n#include <chrono>\n#include <iomanip>\n#include <limits>\n\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    ll x, y;\n    \n    Point() : x(0), y(0) {}\n    Point(ll x, ll y) : x(x), y(y) {}\n    \n    ll dist2(const Point& other) const {\n        ll dx = x - other.x;\n        ll dy = y - other.y;\n        return dx * dx + dy * dy;\n    }\n    \n    double dist(const Point& other) const {\n        return sqrt(dist2(other));\n    }\n};\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int idx;\n    \n    Edge(int u, int v, ll w, int idx) : u(u), v(v), w(w), idx(idx) {}\n    \n    bool operator<(const Edge& other) const {\n        return w < other.w;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    ll cost;\n    int covered;\n    \n    Solution(int N, int M) : P(N, 0), B(M, 0), cost(0), covered(0) {}\n};\n\nclass TVNetworkOptimizer {\nprivate:\n    int N, M, K;\n    vector<Point> stations;\n    vector<Point> residents;\n    vector<Edge> edges;\n    vector<vector<pair<int, ll>>> adj; // adjacency list\n    \n    // Random number generation\n    mt19937 rng;\n    \n    // Best solution found\n    Solution best_solution;\n    \n    // Distance matrices\n    vector<vector<double>> station_to_resident_dist;\n    vector<vector<double>> station_to_station_dist;\n    \npublic:\n    TVNetworkOptimizer() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void read_input() {\n        cin >> N >> M >> K;\n        \n        stations.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> stations[i].x >> stations[i].y;\n        }\n        \n        edges.reserve(M);\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v;\n            ll w;\n            cin >> u >> v >> w;\n            u--; v--;\n            edges.emplace_back(u, v, w, i);\n            adj[u].emplace_back(v, w);\n            adj[v].emplace_back(u, w);\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].x >> residents[i].y;\n        }\n        \n        // Precompute distances\n        compute_distances();\n    }\n    \n    void compute_distances() {\n        station_to_resident_dist.resize(N, vector<double>(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                station_to_resident_dist[i][j] = stations[i].dist(residents[j]);\n            }\n        }\n        \n        station_to_station_dist.resize(N, vector<double>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                station_to_station_dist[i][j] = stations[i].dist(stations[j]);\n            }\n        }\n    }\n    \n    // Build initial MST solution\n    Solution build_mst_solution() {\n        Solution sol(N, M);\n        \n        // Prim's algorithm for MST\n        vector<bool> in_mst(N, false);\n        vector<ll> min_edge(N, numeric_limits<ll>::max());\n        vector<int> parent(N, -1);\n        \n        min_edge[0] = 0;\n        \n        for (int i = 0; i < N; i++) {\n            int u = -1;\n            for (int v = 0; v < N; v++) {\n                if (!in_mst[v] && (u == -1 || min_edge[v] < min_edge[u])) {\n                    u = v;\n                }\n            }\n            \n            if (min_edge[u] == numeric_limits<ll>::max()) break;\n            \n            in_mst[u] = true;\n            \n            if (parent[u] != -1) {\n                // Find the edge between u and parent[u]\n                for (const auto& edge : edges) {\n                    if ((edge.u == u && edge.v == parent[u]) || \n                        (edge.u == parent[u] && edge.v == u)) {\n                        sol.B[edge.idx] = 1;\n                        sol.cost += edge.w;\n                        break;\n                    }\n                }\n            }\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!in_mst[v] && w < min_edge[v]) {\n                    min_edge[v] = w;\n                    parent[v] = u;\n                }\n            }\n        }\n        \n        // Assign powers to cover residents\n        assign_powers(sol);\n        \n        return sol;\n    }\n    \n    // Assign powers to vertices to cover residents\n    void assign_powers(Solution& sol) {\n        vector<bool> covered(K, false);\n        sol.covered = 0;\n        \n        // First, find which vertices are reachable from vertex 1\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find the closest reachable station\n        vector<vector<int>> assignments(N);\n        for (int k = 0; k < K; k++) {\n            double min_dist = numeric_limits<double>::max();\n            int best_station = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (reachable[i] && station_to_resident_dist[i][k] < min_dist) {\n                    min_dist = station_to_resident_dist[i][k];\n                    best_station = i;\n                }\n            }\n            \n            if (best_station != -1) {\n                assignments[best_station].push_back(k);\n            }\n        }\n        \n        // Calculate power for each station\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            if (!assignments[i].empty()) {\n                double max_dist = 0;\n                for (int k : assignments[i]) {\n                    max_dist = max(max_dist, station_to_resident_dist[i][k]);\n                }\n                sol.P[i] = min(5000, static_cast<int>(ceil(max_dist)));\n                power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n                \n                for (int k : assignments[i]) {\n                    if (!covered[k]) {\n                        covered[k] = true;\n                        sol.covered++;\n                    }\n                }\n            } else {\n                sol.P[i] = 0;\n            }\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    // Find vertices reachable from vertex 1\n    vector<bool> find_reachable(const vector<int>& B) {\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!reachable[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                reachable[v] = true;\n                                q.push(v);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return reachable;\n    }\n    \n    // Calculate total edge cost\n    ll get_edge_cost(const vector<int>& B) {\n        ll cost = 0;\n        for (int i = 0; i < M; i++) {\n            if (B[i]) {\n                cost += edges[i].w;\n            }\n        }\n        return cost;\n    }\n    \n    // Try to improve solution by adding/removing edges\n    Solution local_search(const Solution& initial_sol) {\n        Solution best_sol = initial_sol;\n        Solution current_sol = initial_sol;\n        \n        uniform_int_distribution<int> edge_dist(0, M-1);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        double temperature = 1000.0;\n        double cooling_rate = 0.995;\n        int iterations = 10000;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Try random edge operation\n            int edge_idx = edge_dist(rng);\n            Solution new_sol = current_sol;\n            \n            if (new_sol.B[edge_idx] == 1) {\n                // Try removing edge\n                new_sol.B[edge_idx] = 0;\n                if (is_connected(new_sol.B)) {\n                    assign_powers(new_sol);\n                } else {\n                    new_sol.B[edge_idx] = 1; // Revert if disconnected\n                }\n            } else {\n                // Try adding edge\n                new_sol.B[edge_idx] = 1;\n                assign_powers(new_sol);\n            }\n            \n            // Accept or reject based on simulated annealing\n            if (accept_solution(current_sol, new_sol, temperature)) {\n                current_sol = new_sol;\n                if (current_sol.covered == K && \n                    (best_sol.covered < K || current_sol.cost < best_sol.cost)) {\n                    best_sol = current_sol;\n                }\n            }\n            \n            temperature *= cooling_rate;\n        }\n        \n        return best_sol;\n    }\n    \n    // Check if the graph with selected edges is connected\n    bool is_connected(const vector<int>& B) {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!visited[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                visited[v] = true;\n                                q.push(v);\n                                count++;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return count == N;\n    }\n    \n    // Simulated annealing acceptance criterion\n    bool accept_solution(const Solution& current, const Solution& new_sol, double temperature) {\n        if (new_sol.covered > current.covered) return true;\n        if (new_sol.covered < current.covered) return false;\n        \n        if (new_sol.cost < current.cost) return true;\n        \n        if (temperature < 1e-6) return false;\n        \n        double delta = new_sol.cost - current.cost;\n        double prob = exp(-delta / temperature);\n        \n        uniform_real_distribution<double> dist(0.0, 1.0);\n        return dist(rng) < prob;\n    }\n    \n    // Optimize power assignments given fixed network\n    void optimize_powers(Solution& sol) {\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find all stations that can cover it\n        vector<vector<int>> covering_stations(K);\n        for (int k = 0; k < K; k++) {\n            for (int i = 0; i < N; i++) {\n                if (reachable[i]) {\n                    double dist = station_to_resident_dist[i][k];\n                    if (dist <= 5000) {\n                        covering_stations[k].push_back(i);\n                    }\n                }\n            }\n        }\n        \n        // Greedily assign residents to minimize total power cost\n        vector<bool> covered(K, false);\n        vector<int> assignments(K, -1);\n        sol.covered = 0;\n        \n        // Sort residents by number of covering stations (ascending)\n        vector<int> resident_order(K);\n        for (int k = 0; k < K; k++) resident_order[k] = k;\n        sort(resident_order.begin(), resident_order.end(), \n             [&](int a, int b) { \n                 return covering_stations[a].size() < covering_stations[b].size(); \n             });\n        \n        for (int k : resident_order) {\n            if (covered[k]) continue;\n            \n            // Find best station for this resident\n            int best_station = -1;\n            double best_cost = numeric_limits<double>::max();\n            \n            for (int station : covering_stations[k]) {\n                double dist = station_to_resident_dist[station][k];\n                double additional_cost = dist * dist;\n                \n                // Check how many additional residents this station would cover\n                int additional_cover = 0;\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && station_to_resident_dist[station][other] <= dist) {\n                        additional_cover++;\n                    }\n                }\n                \n                double cost_per_resident = additional_cost / max(1, additional_cover);\n                \n                if (cost_per_resident < best_cost) {\n                    best_cost = cost_per_resident;\n                    best_station = station;\n                }\n            }\n            \n            if (best_station != -1) {\n                double required_power = station_to_resident_dist[best_station][k];\n                \n                // Assign this resident and others that can be covered\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && \n                        station_to_resident_dist[best_station][other] <= required_power) {\n                        covered[other] = true;\n                        assignments[other] = best_station;\n                        sol.covered++;\n                    }\n                }\n            }\n        }\n        \n        // Set powers based on assignments\n        vector<double> max_power(N, 0.0);\n        for (int k = 0; k < K; k++) {\n            if (assignments[k] != -1) {\n                max_power[assignments[k]] = max(max_power[assignments[k]], \n                                               station_to_resident_dist[assignments[k]][k]);\n            }\n        }\n        \n        // Calculate power cost\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            sol.P[i] = min(5000, static_cast<int>(ceil(max_power[i])));\n            power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    void solve() {\n        // Build initial MST solution\n        Solution sol = build_mst_solution();\n        \n        // Optimize power assignments\n        optimize_powers(sol);\n        best_solution = sol;\n        \n        // Run local search with simulated annealing\n        for (int trial = 0; trial < 5; trial++) {\n            Solution improved = local_search(best_solution);\n            optimize_powers(improved);\n            \n            if (improved.covered == K && \n                (best_solution.covered < K || improved.cost < best_solution.cost)) {\n                best_solution = improved;\n            }\n        }\n        \n        // Final power optimization\n        optimize_powers(best_solution);\n        \n        // Output solution\n        output_solution(best_solution);\n    }\n    \n    void output_solution(const Solution& sol) {\n        for (int i = 0; i < N; i++) {\n            cout << sol.P[i];\n            if (i < N - 1) cout << \" \";\n        }\n        cout << endl;\n        \n        for (int i = 0; i < M; i++) {\n            cout << sol.B[i];\n            if (i < M - 1) cout << \" \";\n        }\n        cout << endl;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TVNetworkOptimizer optimizer;\n    optimizer.read_input();\n    optimizer.solve();\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n\nusing namespace std;\n\nvector<vector<int>> pyramid;\nvector<tuple<int, int, int, int>> operations;\n\n// Check if two positions are adjacent\nbool is_adjacent(int x1, int y1, int x2, int y2) {\n    return (x1 == x2 - 1 && y1 == y2 - 1) ||\n           (x1 == x2 - 1 && y1 == y2) ||\n           (x1 == x2 && y1 == y2 - 1) ||\n           (x1 == x2 && y1 == y2 + 1) ||\n           (x1 == x2 + 1 && y1 == y2) ||\n           (x1 == x2 + 1 && y1 == y2 + 1);\n}\n\n// Count the number of violations\nint count_violations() {\n    int violations = 0;\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) violations++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) violations++;\n        }\n    }\n    return violations;\n}\n\n// Swap two balls and record the operation\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    if (!is_adjacent(x1, y1, x2, y2)) {\n        cerr << \"Error: Attempting to swap non-adjacent balls\" << endl;\n        return;\n    }\n    operations.emplace_back(x1, y1, x2, y2);\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n}\n\n// Top-down pass: ensure each ball is smaller than those below it\nvoid top_down_pass() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            int left_child = pyramid[x+1][y];\n            int right_child = pyramid[x+1][y+1];\n            \n            if (current > left_child || current > right_child) {\n                // Find the smaller child\n                if (left_child < right_child) {\n                    // Swap with left child\n                    swap_balls(x, y, x+1, y);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                } else {\n                    // Swap with right child\n                    swap_balls(x, y, x+1, y+1);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y+1;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Bubble up larger numbers towards the bottom\nvoid bubble_up() {\n    for (int x = 28; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check if current is larger than its parent\n            if (x > 0) {\n                int parent_y = -1;\n                if (y <= x-1 && pyramid[x-1][y] < current) {\n                    parent_y = y;\n                } else if (y > 0 && pyramid[x-1][y-1] < current) {\n                    parent_y = y-1;\n                }\n                \n                if (parent_y != -1) {\n                    // Swap with parent\n                    swap_balls(x, y, x-1, parent_y);\n                }\n            }\n        }\n    }\n}\n\n// Local refinement: fix specific violations\nvoid local_refinement() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check violation with left child\n            if (current > pyramid[x+1][y]) {\n                // Try to find a better position for current\n                bool found = false;\n                \n                // Check adjacent positions\n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    // Just swap with the child\n                    swap_balls(x, y, x+1, y);\n                }\n            }\n            \n            // Check violation with right child\n            if (current > pyramid[x+1][y+1]) {\n                // Similar logic as above\n                bool found = false;\n                \n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    swap_balls(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    pyramid.resize(30);\n    for (int x = 0; x < 30; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Apply our algorithm\n    int max_operations = 10000;\n    \n    // Initial top-down pass\n    top_down_pass();\n    \n    // Iterative improvement\n    while (operations.size() < max_operations) {\n        int violations_before = count_violations();\n        if (violations_before == 0) break;\n        \n        // Try different strategies\n        if (operations.size() % 3 == 0) {\n            bubble_up();\n        } else if (operations.size() % 3 == 1) {\n            top_down_pass();\n        } else {\n            local_refinement();\n        }\n        \n        // Check if we're making progress\n        int violations_after = count_violations();\n        if (violations_after >= violations_before) {\n            // Not making progress, try a different approach\n            break;\n        }\n    }\n    \n    // Final pass to fix remaining violations\n    if (operations.size() < max_operations) {\n        local_refinement();\n    }\n    \n    // Output the result\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <iomanip>\n\nusing namespace std;\n\nconst int D = 9;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nint grid[D][D];\nint base_distance[D][D];\n\nvoid bfs_base() {\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_distance[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_distance[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (base_distance[nx][ny] == -1 && grid[nx][ny] != -1) {\n                    base_distance[nx][ny] = base_distance[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nstruct BFSResult {\n    bool visited[D][D];\n    int dist[D][D];\n};\n\nBFSResult bfs_current() {\n    BFSResult res;\n    memset(res.visited, false, sizeof(res.visited));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            res.dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    res.visited[0][4] = true;\n    res.dist[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (!res.visited[nx][ny]) {\n                    if (grid[nx][ny] == 0 || grid[nx][ny] == -2) {\n                        res.visited[nx][ny] = true;\n                        res.dist[nx][ny] = res.dist[x][y] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n    }\n    return res;\n}\n\nbool check_reachability_after_placing(int i, int j, int t_d) {\n    grid[i][j] = t_d;\n    BFSResult res = bfs_current();\n    vector<pair<int, int>> container_cells;\n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            if (grid[x][y] >= 0) {\n                container_cells.push_back({x, y});\n            }\n        }\n    }\n    bool all_reachable = true;\n    for (auto [x, y] : container_cells) {\n        bool reachable = false;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (res.visited[nx][ny]) {\n                    reachable = true;\n                    break;\n                }\n            }\n        }\n        if (!reachable) {\n            all_reachable = false;\n            break;\n        }\n    }\n    grid[i][j] = 0;\n    return all_reachable;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    cin >> N;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            grid[i][j] = 0;\n        }\n    }\n    grid[0][4] = -2;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    bfs_base();\n\n    int min_base = INT_MAX, max_base = INT_MIN;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == 4) continue;\n            if (grid[i][j] == -1) continue;\n            if (base_distance[i][j] == -1) continue;\n            if (base_distance[i][j] < min_base) min_base = base_distance[i][j];\n            if (base_distance[i][j] > max_base) max_base = base_distance[i][j];\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    if (M > 0) {\n        for (int d = 0; d < M; d++) {\n            int t_d;\n            cin >> t_d;\n\n            double desired;\n            if (M == 1) {\n                desired = min_base;\n            } else {\n                desired = (double)(t_d) / (M - 1) * (max_base - min_base) + min_base;\n            }\n\n            BFSResult res1 = bfs_current();\n            vector<pair<int, int>> candidate_cells;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] == 0 && res1.visited[i][j]) {\n                        candidate_cells.push_back({i, j});\n                    }\n                }\n            }\n\n            vector<pair<int, int>> valid_candidates;\n            vector<double> costs;\n            vector<int> current_dists;\n\n            for (auto [i, j] : candidate_cells) {\n                if (check_reachability_after_placing(i, j, t_d)) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            if (valid_candidates.empty()) {\n                for (auto [i, j] : candidate_cells) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            int best_index = 0;\n            for (int idx = 1; idx < valid_candidates.size(); idx++) {\n                if (costs[idx] < costs[best_index]) {\n                    best_index = idx;\n                } else if (costs[idx] == costs[best_index]) {\n                    if (current_dists[idx] < current_dists[best_index]) {\n                        best_index = idx;\n                    } else if (current_dists[idx] == current_dists[best_index]) {\n                        if (base_distance[valid_candidates[idx].first][valid_candidates[idx].second] < \n                            base_distance[valid_candidates[best_index].first][valid_candidates[best_index].second]) {\n                            best_index = idx;\n                        }\n                    }\n                }\n            }\n\n            auto [i, j] = valid_candidates[best_index];\n            grid[i][j] = t_d;\n            cout << i << \" \" << j << endl;\n            cout.flush();\n        }\n    }\n\n    if (M > 0) {\n        vector<pair<int, int>> transport_order;\n        for (int step = 0; step < M; step++) {\n            BFSResult res = bfs_current();\n            vector<pair<int, int>> reachable_containers;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] >= 0) {\n                        for (int d = 0; d < 4; d++) {\n                            int ni = i + dx[d], nj = j + dy[d];\n                            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                                if (res.visited[ni][nj]) {\n                                    reachable_containers.push_back({i, j});\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int min_number = INT_MAX;\n            pair<int, int> min_cell = {-1, -1};\n            for (auto [i, j] : reachable_containers) {\n                if (grid[i][j] < min_number) {\n                    min_number = grid[i][j];\n                    min_cell = {i, j};\n                }\n            }\n\n            grid[min_cell.first][min_cell.second] = 0;\n            transport_order.push_back(min_cell);\n        }\n\n        for (auto [i, j] : transport_order) {\n            cout << i << \" \" << j << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nconst int dx[4] = {1, 0, -1, 0};\nconst int dy[4] = {0, 1, 0, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<vector<bool>> adj(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 = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    adj[c1][0] = true;\n                    adj[0][c1] = true;\n                } else {\n                    int c2 = grid[ni][nj];\n                    if (c1 != c2) {\n                        adj[c1][c2] = true;\n                        adj[c2][c1] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> new_grid(n, vector<int>(n, -1));\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<tuple<int, int, int>> q;\n\n    vector<int> A;\n    for (int c = 1; c <= m; c++) {\n        if (adj[c][0]) {\n            A.push_back(c);\n        }\n    }\n\n    vector<vector<int>> H(A.size());\n    for (int i = 0; i < A.size(); i++) {\n        for (int j = i+1; j < A.size(); j++) {\n            if (adj[A[i]][A[j]]) {\n                H[i].push_back(j);\n                H[j].push_back(i);\n            }\n        }\n    }\n\n    vector<int> order;\n    vector<bool> done(H.size(), false);\n    if (!H.empty()) {\n        queue<int> qq;\n        qq.push(0);\n        done[0] = true;\n        while (!qq.empty()) {\n            int u = qq.front(); qq.pop();\n            order.push_back(u);\n            for (int v : H[u]) {\n                if (!done[v]) {\n                    done[v] = true;\n                    qq.push(v);\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> boundary;\n    for (int j = 0; j < n; j++) {\n        boundary.emplace_back(0, j);\n    }\n    for (int i = 1; i < n; i++) {\n        boundary.emplace_back(i, n-1);\n    }\n    for (int j = n-2; j >= 0; j--) {\n        boundary.emplace_back(n-1, j);\n    }\n    for (int i = n-2; i >= 1; i--) {\n        boundary.emplace_back(i, 0);\n    }\n\n    vector<int> boundary_assignment;\n    if (!order.empty()) {\n        boundary_assignment.push_back(A[order[0]]);\n        for (int i = 1; i < order.size(); i++) {\n            int u = order[i-1];\n            int v = order[i];\n            bool adj_in_H = false;\n            for (int w : H[u]) {\n                if (w == v) {\n                    adj_in_H = true;\n                    break;\n                }\n            }\n            if (!adj_in_H) {\n                boundary_assignment.push_back(0);\n            }\n            boundary_assignment.push_back(A[v]);\n        }\n        int u = order.back();\n        int v = order[0];\n        bool adj_in_H = false;\n        for (int w : H[u]) {\n            if (w == v) {\n                adj_in_H = true;\n                break;\n            }\n        }\n        if (!adj_in_H) {\n            boundary_assignment.push_back(0);\n        }\n    }\n\n    for (int idx = 0; idx < boundary.size(); idx++) {\n        int color = (idx < boundary_assignment.size()) ? boundary_assignment[idx] : 0;\n        int i = boundary[idx].first;\n        int j = boundary[idx].second;\n        new_grid[i][j] = color;\n        visited[i][j] = true;\n        if (color != 0) {\n            q.push({i, j, color});\n        }\n    }\n\n    while (!q.empty()) {\n        auto [i, j, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n            if (visited[ni][nj]) continue;\n            bool can_assign = true;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + dx[dd];\n                int nnj = nj + dy[dd];\n                if (nni < 0 || nni >= n || nnj < 0 || nnj >= n) continue;\n                if (new_grid[nni][nnj] == -1) continue;\n                int d_color = new_grid[nni][nnj];\n                if (d_color == 0) continue;\n                if (d_color == c) continue;\n                if (!adj[c][d_color]) {\n                    can_assign = false;\n                    break;\n                }\n            }\n            if (can_assign) {\n                new_grid[ni][nj] = c;\n                visited[ni][nj] = true;\n                q.push({ni, nj, c});\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (new_grid[i][j] == -1) {\n                new_grid[i][j] = 0;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << new_grid[i][j] << (j < n-1 ? ' ' : '\\n');\n        }\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\n\n// Random number generator with proper seeding\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to output a query and get the result\nchar query(int nL, int nR, const vector<int>& L, const vector<int>& R) {\n    cout << nL << \" \" << nR;\n    for (int i : L) cout << \" \" << i;\n    for (int i : R) cout << \" \" << i;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\n// Function to partition items into D sets based on estimated weights\nvector<int> partition_items(int N, int D, const vector<double>& estimated_weights) {\n    // Create pairs of (item_index, estimated_weight)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.emplace_back(estimated_weights[i], i);\n    }\n    \n    // Sort items by estimated weight in descending order\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize D sets\n    vector<double> set_weights(D, 0.0);\n    vector<int> assignment(N, -1);\n    \n    // Greedy assignment: assign each item to the set with the smallest current total weight\n    for (const auto& [weight, idx] : items) {\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        assignment[idx] = min_set;\n        set_weights[min_set] += weight;\n    }\n    \n    // Improvement phase 1: Try to balance by swapping items between sets\n    for (int iter = 0; iter < 100; iter++) {\n        // Calculate the current variance\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        double variance = 0.0;\n        for (double w : set_weights) {\n            variance += (w - mean) * (w - mean);\n        }\n        variance /= D;\n        \n        // Try to find a swap that reduces the variance\n        bool improved = false;\n        \n        // Try swaps between sets\n        for (int trial = 0; trial < 50; trial++) {\n            int i = rng() % N;\n            int j = rng() % N;\n            while (i == j) {\n                j = rng() % N;\n            }\n            \n            if (assignment[i] != assignment[j]) {\n                // Calculate the new variance if we swap items i and j\n                int set_i = assignment[i];\n                int set_j = assignment[j];\n                \n                double new_weight_i = set_weights[set_i] - estimated_weights[i] + estimated_weights[j];\n                double new_weight_j = set_weights[set_j] - estimated_weights[j] + estimated_weights[i];\n                \n                double new_variance = variance;\n                new_variance -= (set_weights[set_i] - mean) * (set_weights[set_i] - mean) / D;\n                new_variance -= (set_weights[set_j] - mean) * (set_weights[set_j] - mean) / D;\n                new_variance += (new_weight_i - mean) * (new_weight_i - mean) / D;\n                new_variance += (new_weight_j - mean) * (new_weight_j - mean) / D;\n                \n                if (new_variance < variance) {\n                    // Swap the items\n                    assignment[i] = set_j;\n                    assignment[j] = set_i;\n                    set_weights[set_i] = new_weight_i;\n                    set_weights[set_j] = new_weight_j;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Improvement phase 2: Try to move items to balance sets\n    for (int iter = 0; iter < 50; iter++) {\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        \n        // Find the set with the highest weight and the set with the lowest weight\n        int max_set = max_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        \n        if (set_weights[max_set] - set_weights[min_set] < 1e-6) break;\n        \n        // Find an item in the max_set that can be moved to min_set to reduce difference\n        bool moved = false;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == max_set) {\n                double new_max = set_weights[max_set] - estimated_weights[i];\n                double new_min = set_weights[min_set] + estimated_weights[i];\n                \n                double current_diff = set_weights[max_set] - set_weights[min_set];\n                double new_diff = abs(new_max - new_min);\n                \n                if (new_diff < current_diff) {\n                    // Move the item\n                    assignment[i] = min_set;\n                    set_weights[max_set] = new_max;\n                    set_weights[min_set] = new_min;\n                    moved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!moved) break;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Initialize estimated weights\n    vector<double> estimated_weights(N, 1.0);\n    \n    // Keep track of how many times each item has been compared\n    vector<int> compare_count(N, 0);\n    \n    // Use queries to estimate relative weights\n    for (int q = 0; q < Q; q++) {\n        if (q < Q / 2) {\n            // First half: Compare individual items using tournament method\n            // Find two items with the lowest comparison counts\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            int i = -1, j = -1;\n            for (int idx : indices) {\n                if (i == -1) {\n                    i = idx;\n                } else if (j == -1) {\n                    j = idx;\n                    break;\n                }\n            }\n            \n            char result = query(1, 1, {i}, {j});\n            compare_count[i]++;\n            compare_count[j]++;\n            \n            // Update estimates based on result\n            double adjustment = 0.15;\n            if (result == '>') {\n                estimated_weights[i] *= (1.0 + adjustment);\n                estimated_weights[j] *= (1.0 - adjustment);\n            } else if (result == '<') {\n                estimated_weights[i] *= (1.0 - adjustment);\n                estimated_weights[j] *= (1.0 + adjustment);\n            }\n        } else {\n            // Second half: Compare groups of items to refine estimates\n            // Sort items by estimated weight\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return estimated_weights[a] < estimated_weights[b];\n            });\n            \n            // Create two groups of similar weight items\n            int group_size = 2 + rng() % min(4, N / 5);\n            int start = rng() % (N - 2 * group_size);\n            \n            vector<int> group1, group2;\n            for (int k = 0; k < group_size; k++) {\n                group1.push_back(indices[start + k]);\n                group2.push_back(indices[start + group_size + k]);\n            }\n            \n            char result = query(group_size, group_size, group1, group2);\n            \n            // Update estimates based on result\n            double adjustment = 0.08;\n            if (result == '>') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n            } else if (result == '<') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n            }\n            \n            for (int k : group1) compare_count[k]++;\n            for (int k : group2) compare_count[k]++;\n        }\n    }\n    \n    // Normalize estimated weights to a reasonable scale\n    double min_weight = *min_element(estimated_weights.begin(), estimated_weights.end());\n    for (int i = 0; i < N; i++) {\n        estimated_weights[i] /= min_weight;\n    }\n    \n    // Partition items into D sets\n    vector<int> assignment = partition_items(N, D, estimated_weights);\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> position(n + 1);  // position[v] = stack_index\n    \n    // Read input and initialize data structures\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            position[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int next_box = 1;\n    \n    while (next_box <= n) {\n        // Check if next_box is at the top of any stack\n        bool found_at_top = false;\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_box) {\n                // Carry out operation\n                stacks[i].pop_back();\n                operations.emplace_back(next_box, 0);\n                next_box++;\n                found_at_top = true;\n                break;\n            }\n        }\n        \n        if (found_at_top) continue;\n        \n        // Find the stack containing next_box\n        int stack_idx = -1;\n        int pos_in_stack = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                if (stacks[i][j] == next_box) {\n                    stack_idx = i;\n                    pos_in_stack = j;\n                    break;\n                }\n            }\n            if (stack_idx != -1) break;\n        }\n        \n        // The box immediately above next_box\n        int box_above = stacks[stack_idx][pos_in_stack + 1];\n        \n        // Choose destination stack\n        int best_dest = -1;\n        \n        // Prefer empty stacks\n        for (int i = 0; i < m; i++) {\n            if (i != stack_idx && stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n        }\n        \n        // If no empty stack, prefer stacks with larger bottom elements\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx && !stacks[i].empty() && stacks[i][0] > next_box) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Otherwise, choose any non-source stack\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Move boxes above next_box (including box_above) to destination\n        vector<int> moved_boxes;\n        for (int i = pos_in_stack + 1; i < stacks[stack_idx].size(); i++) {\n            moved_boxes.push_back(stacks[stack_idx][i]);\n            position[stacks[stack_idx][i]] = best_dest;\n        }\n        \n        // Update source stack\n        stacks[stack_idx].resize(pos_in_stack + 1);\n        \n        // Update destination stack\n        stacks[best_dest].insert(stacks[best_dest].end(), \n                                 moved_boxes.begin(), moved_boxes.end());\n        \n        // Record operation\n        operations.emplace_back(box_above, best_dest + 1);\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <utility>\n#include <unordered_set>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    Point operator+(const Point& other) const {\n        return Point(i + other.i, j + other.j);\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<Point> {\n        size_t operator()(const Point& p) const {\n            return static_cast<size_t>(p.i) * 1000 + p.j;\n        }\n    };\n}\n\nclass Solution {\npublic:\n    int N;\n    vector<string> h, v;\n    vector<vector<int>> d;\n    vector<vector<bool>> visited;\n    vector<Point> path;\n    string route;\n    \n    // Directions: R, D, L, U\n    const vector<Point> directions = {Point(0, 1), Point(1, 0), Point(0, -1), Point(-1, 0)};\n    const string dir_chars = \"RDLU\";\n    \n    Solution(int n, const vector<string>& h, const vector<string>& v, const vector<vector<int>>& d)\n        : N(n), h(h), v(v), d(d), visited(n, vector<bool>(n, false)) {\n        // Initialize path with starting point\n        path.emplace_back(0, 0);\n    }\n    \n    bool can_move(const Point& from, const Point& to) const {\n        if (to.i < 0 || to.i >= N || to.j < 0 || to.j >= N) return false;\n        \n        // Check horizontal wall\n        if (from.i == to.i) {\n            int j = min(from.j, to.j);\n            if (v[from.i][j] == '1') return false;\n        }\n        // Check vertical wall\n        else if (from.j == to.j) {\n            int i = min(from.i, to.i);\n            if (h[i][from.j] == '1') return false;\n        }\n        return true;\n    }\n    \n    void dfs(Point p) {\n        visited[p.i][p.j] = true;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            Point next = p + directions[dir];\n            if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                !visited[next.i][next.j] && can_move(p, next)) {\n                path.push_back(next);\n                route += dir_chars[dir];\n                dfs(next);\n                path.push_back(p);\n                route += dir_chars[(dir + 2) % 4];\n            }\n        }\n    }\n    \n    vector<Point> bfs(const Point& start, const Point& end) {\n        vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n        vector<vector<bool>> bfs_visited(N, vector<bool>(N, false));\n        queue<Point> q;\n        \n        q.push(start);\n        bfs_visited[start.i][start.j] = true;\n        \n        while (!q.empty()) {\n            Point current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Point> result;\n                Point p = end;\n                while (p != start) {\n                    result.push_back(p);\n                    p = parent[p.i][p.j];\n                }\n                result.push_back(start);\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (const Point& dir : directions) {\n                Point next = current + dir;\n                if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                    !bfs_visited[next.i][next.j] && can_move(current, next)) {\n                    bfs_visited[next.i][next.j] = true;\n                    parent[next.i][next.j] = current;\n                    q.push(next);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    string get_route_string(const vector<Point>& path) {\n        string result;\n        for (size_t i = 1; i < path.size(); i++) {\n            Point from = path[i-1];\n            Point to = path[i];\n            for (int dir = 0; dir < 4; dir++) {\n                if (from + directions[dir] == to) {\n                    result += dir_chars[dir];\n                    break;\n                }\n            }\n        }\n        return result;\n    }\n    \n    void optimize_route() {\n        // Find cells with high dirt susceptibility\n        vector<pair<int, Point>> high_dirt_cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                high_dirt_cells.emplace_back(d[i][j], Point(i, j));\n            }\n        }\n        sort(high_dirt_cells.rbegin(), high_dirt_cells.rend());\n        \n        // Try to create shortcuts to high dirt cells\n        for (int iter = 0; iter < 100; iter++) {\n            if (route.length() > 90000) break; // Don't exceed the limit\n            \n            // Select a random high dirt cell\n            int idx = rng() % min(10, (int)high_dirt_cells.size());\n            Point target = high_dirt_cells[idx].second;\n            \n            // Find random positions in the current path\n            int pos1 = rng() % (path.size() - 1);\n            int pos2 = rng() % (path.size() - 1);\n            if (pos1 > pos2) swap(pos1, pos2);\n            \n            // Try to create a shortcut from pos1 to target and back to pos2\n            vector<Point> path1 = bfs(path[pos1], target);\n            vector<Point> path2 = bfs(target, path[pos2]);\n            \n            if (!path1.empty() && !path2.empty() && \n                path1.size() + path2.size() < pos2 - pos1) {\n                // Create new path\n                vector<Point> new_path;\n                for (int i = 0; i <= pos1; i++) {\n                    new_path.push_back(path[i]);\n                }\n                for (size_t i = 1; i < path1.size(); i++) {\n                    new_path.push_back(path1[i]);\n                }\n                for (size_t i = 1; i < path2.size(); i++) {\n                    new_path.push_back(path2[i]);\n                }\n                for (size_t i = pos2 + 1; i < path.size(); i++) {\n                    new_path.push_back(path[i]);\n                }\n                \n                // Update path and route\n                path = new_path;\n                route = get_route_string(path);\n            }\n        }\n        \n        // Ensure we return to (0,0)\n        if (path.back() != Point(0, 0)) {\n            vector<Point> return_path = bfs(path.back(), Point(0, 0));\n            for (size_t i = 1; i < return_path.size(); i++) {\n                path.push_back(return_path[i]);\n            }\n            route = get_route_string(path);\n        }\n        \n        // Ensure length constraint\n        if (route.length() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    \n    string solve() {\n        // Generate initial route using DFS\n        dfs(Point(0, 0));\n        \n        // Optimize the route\n        optimize_route();\n        \n        return route;\n    }\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> d(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    Solution solution(N, h, v, d);\n    string route = solution.solve();\n    cout << route << endl;\n    \n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M;\n    cin >> N >> M;\n    int s_i, s_j;\n    cin >> s_i >> s_j;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<string> targets(M);\n    set<string> uncovered_targets;\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n        uncovered_targets.insert(targets[i]);\n    }\n\n    map<string, int> prefix_potential;\n    map<string, map<char, int>> next_char_count;\n\n    for (const string& t : targets) {\n        for (int len = 1; len <= 4; len++) {\n            string p = t.substr(0, len);\n            prefix_potential[p]++;\n        }\n        for (int len = 0; len < 5; len++) {\n            string p = t.substr(0, len);\n            if (len < 5) {\n                char next_char = t[len];\n                next_char_count[p][next_char]++;\n            }\n        }\n    }\n\n    int current_i = s_i, current_j = s_j;\n    string current_last4 = string(1, grid[s_i][s_j]);\n    vector<pair<int, int>> path;\n    path.emplace_back(s_i, s_j);\n\n    for (int step = 1; step < 5000; step++) {\n        double best_score = -1e18;\n        pair<int, int> best_move = {-1, -1};\n        string best_new_last4;\n        string best_completed_target = \"\";\n\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char c = grid[i][j];\n                int cost_move = abs(current_i - i) + abs(current_j - j) + 1;\n\n                string new_last4;\n                if (current_last4.size() == 4) {\n                    new_last4 = current_last4.substr(1) + c;\n                } else {\n                    new_last4 = current_last4 + c;\n                }\n\n                double bonus = 0.0;\n\n                string candidate;\n                if (current_last4.size() == 4) {\n                    candidate = current_last4 + c;\n                    if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                        bonus += 100000;\n                    }\n                }\n\n                if (current_last4.size() < 4) {\n                    bonus += 100;\n                }\n\n                bonus += 10 * prefix_potential[new_last4];\n\n                if (next_char_count.find(current_last4) != next_char_count.end()) {\n                    const auto& char_count = next_char_count.at(current_last4);\n                    auto it = char_count.find(c);\n                    if (it != char_count.end()) {\n                        bonus += 1000 * it->second * (5 - current_last4.size());\n                    }\n                }\n\n                double score = -cost_move + bonus;\n\n                if (score > best_score) {\n                    best_score = score;\n                    best_move = {i, j};\n                    best_new_last4 = new_last4;\n                    if (current_last4.size() == 4) {\n                        best_completed_target = candidate;\n                    } else {\n                        best_completed_target = \"\";\n                    }\n                }\n            }\n        }\n\n        path.push_back(best_move);\n        current_i = best_move.first;\n        current_j = best_move.second;\n        current_last4 = best_new_last4;\n\n        if (!best_completed_target.empty()) {\n            uncovered_targets.erase(best_completed_target);\n            for (int len = 1; len <= 4; len++) {\n                string p = best_completed_target.substr(0, len);\n                prefix_potential[p]--;\n            }\n            for (int len = 0; len < 5; len++) {\n                string p = best_completed_target.substr(0, len);\n                if (len < 5) {\n                    char next_char = best_completed_target[len];\n                    next_char_count[p][next_char]--;\n                    if (next_char_count[p][next_char] == 0) {\n                        next_char_count[p].erase(next_char);\n                    }\n                }\n            }\n        }\n\n        if (uncovered_targets.empty()) {\n            break;\n        }\n    }\n\n    for (const auto& p : path) {\n        cout << p.first << \" \" << p.second << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        return tie(i, j) < tie(other.i, other.j);\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct OilField {\n    vector<Point> cells;\n    int size;\n};\n\nstruct GridInfo {\n    int N, M;\n    double epsilon;\n    vector<OilField> oil_fields;\n    vector<vector<int>> drilled_values;\n    vector<vector<double>> estimated_values;\n    set<Point> oil_squares;\n    \n    GridInfo(int N, int M, double epsilon) : N(N), M(M), epsilon(epsilon) {\n        drilled_values.assign(N, vector<int>(N, -1));\n        estimated_values.assign(N, vector<double>(N, 0.0));\n    }\n};\n\nvoid read_input(GridInfo& grid) {\n    cin >> grid.N >> grid.M >> grid.epsilon;\n    grid.oil_fields.resize(grid.M);\n    \n    for (int k = 0; k < grid.M; ++k) {\n        int d;\n        cin >> d;\n        grid.oil_fields[k].size = d;\n        grid.oil_fields[k].cells.resize(d);\n        for (int i = 0; i < d; ++i) {\n            cin >> grid.oil_fields[k].cells[i].i >> grid.oil_fields[k].cells[i].j;\n        }\n    }\n}\n\nint drill(GridInfo& grid, int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    grid.drilled_values[i][j] = value;\n    grid.estimated_values[i][j] = value;\n    if (value > 0) {\n        grid.oil_squares.insert(Point(i, j));\n    }\n    return value;\n}\n\nint divine(GridInfo& grid, const vector<Point>& squares) {\n    cout << \"q \" << squares.size();\n    for (const auto& p : squares) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    return value;\n}\n\nbool submit_answer(GridInfo& grid, const set<Point>& answer) {\n    cout << \"a \" << answer.size();\n    for (const auto& p : answer) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nvector<Point> get_region_points(int i1, int j1, int i2, int j2, int N) {\n    vector<Point> points;\n    for (int i = i1; i <= i2; ++i) {\n        for (int j = j1; j <= j2; ++j) {\n            if (i >= 0 && i < N && j >= 0 && j < N) {\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    return points;\n}\n\nvoid explore_grid(GridInfo& grid, int max_operations) {\n    int operations_used = 0;\n    \n    if (operations_used < max_operations) {\n        auto all_points = get_region_points(0, 0, grid.N-1, grid.N-1, grid.N);\n        if (all_points.size() >= 2) {\n            int total_oil_estimate = divine(grid, all_points);\n            operations_used++;\n            \n            double avg_oil = static_cast<double>(total_oil_estimate) / (grid.N * grid.N);\n            for (int i = 0; i < grid.N; ++i) {\n                for (int j = 0; j < grid.N; ++j) {\n                    grid.estimated_values[i][j] = avg_oil;\n                }\n            }\n        }\n    }\n    \n    queue<tuple<int, int, int, int>> regions;\n    regions.push({0, 0, grid.N-1, grid.N-1});\n    \n    while (!regions.empty() && operations_used < max_operations) {\n        auto [i1, j1, i2, j2] = regions.front();\n        regions.pop();\n        \n        auto points = get_region_points(i1, j1, i2, j2, grid.N);\n        if (points.size() < 2) continue;\n        \n        int oil_estimate = divine(grid, points);\n        operations_used++;\n        \n        if (oil_estimate > 0) {\n            int mid_i = (i1 + i2) / 2;\n            int mid_j = (j1 + j2) / 2;\n            \n            if (i2 - i1 > 1 || j2 - j1 > 1) {\n                regions.push({i1, j1, mid_i, mid_j});\n                regions.push({i1, mid_j + 1, mid_i, j2});\n                regions.push({mid_i + 1, j1, i2, mid_j});\n                regions.push({mid_i + 1, mid_j + 1, i2, j2});\n            } else {\n                for (const auto& p : points) {\n                    if (operations_used < max_operations) {\n                        drill(grid, p.i, p.j);\n                        operations_used++;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (operations_used < max_operations) {\n        vector<pair<double, Point>> candidates;\n        for (int i = 0; i < grid.N; ++i) {\n            for (int j = 0; j < grid.N; ++j) {\n                if (grid.drilled_values[i][j] == -1) {\n                    candidates.emplace_back(grid.estimated_values[i][j], Point(i, j));\n                }\n            }\n        }\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        for (const auto& [_, p] : candidates) {\n            if (operations_used >= max_operations) break;\n            drill(grid, p.i, p.j);\n            operations_used++;\n        }\n    }\n}\n\nvoid infer_oil_fields(GridInfo& grid) {\n    for (const auto& field : grid.oil_fields) {\n        vector<pair<int, Point>> possible_positions;\n        \n        for (int di = 0; di <= grid.N - field.cells.back().i; ++di) {\n            for (int dj = 0; dj <= grid.N - field.cells.back().j; ++dj) {\n                int score = 0;\n                for (const auto& cell : field.cells) {\n                    int i = di + cell.i;\n                    int j = dj + cell.j;\n                    if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                        if (grid.drilled_values[i][j] > 0) {\n                            score += grid.drilled_values[i][j];\n                        } else if (grid.drilled_values[i][j] == 0) {\n                            score = -1;\n                            break;\n                        }\n                    }\n                }\n                if (score > 0) {\n                    possible_positions.emplace_back(score, Point(di, dj));\n                }\n            }\n        }\n        \n        sort(possible_positions.rbegin(), possible_positions.rend());\n        \n        for (int idx = 0; idx < min(3, (int)possible_positions.size()); ++idx) {\n            const auto& [_, pos] = possible_positions[idx];\n            double weight = idx == 0 ? 1.0 : 0.5;\n            \n            for (const auto& cell : field.cells) {\n                int i = pos.i + cell.i;\n                int j = pos.j + cell.j;\n                if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                    if (grid.drilled_values[i][j] == -1) {\n                        grid.estimated_values[i][j] += weight;\n                    }\n                }\n            }\n        }\n    }\n}\n\nset<Point> determine_answer(GridInfo& grid) {\n    set<Point> answer;\n    \n    answer.insert(grid.oil_squares.begin(), grid.oil_squares.end());\n    \n    for (int i = 0; i < grid.N; ++i) {\n        for (int j = 0; j < grid.N; ++j) {\n            if (grid.drilled_values[i][j] == -1 && grid.estimated_values[i][j] > 0.5) {\n                answer.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return answer;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double epsilon;\n    cin >> N >> M >> epsilon;\n    \n    GridInfo grid(N, M, epsilon);\n    read_input(grid);\n    \n    int max_operations = 2 * N * N;\n    \n    explore_grid(grid, max_operations / 2);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations * 3 / 4);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations);\n    \n    set<Point> answer = determine_answer(grid);\n    \n    bool correct = submit_answer(grid, answer);\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <cassert>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    \n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int i0, int j0, int i1, int j1) : i0(i0), j0(j0), i1(i1), j1(j1) {}\n    \n    int area() const {\n        return (i1 - i0) * (j1 - j0);\n    }\n    \n    bool operator==(const Rectangle& other) const {\n        return i0 == other.i0 && j0 == other.j0 && i1 == other.i1 && j1 == other.j1;\n    }\n};\n\nstruct DayLayout {\n    vector<Rectangle> rectangles;\n    vector<vector<int>> horizontal_partitions;  // H_{d,i,j}\n    vector<vector<int>> vertical_partitions;    // V_{d,i,j}\n    \n    DayLayout(int W) {\n        horizontal_partitions.resize(W-1, vector<int>(W, 0));\n        vertical_partitions.resize(W, vector<int>(W-1, 0));\n    }\n    \n    void update_partitions(int W) {\n        // Reset partitions\n        for (auto& row : horizontal_partitions) fill(row.begin(), row.end(), 0);\n        for (auto& row : vertical_partitions) fill(row.begin(), row.end(), 0);\n        \n        // Set partitions based on rectangles\n        for (const auto& rect : rectangles) {\n            // Horizontal partitions (top and bottom edges)\n            if (rect.i0 > 0) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i0-1][j] = 1;\n                }\n            }\n            if (rect.i1 < W) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i1-1][j] = 1;\n                }\n            }\n            \n            // Vertical partitions (left and right edges)\n            if (rect.j0 > 0) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j0-1] = 1;\n                }\n            }\n            if (rect.j1 < W) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j1-1] = 1;\n                }\n            }\n        }\n    }\n};\n\nclass EventHallOptimizer {\nprivate:\n    int W, D, N;\n    vector<vector<int>> desired_areas;\n    vector<DayLayout> layouts;\n    mt19937 rng;\n    \npublic:\n    EventHallOptimizer(int W, int D, int N, const vector<vector<int>>& areas)\n        : W(W), D(D), N(N), desired_areas(areas) {\n        // Initialize random number generator\n        rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n        \n        layouts.reserve(D);\n        for (int d = 0; d < D; ++d) {\n            layouts.emplace_back(W);\n        }\n    }\n    \n    void solve() {\n        // Generate initial layout for day 0\n        generate_initial_layout(0);\n        layouts[0].update_partitions(W);\n        \n        // Generate layouts for subsequent days\n        for (int d = 1; d < D; ++d) {\n            // Start with previous day's layout as base\n            layouts[d] = layouts[d-1];\n            \n            // Optimize layout for day d\n            optimize_layout(d);\n            layouts[d].update_partitions(W);\n        }\n    }\n    \n    void generate_initial_layout(int day) {\n        vector<pair<int, int>> area_indices;\n        for (int k = 0; k < N; ++k) {\n            area_indices.emplace_back(desired_areas[day][k], k);\n        }\n        sort(area_indices.begin(), area_indices.end(), greater<pair<int, int>>());\n        \n        vector<Rectangle> rects(N);\n        vector<bool> used(N, false);\n        \n        // Use a space-filling curve approach\n        int current_i = 0, current_j = 0;\n        \n        for (const auto& [area, idx] : area_indices) {\n            // Find best fitting rectangle\n            Rectangle best_rect;\n            int best_score = -1;\n            \n            // Try different starting positions and sizes\n            for (int start_i = current_i; start_i < W - 1; ++start_i) {\n                for (int start_j = (start_i == current_i ? current_j : 0); start_j < W - 1; ++start_j) {\n                    // Try different aspect ratios\n                    for (int aspect = 1; aspect <= 4; ++aspect) {\n                        int height = sqrt(area * aspect);\n                        int width = area / height;\n                        if (width * height < area) width++;\n                        \n                        // Ensure rectangle fits\n                        if (start_i + height > W || start_j + width > W) continue;\n                        \n                        Rectangle rect(start_i, start_j, start_i + height, start_j + width);\n                        \n                        // Check for overlaps\n                        bool overlap = false;\n                        for (int k = 0; k < N; ++k) {\n                            if (used[k] && rectangles_overlap(rect, rects[k])) {\n                                overlap = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!overlap) {\n                            int score = rect.area();\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (best_score == -1) {\n                // Fallback: place at current position with minimum size\n                int side = ceil(sqrt(area));\n                best_rect = Rectangle(current_i, current_j, \n                                    min(current_i + side, W), \n                                    min(current_j + side, W));\n            }\n            \n            rects[idx] = best_rect;\n            used[idx] = true;\n            \n            // Update current position\n            current_j = best_rect.j1;\n            if (current_j >= W - 1) {\n                current_j = 0;\n                current_i = best_rect.i1;\n            }\n        }\n        \n        layouts[day].rectangles = rects;\n    }\n    \n    void optimize_layout(int day) {\n        const double initial_temp = 1000.0;\n        const double cooling_rate = 0.95;\n        const int iterations = 1000;\n        \n        double temp = initial_temp;\n        vector<Rectangle> current_rects = layouts[day].rectangles;\n        int current_cost = calculate_total_cost(day, current_rects);\n        \n        for (int iter = 0; iter < iterations; ++iter) {\n            // Generate neighbor solution\n            vector<Rectangle> neighbor_rects = current_rects;\n            apply_random_move(day, neighbor_rects);\n            \n            // Calculate cost\n            int neighbor_cost = calculate_total_cost(day, neighbor_rects);\n            \n            // Accept or reject\n            int delta = neighbor_cost - current_cost;\n            if (delta < 0 || exp(-delta / temp) > generate_random_double()) {\n                current_rects = neighbor_rects;\n                current_cost = neighbor_cost;\n            }\n            \n            // Cool down\n            temp *= cooling_rate;\n        }\n        \n        layouts[day].rectangles = current_rects;\n    }\n    \n    void apply_random_move(int day, vector<Rectangle>& rects) {\n        uniform_int_distribution<int> move_dist(0, 2);\n        int move_type = move_dist(rng);\n        \n        switch (move_type) {\n            case 0: // Resize rectangle\n                resize_random_rectangle(rects);\n                break;\n            case 1: // Move rectangle\n                move_random_rectangle(rects);\n                break;\n            case 2: // Swap two rectangles\n                swap_random_rectangles(rects);\n                break;\n        }\n        \n        // Ensure no overlaps\n        fix_overlaps(rects);\n    }\n    \n    void resize_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-10, 10);\n        int di0 = delta_dist(rng);\n        int dj0 = delta_dist(rng);\n        int di1 = delta_dist(rng);\n        int dj1 = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        rect.i0 = max(0, min(W-1, rect.i0 + di0));\n        rect.j0 = max(0, min(W-1, rect.j0 + dj0));\n        rect.i1 = max(rect.i0+1, min(W, rect.i1 + di1));\n        rect.j1 = max(rect.j0+1, min(W, rect.j1 + dj1));\n    }\n    \n    void move_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-5, 5);\n        int di = delta_dist(rng);\n        int dj = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        int height = rect.i1 - rect.i0;\n        int width = rect.j1 - rect.j0;\n        \n        rect.i0 = max(0, min(W - height, rect.i0 + di));\n        rect.j0 = max(0, min(W - width, rect.j0 + dj));\n        rect.i1 = rect.i0 + height;\n        rect.j1 = rect.j0 + width;\n    }\n    \n    void swap_random_rectangles(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx1 = rect_dist(rng);\n        int idx2 = rect_dist(rng);\n        \n        if (idx1 != idx2) {\n            swap(rects[idx1], rects[idx2]);\n        }\n    }\n    \n    void fix_overlaps(vector<Rectangle>& rects) {\n        // Simple overlap resolution: shrink overlapping rectangles\n        for (int i = 0; i < N; ++i) {\n            for (int j = i+1; j < N; ++j) {\n                if (rectangles_overlap(rects[i], rects[j])) {\n                    // Shrink the smaller rectangle\n                    if (rects[i].area() < rects[j].area()) {\n                        shrink_rectangle(rects[i], rects[j]);\n                    } else {\n                        shrink_rectangle(rects[j], rects[i]);\n                    }\n                }\n            }\n        }\n    }\n    \n    void shrink_rectangle(Rectangle& to_shrink, const Rectangle& other) {\n        // Find intersection and shrink accordingly\n        int left = max(to_shrink.j0, other.j0);\n        int right = min(to_shrink.j1, other.j1);\n        int top = max(to_shrink.i0, other.i0);\n        int bottom = min(to_shrink.i1, other.i1);\n        \n        if (left < right && top < bottom) {\n            // Calculate overlap sizes\n            int overlap_width = right - left;\n            int overlap_height = bottom - top;\n            \n            // Shrink in the direction with smaller overlap\n            if (overlap_width < overlap_height) {\n                if (other.j0 <= to_shrink.j0) {\n                    to_shrink.j0 = right;\n                } else {\n                    to_shrink.j1 = left;\n                }\n            } else {\n                if (other.i0 <= to_shrink.i0) {\n                    to_shrink.i0 = bottom;\n                } else {\n                    to_shrink.i1 = top;\n                }\n            }\n        }\n    }\n    \n    int calculate_total_cost(int day, const vector<Rectangle>& rects) {\n        int cost = 0;\n        \n        // Area penalty cost\n        for (int k = 0; k < N; ++k) {\n            int actual_area = rects[k].area();\n            if (actual_area < desired_areas[day][k]) {\n                cost += 100 * (desired_areas[day][k] - actual_area);\n            }\n        }\n        \n        // Partition change cost (except for day 0)\n        if (day > 0) {\n            // Create temporary layout to calculate partitions\n            DayLayout temp_layout(W);\n            temp_layout.rectangles = rects;\n            temp_layout.update_partitions(W);\n            \n            // Calculate partition differences\n            for (int i = 0; i < W-1; ++i) {\n                for (int j = 0; j < W; ++j) {\n                    if (layouts[day-1].horizontal_partitions[i][j] != temp_layout.horizontal_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n            \n            for (int i = 0; i < W; ++i) {\n                for (int j = 0; j < W-1; ++j) {\n                    if (layouts[day-1].vertical_partitions[i][j] != temp_layout.vertical_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n        }\n        \n        return cost;\n    }\n    \n    bool rectangles_overlap(const Rectangle& r1, const Rectangle& r2) {\n        return !(r1.i1 <= r2.i0 || r2.i1 <= r1.i0 || r1.j1 <= r2.j0 || r2.j1 <= r1.j0);\n    }\n    \n    double generate_random_double() {\n        return uniform_real_distribution<double>(0.0, 1.0)(rng);\n    }\n    \n    void output_solution() {\n        for (int d = 0; d < D; ++d) {\n            for (int k = 0; k < N; ++k) {\n                const auto& rect = layouts[d].rectangles[k];\n                cout << rect.i0 << \" \" << rect.j0 << \" \" << rect.i1 << \" \" << rect.j1 << \"\\n\";\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> desired_areas(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> desired_areas[d][k];\n        }\n    }\n    \n    EventHallOptimizer optimizer(W, D, N, desired_areas);\n    optimizer.solve();\n    optimizer.output_solution();\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<pair<int, pair<int, int>>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_improvement = -1;\n        int best_stamp = -1;\n        int best_p = -1;\n        int best_q = -1;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    int improvement = 0;\n                    \n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int v = board[p + i][q + j];\n                            int x = stamps[m][i][j];\n                            \n                            // Calculate the improvement\n                            int current_mod = v % MOD;\n                            int new_mod = (v + x) % MOD;\n                            int cell_improvement = new_mod - current_mod;\n                            if (cell_improvement < 0) cell_improvement += MOD;\n                            \n                            improvement += cell_improvement;\n                        }\n                    }\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_stamp = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_improvement <= 0) {\n            // No improvement, stop early\n            break;\n        }\n        \n        operations.push_back({best_stamp, {best_p, best_q}});\n        \n        // Apply the stamp\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_stamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << endl;\n    for (auto &op : operations) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <set>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 5;\n\nchar move_towards(int i0, int j0, int i1, int j1, int grid[N][N], int crane_pos[N][2], int crane_id, bool is_large, int crane_carrying[N]) {\n    vector<char> dirs = {'U', 'D', 'L', 'R'};\n    vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    int current_dist = abs(i0 - i1) + abs(j0 - j1);\n    vector<char> good_moves;\n    vector<char> ok_moves;\n\n    for (int idx = 0; idx < 4; idx++) {\n        int ni = i0 + moves[idx].first;\n        int nj = j0 + moves[idx].second;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n            continue;\n        }\n\n        if (crane_carrying[crane_id] != -1 && !is_large) {\n            if (grid[ni][nj] != -1) {\n                continue;\n            }\n        }\n\n        int new_dist = abs(ni - i1) + abs(nj - j1);\n        if (new_dist < current_dist) {\n            good_moves.push_back(dirs[idx]);\n        } else if (new_dist == current_dist) {\n            ok_moves.push_back(dirs[idx]);\n        }\n    }\n\n    if (!good_moves.empty()) {\n        return good_moves[0];\n    } else if (!ok_moves.empty()) {\n        return ok_moves[0];\n    } else {\n        return '.';\n    }\n}\n\nint main() {\n    int n_val;\n    cin >> n_val;\n    int A[N][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    int grid[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n\n    int crane_pos[N][2];\n    for (int i = 0; i < N; i++) {\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n    }\n\n    int crane_carrying[N];\n    for (int i = 0; i < N; i++) {\n        crane_carrying[i] = -1;\n    }\n\n    int next_container_index[N] = {0};\n    int next_dispatch[N];\n    for (int i = 0; i < N; i++) {\n        next_dispatch[i] = 5 * i;\n    }\n\n    bool bombed[N] = {false};\n    vector<string> crane_actions(N);\n\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) {\n            if (next_container_index[i] < N) {\n                bool crane_holding_at_gate = false;\n                for (int c = 0; c < N; c++) {\n                    if (!bombed[c] && crane_pos[c][0] == i && crane_pos[c][1] == 0 && crane_carrying[c] != -1) {\n                        crane_holding_at_gate = true;\n                        break;\n                    }\n                }\n                if (grid[i][0] == -1 && !crane_holding_at_gate) {\n                    grid[i][0] = A[i][next_container_index[i]];\n                    next_container_index[i]++;\n                }\n            }\n        }\n\n        vector<char> actions(N, '.');\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                actions[c] = '.';\n                continue;\n            }\n\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            int carrying = crane_carrying[c];\n\n            if (carrying != -1) {\n                int container_id = carrying;\n                int target_gate = container_id / N;\n\n                if (container_id == next_dispatch[target_gate]) {\n                    if (i0 == target_gate && j0 == N-1) {\n                        actions[c] = 'Q';\n                    } else {\n                        actions[c] = move_towards(i0, j0, target_gate, N-1, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (j0 >= 1 && j0 <= 3 && grid[i0][j0] == -1) {\n                        actions[c] = 'Q';\n                    } else {\n                        vector<pair<int, int>> candidates;\n                        for (int i = 0; i < N; i++) {\n                            for (int j = 1; j <= 3; j++) {\n                                if (grid[i][j] == -1) {\n                                    candidates.push_back({i, j});\n                                }\n                            }\n                        }\n                        if (!candidates.empty()) {\n                            auto best = candidates[0];\n                            int best_dist = abs(i0 - best.first) + abs(j0 - best.second);\n                            for (auto cand : candidates) {\n                                int dist = abs(i0 - cand.first) + abs(j0 - cand.second);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best = cand;\n                                }\n                            }\n                            actions[c] = move_towards(i0, j0, best.first, best.second, grid, crane_pos, c, (c==0), crane_carrying);\n                        } else {\n                            actions[c] = '.';\n                        }\n                    }\n                }\n            } else {\n                vector<tuple<int, int, int>> containers;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int cid = grid[i][j];\n                            if (cid / N == c) {\n                                containers.push_back(make_tuple(i, j, cid));\n                            }\n                        }\n                    }\n                }\n                if (!containers.empty()) {\n                    auto best = containers[0];\n                    int best_dist = abs(i0 - get<0>(best)) + abs(j0 - get<1>(best));\n                    for (auto cont : containers) {\n                        int dist = abs(i0 - get<0>(cont)) + abs(j0 - get<1>(cont));\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best = cont;\n                        }\n                    }\n                    int ti = get<0>(best), tj = get<1>(best);\n                    if (i0 == ti && j0 == tj) {\n                        actions[c] = 'P';\n                    } else {\n                        actions[c] = move_towards(i0, j0, ti, tj, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (i0 == c && j0 == 0) {\n                        actions[c] = '.';\n                    } else {\n                        actions[c] = move_towards(i0, j0, c, 0, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> next_pos(N);\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'U') {\n                next_pos[c] = {i0-1, j0};\n            } else if (act == 'D') {\n                next_pos[c] = {i0+1, j0};\n            } else if (act == 'L') {\n                next_pos[c] = {i0, j0-1};\n            } else if (act == 'R') {\n                next_pos[c] = {i0, j0+1};\n            } else {\n                next_pos[c] = {i0, j0};\n            }\n        }\n\n        set<int> involved;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == make_pair(crane_pos[j][0], crane_pos[j][1]) && \n                    next_pos[j] == make_pair(crane_pos[i][0], crane_pos[i][1])) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n\n        for (int c : involved) {\n            if (!bombed[c]) {\n                actions[c] = '.';\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'P') {\n                if (crane_carrying[c] == -1 && grid[i0][j0] != -1) {\n                    crane_carrying[c] = grid[i0][j0];\n                    grid[i0][j0] = -1;\n                }\n            } else if (act == 'Q') {\n                if (crane_carrying[c] != -1 && grid[i0][j0] == -1) {\n                    grid[i0][j0] = crane_carrying[c];\n                    crane_carrying[c] = -1;\n                }\n            } else if (act == 'B') {\n                if (crane_carrying[c] == -1) {\n                    bombed[c] = true;\n                }\n            } else if (act == 'U' || act == 'D' || act == 'L' || act == 'R') {\n                crane_pos[c][0] = next_pos[c].first;\n                crane_pos[c][1] = next_pos[c].second;\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container_id = grid[i][N-1];\n                grid[i][N-1] = -1;\n                next_dispatch[i] = container_id + 1;\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            crane_actions[c] += actions[c];\n        }\n\n        int total_dispatched = 0;\n        for (int i = 0; i < N; i++) {\n            total_dispatched += (next_dispatch[i] - 5*i);\n        }\n        if (total_dispatched == N*N) {\n            break;\n        }\n    }\n\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        if (crane_actions[i].size() > max_len) {\n            max_len = crane_actions[i].size();\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        while (crane_actions[i].size() < max_len) {\n            crane_actions[i] += '.';\n        }\n        cout << crane_actions[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <tuple>\n#include <string>\nusing namespace std;\n\nvector<string> get_manhattan_path(pair<int, int> start, pair<int, int> end) {\n    vector<string> path;\n    int x1 = start.first, y1 = start.second;\n    int x2 = end.first, y2 = end.second;\n    while (x1 < x2) {\n        path.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        path.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        path.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        path.push_back(\"L\");\n        y1--;\n    }\n    return path;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    long long base = 0;\n    vector<tuple<int, int, int>> sources;\n    vector<tuple<int, int, int>> sinks;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                sources.emplace_back(i, j, grid[i][j]);\n                base += grid[i][j];\n            } else if (grid[i][j] < 0) {\n                sinks.emplace_back(i, j, -grid[i][j]);\n                base += -grid[i][j];\n            }\n        }\n    }\n\n    long long total_soil = base / 2;\n\n    if (total_soil == 0) {\n        cout << endl;\n        return 0;\n    }\n\n    pair<int, int> best_hub;\n    long long best_cost = LLONG_MAX;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pair<int, int> hub = {i, j};\n\n            vector<tuple<int, int, int>> sorted_sources = sources;\n            sort(sorted_sources.begin(), sorted_sources.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            vector<tuple<int, int, int>> sorted_sinks = sinks;\n            sort(sorted_sinks.begin(), sorted_sinks.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            long long cost_transport = 0;\n            pair<int, int> current = {0, 0};\n            long long load = 0;\n\n            if (!sorted_sources.empty()) {\n                auto first = sorted_sources[0];\n                int d = abs(current.first - get<0>(first)) + abs(current.second - get<1>(first));\n                cost_transport += d * 100;\n                current = {get<0>(first), get<1>(first)};\n                load += get<2>(first);\n\n                for (int idx = 1; idx < sorted_sources.size(); idx++) {\n                    auto src = sorted_sources[idx];\n                    d = abs(current.first - get<0>(src)) + abs(current.second - get<1>(src));\n                    cost_transport += d * (100 + load);\n                    current = {get<0>(src), get<1>(src)};\n                    load += get<2>(src);\n                }\n\n                d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * (100 + load);\n            } else {\n                int d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * 100;\n            }\n\n            current = hub;\n            load = total_soil;\n\n            for (int idx = 0; idx < sorted_sinks.size(); idx++) {\n                auto sink = sorted_sinks[idx];\n                int d = abs(current.first - get<0>(sink)) + abs(current.second - get<1>(sink));\n                cost_transport += d * (100 + load);\n                current = {get<0>(sink), get<1>(sink)};\n                load -= get<2>(sink);\n            }\n\n            long long total_cost = base + cost_transport;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                best_hub = hub;\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> sorted_sources = sources;\n    sort(sorted_sources.begin(), sorted_sources.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<tuple<int, int, int>> sorted_sinks = sinks;\n    sort(sorted_sinks.begin(), sorted_sinks.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<string> operations;\n    pair<int, int> current_pos = {0, 0};\n\n    if (!sorted_sources.empty()) {\n        auto first = sorted_sources[0];\n        pair<int, int> first_pos = {get<0>(first), get<1>(first)};\n        vector<string> path = get_manhattan_path(current_pos, first_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"+\" + to_string(get<2>(first)));\n        current_pos = first_pos;\n\n        for (int idx = 1; idx < sorted_sources.size(); idx++) {\n            auto src = sorted_sources[idx];\n            pair<int, int> src_pos = {get<0>(src), get<1>(src)};\n            vector<string> path = get_manhattan_path(current_pos, src_pos);\n            operations.insert(operations.end(), path.begin(), path.end());\n            operations.push_back(\"+\" + to_string(get<2>(src)));\n            current_pos = src_pos;\n        }\n\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    } else {\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    }\n\n    for (auto sink : sorted_sinks) {\n        pair<int, int> sink_pos = {get<0>(sink), get<1>(sink)};\n        vector<string> path = get_manhattan_path(current_pos, sink_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"-\" + to_string(get<2>(sink)));\n        current_pos = sink_pos;\n    }\n\n    for (const string& op : operations) {\n        cout << op << endl;\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    // For each turn\n    for (int t = 0; t < T; t++) {\n        // Calculate scores for each seed\n        vector<pair<double, int>> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            // Calculate total value\n            int total_value = accumulate(X[i].begin(), X[i].end(), 0);\n            \n            // Find maximum value in any single criterion\n            int max_criterion = *max_element(X[i].begin(), X[i].end());\n            \n            // Calculate sum of top 5 criteria\n            vector<int> sorted_criteria = X[i];\n            sort(sorted_criteria.rbegin(), sorted_criteria.rend());\n            int top5_sum = accumulate(sorted_criteria.begin(), sorted_criteria.begin() + min(5, M), 0);\n            \n            // Combined score with weights\n            double score = 0.5 * total_value + 0.3 * max_criterion + 0.2 * top5_sum;\n            seed_scores[i] = {score, i};\n        }\n        \n        // Sort seeds by score in descending order\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Select top 36 seeds\n        vector<int> selected_seeds;\n        for (int i = 0; i < N * N; i++) {\n            selected_seeds.push_back(seed_scores[i].second);\n        }\n        \n        // Create grid arrangement\n        vector<vector<int>> A(N, vector<int>(N, 0));\n        \n        // Strategy: Place seeds with complementary strengths adjacent to each other\n        // Sort selected seeds by their strongest criterion\n        vector<pair<int, int>> seeds_by_max_criterion;\n        for (int seed : selected_seeds) {\n            int max_val = *max_element(X[seed].begin(), X[seed].end());\n            seeds_by_max_criterion.push_back({max_val, seed});\n        }\n        \n        // Sort by maximum criterion value\n        sort(seeds_by_max_criterion.rbegin(), seeds_by_max_criterion.rend());\n        \n        // Place in a checkerboard pattern, alternating high and medium seeds\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if ((i + j) % 2 == 0) {\n                    // Place a seed with high maximum criterion\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                } else {\n                    // Place a seed with balanced criteria\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                }\n            }\n        }\n        \n        // Output the arrangement\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds for next turn\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> X[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <climits>\nusing namespace std;\n\nint main() {\n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s_grid(N);\n    vector<string> t_grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> s_grid[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t_grid[i];\n    }\n    \n    set<pair<int, int>> S;\n    set<pair<int, int>> T;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0') {\n                S.insert({i, j});\n            }\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0') {\n                T.insert({i, j});\n            }\n        }\n    }\n    \n    int V_prime = 2;\n    cout << V_prime << endl;\n    cout << \"0 1\" << endl;\n    int rx0 = (N-1)/2;\n    int ry0 = (N-1)/2;\n    cout << rx0 << \" \" << ry0 << endl;\n    \n    const vector<int> dx = {0, 1, 0, -1};\n    const vector<int> dy = {1, 0, -1, 0};\n    const vector<char> move_dir = {'R', 'D', 'L', 'U'};\n    \n    int rx = rx0;\n    int ry = ry0;\n    int dir = 0;\n    \n    auto manhattan_move = [&](int x1, int y1, int x2, int y2) -> vector<char> {\n        vector<char> moves;\n        while (x1 < x2) {\n            moves.push_back('D');\n            x1++;\n        }\n        while (x1 > x2) {\n            moves.push_back('U');\n            x1--;\n        }\n        while (y1 < y2) {\n            moves.push_back('R');\n            y1++;\n        }\n        while (y1 > y2) {\n            moves.push_back('L');\n            y1--;\n        }\n        return moves;\n    };\n    \n    while (!S.empty()) {\n        pair<int, int> best_pos;\n        pair<int, int> best_adj;\n        int best_dist = INT_MAX;\n        \n        for (const auto& pos : S) {\n            int a = pos.first;\n            int b = pos.second;\n            for (int d = 0; d < 4; d++) {\n                int x = a + dx[d];\n                int y = b + dy[d];\n                if (x < 0 || x >= N || y < 0 || y >= N) continue;\n                int dist = abs(rx - x) + abs(ry - y);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_pos = {a, b};\n                    best_adj = {x, y};\n                }\n            }\n        }\n        \n        int a = best_pos.first;\n        int b = best_pos.second;\n        int x = best_adj.first;\n        int y = best_adj.second;\n        \n        vector<char> path = manhattan_move(rx, ry, x, y);\n        for (char move : path) {\n            string command = string(V_prime, '.');\n            command[0] = move;\n            cout << command << endl;\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        int desired_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (dx[d] == a - x && dy[d] == b - y) {\n                desired_dir = d;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd;\n            if (diff == 1 || diff == 3) {\n                rot_cmd = 'R';\n                dir = (dir + 1) % 4;\n            } else {\n                rot_cmd = 'L';\n                dir = (dir + 3) % 4;\n            }\n            string command = string(V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << endl;\n        }\n        \n        string grab_command = string(V_prime, '.');\n        grab_command[V_prime] = 'P';\n        cout << grab_command << endl;\n        S.erase({a, b});\n        \n        best_dist = INT_MAX;\n        pair<int, int> best_target;\n        pair<int, int> best_adj_target;\n        for (const auto& target : T) {\n            int c = target.first;\n            int d = target.second;\n            for (int dir_adj = 0; dir_adj < 4; dir_adj++) {\n                int x_target = c + dx[dir_adj];\n                int y_target = d + dy[dir_adj];\n                if (x_target < 0 || x_target >= N || y_target < 0 || y_target >= N) continue;\n                int dist = abs(rx - x_target) + abs(ry - y_target);\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_target = {c, d};\n                    best_adj_target = {x_target, y_target};\n                }\n            }\n        }\n        \n        int c = best_target.first;\n        int d = best_target.second;\n        int x_target = best_adj_target.first;\n        int y_target = best_adj_target.second;\n        \n        path = manhattan_move(rx, ry, x_target, y_target);\n        for (char move : path) {\n            string command = string(V_prime, '.');\n            command[0] = move;\n            cout << command << endl;\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        desired_dir = -1;\n        for (int dir_val = 0; dir_val < 4; dir_val++) {\n            if (dx[dir_val] == c - x_target && dy[dir_val] == d - y_target) {\n                desired_dir = dir_val;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd;\n            if (diff == 1 || diff == 3) {\n                rot_cmd = 'R';\n                dir = (dir + 1) % 4;\n            } else {\n                rot_cmd = 'L';\n                dir = (dir + 3) % 4;\n            }\n            string command = string(V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << endl;\n        }\n        \n        string release_command = string(V_prime, '.');\n        release_command[V_prime] = 'P';\n        cout << release_command << endl;\n        T.erase({c, d});\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <chrono>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Point {\n    int x, y;\n    \n    bool operator<(const Point& other) const {\n        return tie(x, y) < tie(other.x, other.y);\n    }\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Polygon {\n    vector<Point> vertices;\n    \n    void add_vertex(const Point& p) {\n        vertices.push_back(p);\n    }\n    \n    double perimeter() const {\n        double perim = 0;\n        for (int i = 0; i < vertices.size(); ++i) {\n            int j = (i + 1) % vertices.size();\n            perim += abs(vertices[i].x - vertices[j].x) + abs(vertices[i].y - vertices[j].y);\n        }\n        return perim;\n    }\n    \n    // Point-in-polygon test for axis-aligned polygon\n    bool contains(const Point& p) const {\n        int n = vertices.size();\n        bool inside = false;\n        \n        for (int i = 0, j = n - 1; i < n; j = i++) {\n            const Point& vi = vertices[i];\n            const Point& vj = vertices[j];\n            \n            if ((vi.y == vj.y) && (p.y == vi.y) && \n                (p.x >= min(vi.x, vj.x)) && (p.x <= max(vi.x, vj.x))) {\n                // Point is on a horizontal edge\n                return true;\n            }\n            \n            if ((vi.x == vj.x) && (p.x == vi.x) && \n                (p.y >= min(vi.y, vj.y)) && (p.y <= max(vi.y, vj.y))) {\n                // Point is on a vertical edge\n                return true;\n            }\n            \n            if (((vi.y > p.y) != (vj.y > p.y)) &&\n                (p.x < (vj.x - vi.x) * (p.y - vi.y) / (vj.y - vi.y) + vi.x)) {\n                inside = !inside;\n            }\n        }\n        \n        return inside;\n    }\n};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<Point> mackerels(N);\n    vector<Point> sardines(N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].x >> mackerels[i].y;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].x >> sardines[i].y;\n    }\n    \n    // Find clusters of mackerels\n    const int cluster_size = 50; // Number of mackerels per cluster\n    vector<vector<Point>> mackerel_clusters;\n    \n    // Simple clustering: group nearby mackerels\n    vector<bool> used(N, false);\n    for (int i = 0; i < N; ++i) {\n        if (!used[i]) {\n            vector<Point> cluster;\n            cluster.push_back(mackerels[i]);\n            used[i] = true;\n            \n            // Find nearby mackerels\n            for (int j = i + 1; j < N && cluster.size() < cluster_size; ++j) {\n                if (!used[j]) {\n                    int dx = mackerels[i].x - mackerels[j].x;\n                    int dy = mackerels[i].y - mackerels[j].y;\n                    if (dx * dx + dy * dy < 10000 * 10000) { // Within 10000 units\n                        cluster.push_back(mackerels[j]);\n                        used[j] = true;\n                    }\n                }\n            }\n            \n            if (cluster.size() >= 10) { // Only consider clusters with at least 10 mackerels\n                mackerel_clusters.push_back(cluster);\n            }\n        }\n    }\n    \n    // Sort clusters by size (descending)\n    sort(mackerel_clusters.begin(), mackerel_clusters.end(), \n         [](const vector<Point>& a, const vector<Point>& b) {\n             return a.size() > b.size();\n         });\n    \n    // Calculate the bounding box for each cluster\n    vector<tuple<int, int, int, int>> cluster_boxes;\n    for (const auto& cluster : mackerel_clusters) {\n        int min_x = 100000, max_x = 0;\n        int min_y = 100000, max_y = 0;\n        \n        for (const auto& p : cluster) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        cluster_boxes.emplace_back(min_x, min_y, max_x, max_y);\n    }\n    \n    // Try to create polygons for each cluster\n    Polygon best_polygon;\n    int best_score = 0;\n    \n    auto calculate_score = [](const Polygon& poly, const vector<Point>& macks, const vector<Point>& sards) {\n        int a = 0, b = 0;\n        for (const auto& p : macks) {\n            if (poly.contains(p)) {\n                a++;\n            }\n        }\n        for (const auto& p : sards) {\n            if (poly.contains(p)) {\n                b++;\n            }\n        }\n        return max(0, a - b + 1);\n    };\n    \n    // Try individual clusters\n    for (size_t i = 0; i < min(mackerel_clusters.size(), size_t(10)); ++i) {\n        const auto& box = cluster_boxes[i];\n        int min_x = get<0>(box);\n        int min_y = get<1>(box);\n        int max_x = get<2>(box);\n        int max_y = get<3>(box);\n        \n        // Create a polygon around this cluster\n        Polygon polygon;\n        polygon.add_vertex({min_x, min_y});\n        polygon.add_vertex({max_x, min_y});\n        polygon.add_vertex({max_x, max_y});\n        polygon.add_vertex({min_x, max_y});\n        \n        // Try to expand the polygon while maintaining a good score\n        const int max_expansions = 10;\n        for (int expansion = 0; expansion < max_expansions; ++expansion) {\n            // Try expanding in each direction\n            vector<Polygon> expansions;\n            \n            // Expand left\n            Polygon left_poly = polygon;\n            if (left_poly.vertices[0].x > 0) {\n                left_poly.vertices[0].x = max(0, left_poly.vertices[0].x - 1000);\n                left_poly.vertices[3].x = left_poly.vertices[0].x;\n                expansions.push_back(left_poly);\n            }\n            \n            // Expand right\n            Polygon right_poly = polygon;\n            if (right_poly.vertices[1].x < 100000) {\n                right_poly.vertices[1].x = min(100000, right_poly.vertices[1].x + 1000);\n                right_poly.vertices[2].x = right_poly.vertices[1].x;\n                expansions.push_back(right_poly);\n            }\n            \n            // Expand down\n            Polygon down_poly = polygon;\n            if (down_poly.vertices[0].y > 0) {\n                down_poly.vertices[0].y = max(0, down_poly.vertices[0].y - 1000);\n                down_poly.vertices[1].y = down_poly.vertices[0].y;\n                expansions.push_back(down_poly);\n            }\n            \n            // Expand up\n            Polygon up_poly = polygon;\n            if (up_poly.vertices[2].y < 100000) {\n                up_poly.vertices[2].y = min(100000, up_poly.vertices[2].y + 1000);\n                up_poly.vertices[3].y = up_poly.vertices[2].y;\n                expansions.push_back(up_poly);\n            }\n            \n            // Find the best expansion\n            Polygon best_expansion = polygon;\n            int best_expansion_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& exp : expansions) {\n                if (exp.perimeter() <= 400000) {\n                    int score = calculate_score(exp, mackerels, sardines);\n                    if (score > best_expansion_score) {\n                        best_expansion = exp;\n                        best_expansion_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_expansion;\n        }\n        \n        // Try to refine the polygon by adding notches to exclude sardines\n        const int max_notches = 50;\n        for (int notch = 0; notch < max_notches && polygon.vertices.size() < 1000; ++notch) {\n            // Find a sardine inside the polygon\n            vector<Point> inside_sardines;\n            for (const auto& p : sardines) {\n                if (polygon.contains(p)) {\n                    inside_sardines.push_back(p);\n                }\n            }\n            \n            if (inside_sardines.empty()) {\n                break; // No more sardines to exclude\n            }\n            \n            // Randomly select a sardine to exclude\n            uniform_int_distribution<int> dist(0, inside_sardines.size() - 1);\n            Point target = inside_sardines[dist(rng)];\n            \n            // Find the edge closest to the target sardine\n            int best_edge = -1;\n            double best_dist = numeric_limits<double>::max();\n            \n            for (int i = 0; i < polygon.vertices.size(); ++i) {\n                int j = (i + 1) % polygon.vertices.size();\n                const Point& v1 = polygon.vertices[i];\n                const Point& v2 = polygon.vertices[j];\n                \n                double dist;\n                if (v1.x == v2.x) { // Vertical edge\n                    dist = abs(target.x - v1.x);\n                } else { // Horizontal edge\n                    dist = abs(target.y - v1.y);\n                }\n                \n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_edge = i;\n                }\n            }\n            \n            if (best_edge != -1) {\n                int i = best_edge;\n                int j = (i + 1) % polygon.vertices.size();\n                const Point& v1 = polygon.vertices[i];\n                const Point& v2 = polygon.vertices[j];\n                \n                // Create a notch to exclude the sardine\n                Polygon new_polygon = polygon;\n                Point notch1, notch2;\n                \n                if (v1.x == v2.x) { // Vertical edge\n                    int x = v1.x;\n                    int y1 = min(v1.y, v2.y);\n                    int y2 = max(v1.y, v2.y);\n                    \n                    if (target.x < x) {\n                        notch1 = {x - 1000, y1 + (y2 - y1) / 3};\n                        notch2 = {x - 1000, y1 + 2 * (y2 - y1) / 3};\n                    } else {\n                        notch1 = {x + 1000, y1 + (y2 - y1) / 3};\n                        notch2 = {x + 1000, y1 + 2 * (y2 - y1) / 3};\n                    }\n                } else { // Horizontal edge\n                    int y = v1.y;\n                    int x1 = min(v1.x, v2.x);\n                    int x2 = max(v1.x, v2.x);\n                    \n                    if (target.y < y) {\n                        notch1 = {x1 + (x2 - x1) / 3, y - 1000};\n                        notch2 = {x1 + 2 * (x2 - x1) / 3, y - 1000};\n                    } else {\n                        notch1 = {x1 + (x2 - x1) / 3, y + 1000};\n                        notch2 = {x1 + 2 * (x2 - x1) / 3, y + 1000};\n                    }\n                }\n                \n                // Insert the notches\n                new_polygon.vertices.insert(new_polygon.vertices.begin() + j, notch2);\n                new_polygon.vertices.insert(new_polygon.vertices.begin() + j, notch1);\n                \n                // Check constraints\n                if (new_polygon.perimeter() <= 400000) {\n                    int score = calculate_score(new_polygon, mackerels, sardines);\n                    if (score > best_score) {\n                        best_score = score;\n                        best_polygon = new_polygon;\n                    }\n                    polygon = new_polygon;\n                }\n            }\n        }\n        \n        // Update the best polygon\n        int score = calculate_score(polygon, mackerels, sardines);\n        if (score > best_score) {\n            best_score = score;\n            best_polygon = polygon;\n        }\n    }\n    \n    // If no good cluster was found, create a simple polygon\n    if (best_polygon.vertices.empty()) {\n        best_polygon.add_vertex({0, 0});\n        best_polygon.add_vertex({100000, 0});\n        best_polygon.add_vertex({100000, 100000});\n        best_polygon.add_vertex({0, 100000});\n    }\n    \n    // Output the best polygon\n    cout << best_polygon.vertices.size() << \"\\n\";\n    for (const auto& p : best_polygon.vertices) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <cctype>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<tuple<double, double, double, double, int>> placed_rectangles;\n        double current_width = 0.0;\n        double current_height = 0.0;\n        double penalty = 0.0;\n        vector<tuple<int, int, char, int>> sequence;\n\n        for (int i = 0; i < N; i++) {\n            tuple<int, int, char, int, double, double, double, double> best_option;\n            double best_cost = 1e18;\n            bool found = false;\n\n            double cost_skip = current_width + current_height + penalty + (w_est[i] + h_est[i]);\n\n            for (int rotation : {0, 1}) {\n                double w_i = (rotation == 0) ? w_est[i] : h_est[i];\n                double h_i = (rotation == 0) ? h_est[i] : w_est[i];\n\n                for (char direction : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (const auto& rect : placed_rectangles) {\n                        refs.push_back(get<4>(rect));\n                    }\n\n                    for (int ref : refs) {\n                        double x0, y0;\n                        if (direction == 'U') {\n                            if (ref == -1) {\n                                x0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                x0 = get<0>(*it) + get<2>(*it);\n                            }\n                            y0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_x, x0) < min(r_x + r_w, x0 + w_i)) {\n                                    double candidate = r_y + r_h;\n                                    if (candidate > y0) {\n                                        y0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        } else {\n                            if (ref == -1) {\n                                y0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                y0 = get<1>(*it) + get<3>(*it);\n                            }\n                            x0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_y, y0) < min(r_y + r_h, y0 + h_i)) {\n                                    double candidate = r_x + r_w;\n                                    if (candidate > x0) {\n                                        x0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (found && best_cost < cost_skip) {\n                auto [i_opt, rot_opt, dir_opt, ref_opt, x0_opt, y0_opt, w_i_opt, h_i_opt] = best_option;\n                current_width = max(current_width, x0_opt + w_i_opt);\n                current_height = max(current_height, y0_opt + h_i_opt);\n                placed_rectangles.emplace_back(x0_opt, y0_opt, w_i_opt, h_i_opt, i_opt);\n                sequence.emplace_back(i_opt, rot_opt, dir_opt, ref_opt);\n            } else {\n                penalty += (w_est[i] + h_est[i]);\n            }\n        }\n\n        cout << sequence.size() << '\\n';\n        for (const auto& [i, rot, dir, ref] : sequence) {\n            cout << i << ' ' << rot << ' ' << dir << ' ' << ref << '\\n';\n        }\n        cout << flush;\n\n        if (turn < T - 1) {\n            int W_prime, H_prime;\n            cin >> W_prime >> H_prime;\n\n            double width_factor = 1.0;\n            if (current_width > 0) {\n                width_factor = static_cast<double>(W_prime) / current_width;\n            }\n            double height_factor = 1.0;\n            if (current_height > 0) {\n                height_factor = static_cast<double>(H_prime) / current_height;\n            }\n\n            double alpha = 0.2;\n            width_factor = 1.0 + alpha * (width_factor - 1.0);\n            height_factor = 1.0 + alpha * (height_factor - 1.0);\n\n            for (const auto& rect : placed_rectangles) {\n                int idx = get<4>(rect);\n                w_est[idx] *= width_factor;\n                h_est[idx] *= height_factor;\n                w_est[idx] = max(1.0, min(1e9, w_est[idx]));\n                h_est[idx] = max(1.0, min(1e9, h_est[idx]));\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nstruct Vertex {\n    int id;\n    int x, y;\n    int beauty;\n    vector<int> neighbors;\n    int parent;\n    int height;\n    int root;\n};\n\nint H;  // Global height limit\n\n// Function to calculate attractiveness of a solution\nlong long calculate_attractiveness(const vector<Vertex>& vertices) {\n    long long attractiveness = 0;\n    for (const auto& v : vertices) {\n        attractiveness += (long long)(v.height + 1) * v.beauty;\n    }\n    return attractiveness;\n}\n\n// Function to update heights after changing a parent\nvoid update_heights(vector<Vertex>& vertices, int v) {\n    if (vertices[v].parent == -1) {\n        vertices[v].height = 0;\n        vertices[v].root = v;\n    } else {\n        vertices[v].height = vertices[vertices[v].parent].height + 1;\n        vertices[v].root = vertices[vertices[v].parent].root;\n    }\n    \n    // Recursively update children\n    for (int u : vertices[v].neighbors) {\n        if (vertices[u].parent == v) {\n            update_heights(vertices, u);\n        }\n    }\n}\n\n// Function to check if a parent assignment is valid (height <= H)\nbool is_valid_parent(const vector<Vertex>& vertices, int v, int parent) {\n    if (parent == -1) return true;\n    \n    int height = 1;  // At least height 1 if it has a parent\n    int current = parent;\n    \n    while (current != -1 && height <= H) {\n        current = vertices[current].parent;\n        height++;\n    }\n    \n    return height <= H;\n}\n\n// Function to calculate Euclidean distance between two vertices\ndouble distance(const Vertex& a, const Vertex& b) {\n    double dx = a.x - b.x;\n    double dy = a.y - b.y;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Function to find the best parent for a vertex\nint find_best_parent(const vector<Vertex>& vertices, int v, const vector<bool>& is_root) {\n    int best_parent = -1;\n    long long best_gain = 0;\n    \n    // Consider neighbors that are roots or from different trees\n    for (int u : vertices[v].neighbors) {\n        if (is_root[u] || vertices[u].root != vertices[v].root) {\n            if (is_valid_parent(vertices, v, u)) {\n                // Calculate the gain in attractiveness if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                // Prefer parents that allow for deeper nesting in the future\n                if (new_height < H) {\n                    gain += vertices[v].beauty / 2;  // Bonus for potential future gains\n                }\n                \n                // Add a spatial component: prefer closer parents\n                double dist = distance(vertices[v], vertices[u]);\n                double spatial_factor = 1.0 / (1.0 + dist / 100.0);  // Normalize distance\n                gain = (long long)(gain * spatial_factor);\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n    }\n    \n    return best_parent;\n}\n\n// Function to perform local search\nvoid local_search(vector<Vertex>& vertices, const vector<vector<int>>& adj, int max_iterations) {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> vertex_dist(0, vertices.size() - 1);\n    \n    long long current_attractiveness = calculate_attractiveness(vertices);\n    vector<bool> is_root(vertices.size(), false);\n    for (const auto& v : vertices) {\n        if (v.parent == -1) {\n            is_root[v.id] = true;\n        }\n    }\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        int v = vertex_dist(gen);\n        \n        // Try to find a better parent for v\n        int current_parent = vertices[v].parent;\n        int best_parent = current_parent;\n        long long best_gain = 0;\n        \n        for (int u : adj[v]) {\n            if (u != current_parent && vertices[u].parent != v &&  // Avoid creating cycles\n                is_valid_parent(vertices, v, u)) {\n                \n                // Calculate the gain if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n        \n        // If we found a better parent, update the solution\n        if (best_parent != current_parent && best_gain > 0) {\n            // Remove v from its current parent's children\n            if (current_parent != -1) {\n                // No need to explicitly remove, just update parent pointer\n            }\n            \n            // Add v to its new parent\n            vertices[v].parent = best_parent;\n            update_heights(vertices, v);\n            \n            // Update root status\n            if (current_parent == -1) {\n                is_root[v] = false;\n            }\n            \n            current_attractiveness += best_gain;\n        }\n        \n        // Occasionally try to make a vertex a root\n        if (iter % 100 == 0 && vertices[v].parent != -1) {\n            int old_parent = vertices[v].parent;\n            vertices[v].parent = -1;\n            update_heights(vertices, v);\n            \n            long long new_attractiveness = calculate_attractiveness(vertices);\n            if (new_attractiveness > current_attractiveness) {\n                current_attractiveness = new_attractiveness;\n                is_root[v] = true;\n            } else {\n                // Revert the change\n                vertices[v].parent = old_parent;\n                update_heights(vertices, v);\n            }\n        }\n        \n        // Occasionally try to swap parent-child relationships\n        if (iter % 200 == 0 && vertices[v].parent != -1) {\n            int parent = vertices[v].parent;\n            \n            // Check if we can swap parent and child\n            if (vertices[parent].parent != v && is_valid_parent(vertices, parent, v)) {\n                // Temporarily swap\n                int old_v_parent = vertices[v].parent;\n                int old_parent_parent = vertices[parent].parent;\n                \n                vertices[v].parent = old_parent_parent;\n                vertices[parent].parent = v;\n                \n                update_heights(vertices, v);\n                update_heights(vertices, parent);\n                \n                long long new_attractiveness = calculate_attractiveness(vertices);\n                if (new_attractiveness > current_attractiveness) {\n                    current_attractiveness = new_attractiveness;\n                    if (old_parent_parent == -1) {\n                        is_root[v] = true;\n                    }\n                    is_root[parent] = false;\n                } else {\n                    // Revert the swap\n                    vertices[v].parent = old_v_parent;\n                    vertices[parent].parent = old_parent_parent;\n                    update_heights(vertices, v);\n                    update_heights(vertices, parent);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M >> H;\n    \n    vector<Vertex> vertices(N);\n    for (int i = 0; i < N; i++) {\n        vertices[i].id = i;\n        cin >> vertices[i].beauty;\n    }\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        vertices[u].neighbors.push_back(v);\n        vertices[v].neighbors.push_back(u);\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].x >> vertices[i].y;\n    }\n    \n    // Initialize with each vertex as its own tree\n    for (auto& v : vertices) {\n        v.parent = -1;\n        v.height = 0;\n        v.root = v.id;\n    }\n    \n    // Sort vertices by beauty (lower beauty first)\n    vector<int> vertex_ids(N);\n    for (int i = 0; i < N; i++) {\n        vertex_ids[i] = i;\n    }\n    sort(vertex_ids.begin(), vertex_ids.end(), [&](int a, int b) {\n        return vertices[a].beauty < vertices[b].beauty;\n    });\n    \n    // Greedily assign parents\n    vector<bool> is_root(N, true);\n    for (int v : vertex_ids) {\n        // Only try to assign parents to vertices that can gain from having a parent\n        if (vertices[v].beauty > 30) {  // Threshold can be adjusted\n            int best_parent = find_best_parent(vertices, v, is_root);\n            if (best_parent != -1) {\n                vertices[v].parent = best_parent;\n                is_root[v] = false;\n                update_heights(vertices, v);\n            }\n        }\n    }\n    \n    // Perform local search\n    local_search(vertices, adj, 20000);  // Increased iterations for better results\n    \n    // Output the solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertices[i].parent;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <climits>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    set<pair<int, int>> oni_set;\n    set<pair<int, int>> fuku_set;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_set.insert({i, j});\n            } else if (grid[i][j] == 'o') {\n                fuku_set.insert({i, j});\n            }\n        }\n    }\n\n    vector<pair<char, int>> moves;\n\n    while (!oni_set.empty()) {\n        int best_cost = INT_MAX;\n        pair<int, int> best_oni;\n        char best_dir;\n        int best_index;\n\n        for (auto oni : oni_set) {\n            int i = oni.first;\n            int j = oni.second;\n\n            bool safe_up = true;\n            for (int r = 0; r < i; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_up = false;\n                    break;\n                }\n            }\n\n            bool safe_down = true;\n            for (int r = i+1; r < N; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_down = false;\n                    break;\n                }\n            }\n\n            bool safe_left = true;\n            for (int c = 0; c < j; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_left = false;\n                    break;\n                }\n            }\n\n            bool safe_right = true;\n            for (int c = j+1; c < N; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_right = false;\n                    break;\n                }\n            }\n\n            if (safe_up) {\n                int cost = i + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'U';\n                    best_index = j;\n                }\n            }\n            if (safe_down) {\n                int cost = N - i;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'D';\n                    best_index = j;\n                }\n            }\n            if (safe_left) {\n                int cost = j + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'L';\n                    best_index = i;\n                }\n            }\n            if (safe_right) {\n                int cost = N - j;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'R';\n                    best_index = i;\n                }\n            }\n        }\n\n        if (best_cost == INT_MAX) {\n            break;\n        }\n\n        for (int step = 0; step < best_cost; step++) {\n            moves.push_back({best_dir, best_index});\n\n            if (best_dir == 'U') {\n                char top = grid[0][best_index];\n                grid[0][best_index] = '.';\n                if (top == 'x') {\n                    oni_set.erase({0, best_index});\n                } else if (top == 'o') {\n                    fuku_set.erase({0, best_index});\n                }\n\n                for (int r = 1; r < N; r++) {\n                    char c = grid[r][best_index];\n                    grid[r-1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r-1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r-1, best_index});\n                    }\n                }\n                grid[N-1][best_index] = '.';\n            } else if (best_dir == 'D') {\n                char bottom = grid[N-1][best_index];\n                grid[N-1][best_index] = '.';\n                if (bottom == 'x') {\n                    oni_set.erase({N-1, best_index});\n                } else if (bottom == 'o') {\n                    fuku_set.erase({N-1, best_index});\n                }\n\n                for (int r = N-2; r >= 0; r--) {\n                    char c = grid[r][best_index];\n                    grid[r+1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r+1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r+1, best_index});\n                    }\n                }\n                grid[0][best_index] = '.';\n            } else if (best_dir == 'L') {\n                char leftmost = grid[best_index][0];\n                grid[best_index][0] = '.';\n                if (leftmost == 'x') {\n                    oni_set.erase({best_index, 0});\n                } else if (leftmost == 'o') {\n                    fuku_set.erase({best_index, 0});\n                }\n\n                for (int c = 1; c < N; c++) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c-1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c-1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c-1});\n                    }\n                }\n                grid[best_index][N-1] = '.';\n            } else if (best_dir == 'R') {\n                char rightmost = grid[best_index][N-1];\n                grid[best_index][N-1] = '.';\n                if (rightmost == 'x') {\n                    oni_set.erase({best_index, N-1});\n                } else if (rightmost == 'o') {\n                    fuku_set.erase({best_index, N-1});\n                }\n\n                for (int c = N-2; c >= 0; c--) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c+1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c+1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c+1});\n                    }\n                }\n                grid[best_index][0] = '.';\n            }\n        }\n    }\n\n    for (auto move : moves) {\n        cout << move.first << \" \" << move.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    srand(0);\n    int N = 100;\n    int L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<long long, int>> candidates;\n        for (int j = 0; j < N; j++) {\n            if (j == i) continue;\n            candidates.push_back({T[j], j});\n        }\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, int>>());\n        if (candidates.size() >= 2) {\n            a[i] = candidates[0].second;\n            b[i] = candidates[1].second;\n        } else if (candidates.size() == 1) {\n            a[i] = candidates[0].second;\n            b[i] = i;\n        } else {\n            a[i] = i;\n            b[i] = i;\n        }\n    }\n\n    auto simulate = [&](const vector<int>& a_vec, const vector<int>& b_vec) {\n        vector<long long> count(N, 0);\n        int current = 0;\n        count[0] = 1;\n        for (int week = 1; week < L; week++) {\n            int next;\n            if (count[current] & 1) {\n                next = a_vec[current];\n            } else {\n                next = b_vec[current];\n            }\n            count[next]++;\n            current = next;\n        }\n        long long error = 0;\n        for (int i = 0; i < N; i++) {\n            error += abs(count[i] - T[i]);\n        }\n        return error;\n    };\n\n    long long best_error = simulate(a, b);\n    vector<int> best_a = a;\n    vector<int> best_b = b;\n\n    for (int iter = 0; iter < 100; iter++) {\n        int i = rand() % N;\n        int old_a = a[i];\n        int old_b = b[i];\n\n        a[i] = rand() % N;\n        b[i] = rand() % N;\n\n        long long new_error = simulate(a, b);\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n        } else {\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <iomanip>\n#include <sstream>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\n\nstruct City {\n    int id;\n    double cx, cy;  // estimated center coordinates\n    int lx, rx, ly, ry;  // given rectangle bounds\n    double uncertainty;  // size of the rectangle, representing uncertainty\n};\n\nstruct Edge {\n    int u, v;\n    int weight;  // estimated or actual weight\n    double estimated_dist;  // estimated distance based on center coordinates\n    \n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nstruct QueryResult {\n    vector<pair<int, int>> edges;  // edges in the MST\n};\n\nclass Solution {\npublic:\n    int N, M, Q, L, W;\n    vector<int> G;\n    vector<City> cities;\n    vector<vector<int>> groups;\n    vector<vector<Edge>> group_edges;\n    int query_count = 0;\n    \n    void read_input() {\n        cin >> N >> M >> Q >> L >> W;\n        G.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> G[i];\n        }\n        \n        cities.resize(N);\n        for (int i = 0; i < N; i++) {\n            cities[i].id = i;\n            cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n            cities[i].cx = (cities[i].lx + cities[i].rx) / 2.0;\n            cities[i].cy = (cities[i].ly + cities[i].ry) / 2.0;\n            // Calculate uncertainty as the diagonal of the rectangle\n            cities[i].uncertainty = sqrt(pow(cities[i].rx - cities[i].lx, 2) + \n                                        pow(cities[i].ry - cities[i].ly, 2));\n        }\n    }\n    \n    double estimated_distance(int i, int j) {\n        double dx = cities[i].cx - cities[j].cx;\n        double dy = cities[i].cy - cities[j].cy;\n        return sqrt(dx * dx + dy * dy);\n    }\n    \n    void group_cities() {\n        // Sort cities by their estimated center coordinates\n        vector<int> city_ids(N);\n        for (int i = 0; i < N; i++) {\n            city_ids[i] = i;\n        }\n        \n        // We'll use a simple approach: divide the sorted list into groups of the required sizes\n        sort(city_ids.begin(), city_ids.end(), [this](int a, int b) {\n            if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n            return cities[a].cy < cities[b].cy;\n        });\n        \n        // Divide into groups of specified sizes\n        groups.resize(M);\n        int start_idx = 0;\n        for (int i = 0; i < M; i++) {\n            groups[i].resize(G[i]);\n            for (int j = 0; j < G[i]; j++) {\n                groups[i][j] = city_ids[start_idx + j];\n            }\n            start_idx += G[i];\n        }\n    }\n    \n    QueryResult query_mst(const vector<int>& city_subset) {\n        assert(city_subset.size() >= 2 && city_subset.size() <= L);\n        assert(query_count < Q);\n        \n        cout << \"? \" << city_subset.size();\n        for (int city : city_subset) {\n            cout << \" \" << city;\n        }\n        cout << endl;\n        cout.flush();\n        \n        QueryResult result;\n        result.edges.resize(city_subset.size() - 1);\n        for (int i = 0; i < city_subset.size() - 1; i++) {\n            cin >> result.edges[i].first >> result.edges[i].second;\n            if (result.edges[i].first > result.edges[i].second) {\n                swap(result.edges[i].first, result.edges[i].second);\n            }\n        }\n        \n        query_count++;\n        return result;\n    }\n    \n    void gather_mst_info() {\n        group_edges.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            // For each group, perform queries to gather MST information\n            int group_size = G[i];\n            \n            // If the group is small enough, query the entire group at once\n            if (group_size <= L) {\n                vector<int> subset = groups[i];\n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n                continue;\n            }\n            \n            // For larger groups, we'll use a more sophisticated approach\n            // First, sort cities within the group by their estimated positions\n            vector<int> sorted_group = groups[i];\n            sort(sorted_group.begin(), sorted_group.end(), [this](int a, int b) {\n                if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n                return cities[a].cy < cities[b].cy;\n            });\n            \n            // We'll create a list of potential edges, sorted by estimated distance\n            vector<pair<double, pair<int, int>>> potential_edges;\n            for (int u = 0; u < group_size; u++) {\n                for (int v = u + 1; v < group_size; v++) {\n                    double dist = estimated_distance(sorted_group[u], sorted_group[v]);\n                    potential_edges.emplace_back(dist, make_pair(u, v));\n                }\n            }\n            \n            sort(potential_edges.begin(), potential_edges.end());\n            \n            // We'll select subsets for querying based on the shortest potential edges\n            set<int> selected_cities;\n            vector<vector<int>> subsets;\n            \n            // Start with the cities connected by the shortest edges\n            for (const auto& [dist, edge] : potential_edges) {\n                if (query_count >= Q) break;\n                \n                int u = edge.first;\n                int v = edge.second;\n                \n                // If both cities are already in a subset, skip\n                if (selected_cities.count(u) && selected_cities.count(v)) continue;\n                \n                // Create a new subset containing these cities and some nearby ones\n                vector<int> subset;\n                subset.push_back(sorted_group[u]);\n                subset.push_back(sorted_group[v]);\n                selected_cities.insert(u);\n                selected_cities.insert(v);\n                \n                // Add nearby cities until we reach the maximum subset size\n                for (const auto& [dist2, edge2] : potential_edges) {\n                    if (subset.size() >= L) break;\n                    \n                    int u2 = edge2.first;\n                    int v2 = edge2.second;\n                    \n                    if (u2 == u || u2 == v || v2 == u || v2 == v) {\n                        int new_city = (selected_cities.count(u2) == 0) ? u2 : v2;\n                        if (selected_cities.count(new_city) == 0) {\n                            subset.push_back(sorted_group[new_city]);\n                            selected_cities.insert(new_city);\n                        }\n                    }\n                }\n                \n                subsets.push_back(subset);\n                \n                // If we've selected all cities, we're done\n                if (selected_cities.size() >= group_size) break;\n            }\n            \n            // If we haven't selected all cities, add the remaining ones\n            for (int j = 0; j < group_size; j++) {\n                if (selected_cities.count(j) == 0) {\n                    // Create a subset with this city and some nearby ones\n                    vector<int> subset;\n                    subset.push_back(sorted_group[j]);\n                    selected_cities.insert(j);\n                    \n                    // Add the closest cities\n                    for (const auto& [dist, edge] : potential_edges) {\n                        if (subset.size() >= L) break;\n                        \n                        int u = edge.first;\n                        int v = edge.second;\n                        \n                        if (u == j || v == j) {\n                            int other = (u == j) ? v : u;\n                            if (selected_cities.count(other) == 0) {\n                                subset.push_back(sorted_group[other]);\n                                selected_cities.insert(other);\n                            }\n                        }\n                    }\n                    \n                    subsets.push_back(subset);\n                }\n            }\n            \n            // Query each subset\n            for (const auto& subset : subsets) {\n                if (query_count >= Q) break;\n                if (subset.size() < 2) continue;\n                \n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n            }\n            \n            if (query_count >= Q) break;  // We've used all our queries\n        }\n    }\n    \n    void construct_final_msts() {\n        // For each group, we'll use the edges we've gathered to construct a connected graph\n        // If we don't have enough edges to form a spanning tree, we'll add more\n        \n        for (int i = 0; i < M; i++) {\n            // We need G[i] - 1 edges to connect G[i] cities\n            \n            // First, let's create a graph from the edges we've gathered\n            vector<vector<int>> graph(G[i]);\n            map<pair<int, int>, int> edge_to_index;\n            \n            for (int j = 0; j < group_edges[i].size(); j++) {\n                const Edge& e = group_edges[i][j];\n                int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                \n                graph[u_idx].push_back(v_idx);\n                graph[v_idx].push_back(u_idx);\n                \n                edge_to_index[{min(u_idx, v_idx), max(u_idx, v_idx)}] = j;\n            }\n            \n            // Check if the graph is connected\n            vector<bool> visited(G[i], false);\n            queue<int> q;\n            q.push(0);\n            visited[0] = true;\n            int visited_count = 1;\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                for (int v : graph[u]) {\n                    if (!visited[v]) {\n                        visited[v] = true;\n                        visited_count++;\n                        q.push(v);\n                    }\n                }\n            }\n            \n            if (visited_count == G[i]) {\n                // The graph is already connected, so we can use a subset of the edges\n                // We'll use Kruskal's algorithm to find the MST\n                vector<Edge> mst_edges;\n                vector<int> parent(G[i]);\n                for (int j = 0; j < G[i]; j++) {\n                    parent[j] = j;\n                }\n                \n                function<int(int)> find = [&](int x) {\n                    if (parent[x] != x) {\n                        parent[x] = find(parent[x]);\n                    }\n                    return parent[x];\n                };\n                \n                auto unite = [&](int x, int y) {\n                    x = find(x);\n                    y = find(y);\n                    if (x != y) {\n                        parent[x] = y;\n                        return true;\n                    }\n                    return false;\n                };\n                \n                // Sort edges by estimated distance\n                sort(group_edges[i].begin(), group_edges[i].end(), \n                    [](const Edge& a, const Edge& b) {\n                        return a.estimated_dist < b.estimated_dist;\n                    });\n                \n                for (const Edge& e : group_edges[i]) {\n                    int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                    int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                    \n                    if (unite(u_idx, v_idx)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == G[i] - 1) break;\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            } else {\n                // The graph is not connected, so we need to add more edges\n                // We'll use Prim's algorithm starting from the visited component\n                \n                // First, let's create a complete graph with estimated distances\n                vector<vector<pair<int, double>>> complete_graph(G[i]);\n                for (int u = 0; u < G[i]; u++) {\n                    for (int v = u + 1; v < G[i]; v++) {\n                        double dist = estimated_distance(groups[i][u], groups[i][v]);\n                        complete_graph[u].emplace_back(v, dist);\n                        complete_graph[v].emplace_back(u, dist);\n                    }\n                }\n                \n                // Use Prim's algorithm to find the MST\n                vector<bool> in_mst(G[i], false);\n                vector<Edge> mst_edges;\n                priority_queue<pair<double, pair<int, int>>, \n                              vector<pair<double, pair<int, int>>>, \n                              greater<pair<double, pair<int, int>>>> pq;\n                \n                // Start with the visited component\n                for (int u = 0; u < G[i]; u++) {\n                    if (visited[u]) {\n                        in_mst[u] = true;\n                        for (const auto& [v, dist] : complete_graph[u]) {\n                            if (!in_mst[v]) {\n                                pq.emplace(dist, make_pair(u, v));\n                            }\n                        }\n                    }\n                }\n                \n                while (!pq.empty() && mst_edges.size() < G[i] - 1) {\n                    auto [dist, edge] = pq.top();\n                    pq.pop();\n                    int u = edge.first;\n                    int v = edge.second;\n                    \n                    if (!in_mst[v]) {\n                        in_mst[v] = true;\n                        Edge e;\n                        e.u = groups[i][u];\n                        e.v = groups[i][v];\n                        e.weight = 0;\n                        e.estimated_dist = dist;\n                        mst_edges.push_back(e);\n                        \n                        for (const auto& [next_v, next_dist] : complete_graph[v]) {\n                            if (!in_mst[next_v]) {\n                                pq.emplace(next_dist, make_pair(v, next_v));\n                            }\n                        }\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            }\n        }\n    }\n    \n    void output_solution() {\n        cout << \"!\" << endl;\n        \n        for (int i = 0; i < M; i++) {\n            // Output the cities in the group\n            for (int j = 0; j < G[i]; j++) {\n                if (j > 0) cout << \" \";\n                cout << groups[i][j];\n            }\n            cout << endl;\n            \n            // Output the edges\n            for (const auto& edge : group_edges[i]) {\n                cout << edge.u << \" \" << edge.v << endl;\n            }\n        }\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        group_cities();\n        gather_mst_info();\n        construct_final_msts();\n        output_solution();\n    }\n};\n\nint main() {\n    Solution solution;\n    solution.solve();\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <array>\n#include <string>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int MAX_ACTIONS = 2 * N * M;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> blocks;\n    vector<string> actions;\n    int remaining_actions;\n    \n    State(int i, int j, int budget = MAX_ACTIONS) : i(i), j(j), blocks(N, vector<bool>(N, false)), remaining_actions(budget) {}\n    \n    bool is_valid(int ni, int nj) const {\n        return ni >= 0 && ni < N && nj >= 0 && nj < N;\n    }\n    \n    bool can_move(int dir) const {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        return is_valid(ni, nj) && !blocks[ni][nj];\n    }\n    \n    State move(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        new_state.i += di[dir];\n        new_state.j += dj[dir];\n        new_state.actions.push_back(string(1, 'M') + dir_chars[dir]);\n        new_state.remaining_actions--;\n        return new_state;\n    }\n    \n    pair<State, int> slide(int dir) const {\n        if (remaining_actions <= 0) return {*this, 0};\n        State new_state = *this;\n        int ni = i, nj = j;\n        int steps = 0;\n        \n        while (true) {\n            int nni = ni + di[dir];\n            int nnj = nj + dj[dir];\n            \n            if (!is_valid(nni, nnj) || blocks[nni][nnj]) {\n                break;\n            }\n            \n            ni = nni;\n            nj = nnj;\n            steps++;\n        }\n        \n        if (steps > 0) {\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.actions.push_back(string(1, 'S') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return {new_state, steps};\n    }\n    \n    State alter(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (is_valid(ni, nj)) {\n            new_state.blocks[ni][nj] = !blocks[ni][nj];\n            new_state.actions.push_back(string(1, 'A') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return new_state;\n    }\n    \n    int manhattan_distance(int ti, int tj) const {\n        return abs(i - ti) + abs(j - tj);\n    }\n    \n    vector<string> find_path(int target_i, int target_j) const {\n        if (remaining_actions <= 0) return vector<string>();\n        \n        queue<tuple<int, int, vector<string>>> q;\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n        \n        q.push({i, j, vector<string>()});\n        visited[i][j] = true;\n        \n        while (!q.empty()) {\n            auto [ci, cj, path] = q.front();\n            q.pop();\n            \n            if (ci == target_i && cj == target_j) {\n                vector<string> result;\n                while (ci != i || cj != j) {\n                    auto [pi, pj] = parent[ci][cj];\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (pi + di[dir] == ci && pj + dj[dir] == cj) {\n                            result.push_back(string(1, 'M') + dir_chars[dir]);\n                            break;\n                        }\n                    }\n                    ci = pi;\n                    cj = pj;\n                }\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ci + di[dir];\n                int nj = cj + dj[dir];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj] && !blocks[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent[ni][nj] = {ci, cj};\n                    vector<string> new_path = path;\n                    new_path.push_back(string(1, 'M') + dir_chars[dir]);\n                    q.push({ni, nj, new_path});\n                }\n            }\n        }\n        \n        return vector<string>();\n    }\n    \n    bool try_slide_to_target(int target_i, int target_j) {\n        if (remaining_actions < 10) return false; // Not enough actions for sliding\n        \n        int initial_manhattan = manhattan_distance(target_i, target_j);\n        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n        \n        // Try all directions as primary\n        for (int primary_dir = 0; primary_dir < 4; primary_dir++) {\n            State temp_state = *this;\n            \n            // Slide in primary direction\n            auto [slide_state, slide_steps] = temp_state.slide(primary_dir);\n            temp_state = slide_state;\n            \n            if (temp_state.manhattan_distance(target_i, target_j) >= initial_manhattan) {\n                continue; // No improvement\n            }\n            \n            // Try to place a block to stop at target\n            for (int stop_dir = 0; stop_dir < 4; stop_dir++) {\n                if (stop_dir == primary_dir || stop_dir == (primary_dir ^ 1)) {\n                    continue; // Same or opposite direction\n                }\n                \n                State temp_state2 = temp_state;\n                \n                // Calculate where to place the stopping block\n                int stop_i = target_i + di[stop_dir];\n                int stop_j = target_j + dj[stop_dir];\n                \n                if (temp_state2.is_valid(stop_i, stop_j)) {\n                    // Try to place block if not already there\n                    if (!temp_state2.blocks[stop_i][stop_j]) {\n                        temp_state2 = temp_state2.alter(stop_dir);\n                        \n                        // Try sliding to target\n                        auto [slide_result, steps] = temp_state2.slide(stop_dir);\n                        if (slide_result.i == target_i && slide_result.j == target_j) {\n                            *this = slide_result;\n                            return true;\n                        }\n                        \n                        // If slide didn't reach target, try moving from there\n                        auto path = slide_result.find_path(target_i, target_j);\n                        if (!path.empty() && path.size() <= 5) {\n                            for (const auto& action : path) {\n                                for (int dir = 0; dir < 4; dir++) {\n                                    if (action[1] == dir_chars[dir]) {\n                                        slide_result = slide_result.move(dir);\n                                        break;\n                                    }\n                                }\n                            }\n                            \n                            if (slide_result.i == target_i && slide_result.j == target_j) {\n                                *this = slide_result;\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return false;\n    }\n    \n    void remove_unnecessary_blocks(const vector<pair<int, int>>& future_targets) {\n        // Remove blocks that are not needed for future targets\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (blocks[i][j]) {\n                    bool needed = false;\n                    \n                    // Check if block is near any future target\n                    for (const auto& target : future_targets) {\n                        if (abs(i - target.first) <= 2 && abs(j - target.second) <= 2) {\n                            needed = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!needed) {\n                        // Remove the block\n                        for (int dir = 0; dir < 4; dir++) {\n                            if (i - di[dir] == this->i && j - dj[dir] == this->j) {\n                                *this = alter(dir);\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    void optimize_blocks(const vector<pair<int, int>>& targets, int current_target_idx) {\n        // Only optimize if we have enough actions\n        if (remaining_actions < 50) return;\n        \n        vector<pair<int, int>> future_targets(targets.begin() + current_target_idx + 1, \n                                            targets.begin() + min(current_target_idx + 6, (int)targets.size()));\n        \n        // Remove unnecessary blocks first\n        remove_unnecessary_blocks(future_targets);\n        \n        // Place blocks for future targets only if beneficial\n        for (const auto& target : future_targets) {\n            int target_i = target.first;\n            int target_j = target.second;\n            \n            // Only place blocks if we're far from the target\n            if (manhattan_distance(target_i, target_j) > 5) {\n                // Try to place a block that will help slide to this target\n                for (int dir = 0; dir < 4; dir++) {\n                    int block_i = target_i + di[dir];\n                    int block_j = target_j + dj[dir];\n                    \n                    if (is_valid(block_i, block_j) && !blocks[block_i][block_j]) {\n                        // Check if placing this block would create a good sliding opportunity\n                        int path_cost = manhattan_distance(block_i, block_j) + 2; // Move to adjacent + alter\n                        if (path_cost < manhattan_distance(target_i, target_j) * 0.7) {\n                            auto path = find_path(block_i, block_j);\n                            if (!path.empty() && path.size() <= 5) {\n                                for (const auto& action : path) {\n                                    for (int d = 0; d < 4; d++) {\n                                        if (action[1] == dir_chars[d]) {\n                                            *this = move(d);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                *this = alter(dir);\n                                break; // Only place one block per target\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<pair<int, int>> targets(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    State current(targets[0].first, targets[0].second);\n    \n    for (int k = 1; k < m; k++) {\n        int target_i = targets[k].first;\n        int target_j = targets[k].second;\n        \n        // If we're running low on actions, use BFS only\n        if (current.remaining_actions < 100) {\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n            continue;\n        }\n        \n        int manhattan = current.manhattan_distance(target_i, target_j);\n        \n        // Try sliding for medium to long distances\n        if (manhattan > 3 && current.try_slide_to_target(target_i, target_j)) {\n            // Sliding succeeded, continue\n        } else {\n            // Use BFS for short distances or when sliding fails\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Optimize blocks for future targets\n        current.optimize_blocks(targets, k);\n    }\n    \n    for (const auto& action : current.actions) {\n        cout << action[0] << \" \" << action[1] << '\\n';\n    }\n    \n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;  // (a, b) and (c, d) are diagonal vertices\n    \n    Rectangle(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {\n        if (a > c) swap(a, c);\n        if (b > d) swap(b, d);\n    }\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(int x, int y) const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n    \n    int overlap_area(const Rectangle& other) const {\n        int overlap_a = max(a, other.a);\n        int overlap_b = max(b, other.b);\n        int overlap_c = min(c, other.c);\n        int overlap_d = min(d, other.d);\n        \n        if (overlap_a >= overlap_c || overlap_b >= overlap_d) return 0;\n        return (overlap_c - overlap_a) * (overlap_d - overlap_b);\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rectangle rect;\n    \n    double satisfaction() const {\n        int s = rect.area();\n        if (!rect.contains(x, y)) return 0.0;\n        \n        double min_val = min(r, s);\n        double max_val = max(r, s);\n        return 1.0 - pow(1.0 - min_val / max_val, 2);\n    }\n};\n\nvector<Rectangle> solve(int n, const vector<pair<int, int>>& points, const vector<int>& rs) {\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        companies[i].x = points[i].first;\n        companies[i].y = points[i].second;\n        companies[i].r = rs[i];\n    }\n    \n    // Sort companies by desired area (largest first)\n    vector<int> indices(n);\n    for (int i = 0; i < n; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return companies[i].r > companies[j].r;\n    });\n    \n    // Create a space-filling curve based initial placement\n    vector<pair<int, int>> space_order;\n    for (int y = 0; y < 100; ++y) {\n        for (int x = 0; x < 100; ++x) {\n            space_order.emplace_back(x, y);\n        }\n    }\n    \n    // Shuffle the space order for better distribution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(space_order.begin(), space_order.end(), rng);\n    \n    // Initialize rectangles\n    vector<Rectangle> placed_rectangles;\n    for (int i : indices) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Find dimensions that give area close to r\n        int w = min(10000, static_cast<int>(sqrt(r)) + 1);\n        int h = r / w;\n        if (w * h < r) h++;\n        \n        // Try to place the rectangle at different positions\n        Rectangle best_rect;\n        double best_score = -1.0;\n        \n        // Try positions based on the space order\n        for (const auto& pos : space_order) {\n            int base_x = pos.first * 100;\n            int base_y = pos.second * 100;\n            \n            // Try to place the rectangle with the desired point inside\n            int a = max(0, min(base_x, x - w/2));\n            int c = min(10000, a + w);\n            if (c - a < w) a = c - w;\n            \n            int b = max(0, min(base_y, y - h/2));\n            int d = min(10000, b + h);\n            if (d - b < h) b = d - h;\n            \n            Rectangle rect(a, b, c, d);\n            \n            // Check if the rectangle contains the desired point\n            if (!rect.contains(x, y)) continue;\n            \n            // Check for overlaps with already placed rectangles\n            bool has_overlap = false;\n            for (const auto& placed : placed_rectangles) {\n                if (rect.overlaps(placed)) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            \n            if (!has_overlap) {\n                // Calculate a score based on how close the area is to the desired area\n                int area = rect.area();\n                double score = 1.0 - abs(area - r) / max(area, r);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect;\n                }\n            }\n        }\n        \n        // If we couldn't find a non-overlapping position, use a minimal rectangle\n        if (best_score < 0) {\n            best_rect = Rectangle(x, y, x + 1, y + 1);\n        }\n        \n        companies[i].rect = best_rect;\n        placed_rectangles.push_back(best_rect);\n    }\n    \n    // Resolve overlaps iteratively\n    const int MAX_ITERATIONS = 100;\n    for (int iter = 0; iter < MAX_ITERATIONS; ++iter) {\n        bool has_overlap = false;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = i + 1; j < n; ++j) {\n                if (companies[i].rect.overlaps(companies[j].rect)) {\n                    has_overlap = true;\n                    \n                    // Calculate overlap area\n                    int overlap_area = companies[i].rect.overlap_area(companies[j].rect);\n                    \n                    // Resolve overlap by shrinking the rectangle with smaller desired area\n                    if (companies[i].r < companies[j].r) {\n                        // Shrink company i's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_i.a < rect_j.a) {\n                                rect_i.c = min(rect_i.c, rect_j.a);\n                            } else {\n                                rect_i.a = max(rect_i.a, rect_j.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_i.b < rect_j.b) {\n                                rect_i.d = min(rect_i.d, rect_j.b);\n                            } else {\n                                rect_i.b = max(rect_i.b, rect_j.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                            // Try a different approach\n                            rect_i = companies[i].rect;\n                            if (rect_j.a < rect_i.a) {\n                                rect_i.a = rect_j.c;\n                            } else {\n                                rect_i.c = rect_j.a;\n                            }\n                            \n                            if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_i = Rectangle(companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1);\n                            }\n                        }\n                    } else {\n                        // Shrink company j's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_j.a < rect_i.a) {\n                                rect_j.c = min(rect_j.c, rect_i.a);\n                            } else {\n                                rect_j.a = max(rect_j.a, rect_i.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_j.b < rect_i.b) {\n                                rect_j.d = min(rect_j.d, rect_i.b);\n                            } else {\n                                rect_j.b = max(rect_j.b, rect_i.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                            // Try a different approach\n                            rect_j = companies[j].rect;\n                            if (rect_i.a < rect_j.a) {\n                                rect_j.a = rect_i.c;\n                            } else {\n                                rect_j.c = rect_i.a;\n                            }\n                            \n                            if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_j = Rectangle(companies[j].x, companies[j].y, companies[j].x + 1, companies[j].y + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!has_overlap) break;\n    }\n    \n    // Final optimization using simulated annealing\n    rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n    double temperature = 100.0;\n    const double COOLING_RATE = 0.95;\n    const int SA_ITERATIONS = 1000;\n    \n    double current_score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        current_score += companies[i].satisfaction();\n    }\n    \n    for (int iter = 0; iter < SA_ITERATIONS; ++iter) {\n        temperature *= COOLING_RATE;\n        \n        // Choose a random company to modify\n        int i = rng() % n;\n        Rectangle old_rect = companies[i].rect;\n        double old_satisfaction = companies[i].satisfaction();\n        \n        // Choose a random modification\n        int mod_type = rng() % 8;\n        \n        switch (mod_type) {\n            case 0: {  // Move left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                companies[i].rect.c -= delta;\n                break;\n            }\n            case 1: {  // Move right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.a += delta;\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 2: {  // Move up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                companies[i].rect.d -= delta;\n                break;\n            }\n            case 3: {  // Move down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.b += delta;\n                companies[i].rect.d += delta;\n                break;\n            }\n            case 4: {  // Expand left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                break;\n            }\n            case 5: {  // Expand right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 6: {  // Expand up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                break;\n            }\n            case 7: {  // Expand down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.d += delta;\n                break;\n            }\n        }\n        \n        // Check constraints\n        bool valid = true;\n        \n        // Check if the rectangle still contains the desired point\n        if (!companies[i].rect.contains(companies[i].x, companies[i].y)) {\n            valid = false;\n        }\n        \n        // Check for overlaps\n        if (valid) {\n            for (int j = 0; j < n; ++j) {\n                if (i != j && companies[i].rect.overlaps(companies[j].rect)) {\n                    valid = false;\n                    break;\n                }\n            }\n        }\n        \n        if (valid) {\n            double new_satisfaction = companies[i].satisfaction();\n            double delta_score = new_satisfaction - old_satisfaction;\n            \n            // Accept or reject the move based on simulated annealing\n            if (delta_score > 0 || exp(delta_score / temperature) > (rng() % 1000) / 1000.0) {\n                current_score += delta_score;\n            } else {\n                companies[i].rect = old_rect;\n            }\n        } else {\n            companies[i].rect = old_rect;\n        }\n    }\n    \n    // Extract the final rectangles\n    vector<Rectangle> result;\n    for (int i = 0; i < n; ++i) {\n        result.push_back(companies[i].rect);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<pair<int, int>> points(n);\n    vector<int> rs(n);\n    \n    for (int i = 0; i < n; ++i) {\n        cin >> points[i].first >> points[i].second >> rs[i];\n    }\n    \n    vector<Rectangle> solution = solve(n, points, rs);\n    \n    for (const auto& rect : solution) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Tile {\n    int id;\n    vector<pair<int, int>> squares;\n    int total_value;\n    set<int> adjacent_tiles;\n    bool is_1x1;\n    pair<int, int> other_square;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tiles(50, vector<int>(50));\n    vector<vector<int>> points(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tiles[i][j];\n        }\n    }\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> points[i][j];\n        }\n    }\n    \n    // Build tile information\n    map<int, Tile> tile_map;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int tile_id = tiles[i][j];\n            if (tile_map.find(tile_id) == tile_map.end()) {\n                tile_map[tile_id] = {tile_id, {}, 0, {}, true, {-1, -1}};\n            }\n            tile_map[tile_id].squares.emplace_back(i, j);\n            tile_map[tile_id].total_value += points[i][j];\n        }\n    }\n    \n    // Determine tile types and other square\n    for (auto& [id, tile] : tile_map) {\n        if (tile.squares.size() == 2) {\n            tile.is_1x1 = false;\n            if (tile.squares[0].first == tile.squares[1].first) {\n                // 1x2 tile\n                if (tile.squares[0].second < tile.squares[1].second) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            } else {\n                // 2x1 tile\n                if (tile.squares[0].first < tile.squares[1].first) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            }\n        }\n    }\n    \n    // Build adjacency information\n    for (auto& [id, tile] : tile_map) {\n        for (auto& [i, j] : tile.squares) {\n            vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n            for (auto& [di, dj] : directions) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int neighbor_tile_id = tiles[ni][nj];\n                    if (neighbor_tile_id != id) {\n                        tile.adjacent_tiles.insert(neighbor_tile_id);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Start tile\n    int start_tile_id = tiles[si][sj];\n    set<int> visited_tiles;\n    visited_tiles.insert(start_tile_id);\n    int current_i = si, current_j = sj;\n    string path;\n    \n    // If starting tile is 1x2 or 2x1, move to the other square\n    if (!tile_map[start_tile_id].is_1x1) {\n        auto [oi, oj] = tile_map[start_tile_id].other_square;\n        if (oi < current_i) {\n            path += 'U';\n            current_i = oi;\n        } else if (oi > current_i) {\n            path += 'D';\n            current_i = oi;\n        } else if (oj < current_j) {\n            path += 'L';\n            current_j = oj;\n        } else if (oj > current_j) {\n            path += 'R';\n            current_j = oj;\n        }\n    }\n    \n    // Greedy walk with probabilistic selection\n    random_device rd;\n    mt19937 gen(rd());\n    \n    while (true) {\n        vector<pair<int, pair<char, pair<int, int>>>> candidates;\n        \n        vector<pair<char, pair<int, int>>> directions = {\n            {'U', {-1, 0}}, {'D', {1, 0}}, {'L', {0, -1}}, {'R', {0, 1}}\n        };\n        \n        for (auto& [dir, delta] : directions) {\n            int ni = current_i + delta.first;\n            int nj = current_j + delta.second;\n            \n            if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                int next_tile_id = tiles[ni][nj];\n                \n                if (visited_tiles.find(next_tile_id) == visited_tiles.end()) {\n                    int score = tile_map[next_tile_id].total_value;\n                    \n                    // Consider connectivity\n                    int adjacent_unvisited = 0;\n                    for (int adj_id : tile_map[next_tile_id].adjacent_tiles) {\n                        if (visited_tiles.find(adj_id) == visited_tiles.end()) {\n                            adjacent_unvisited++;\n                        }\n                    }\n                    \n                    score += adjacent_unvisited * 10;  // Weight for connectivity\n                    candidates.emplace_back(score, make_pair(dir, make_pair(ni, nj)));\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Probabilistic selection\n        vector<double> probabilities;\n        for (int i = 0; i < candidates.size(); ++i) {\n            probabilities.push_back(pow(0.8, i));\n        }\n        \n        double sum_probs = accumulate(probabilities.begin(), probabilities.end(), 0.0);\n        for (double& prob : probabilities) {\n            prob /= sum_probs;\n        }\n        \n        uniform_real_distribution<> dis(0.0, 1.0);\n        double r = dis(gen);\n        double cumulative = 0.0;\n        int selected_idx = 0;\n        \n        for (int i = 0; i < probabilities.size(); ++i) {\n            cumulative += probabilities[i];\n            if (r <= cumulative) {\n                selected_idx = i;\n                break;\n            }\n        }\n        \n        auto& [score, move_info] = candidates[selected_idx];\n        auto& [dir, next_pos] = move_info;\n        auto& [ni, nj] = next_pos;\n        \n        int next_tile_id = tiles[ni][nj];\n        \n        path += dir;\n        visited_tiles.insert(next_tile_id);\n        current_i = ni;\n        current_j = nj;\n        \n        // If tile is 1x2 or 2x1, move to the other square\n        if (!tile_map[next_tile_id].is_1x1) {\n            auto [oi, oj] = tile_map[next_tile_id].other_square;\n            if (oi != ni || oj != nj) {\n                if (oi < ni) {\n                    path += 'U';\n                    current_i = oi;\n                } else if (oi > ni) {\n                    path += 'D';\n                    current_i = oi;\n                } else if (oj < nj) {\n                    path += 'L';\n                    current_j = oj;\n                } else if (oj > nj) {\n                    path += 'R';\n                    current_j = oj;\n                }\n            }\n        }\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <functional>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\nint main() {\n    vector<vector<double>> hor_est(N, vector<double>(N-1, 5000.0));\n    vector<vector<double>> ver_est(N-1, vector<double>(N, 5000.0));\n\n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        vector<vector<double>> dist(N, vector<double>(N, 1e18));\n        vector<vector<tuple<int, int, char>>> parent(N, vector<tuple<int, int, char>>(N, make_tuple(-1, -1, ' ')));\n        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (i == ti && j == tj) {\n                break;\n            }\n            if (d > dist[i][j]) {\n                continue;\n            }\n\n            if (i > 0) {\n                double w = ver_est[i-1][j];\n                if (d + w < dist[i-1][j]) {\n                    dist[i-1][j] = d + w;\n                    parent[i-1][j] = make_tuple(i, j, 'U');\n                    pq.push({dist[i-1][j], i-1, j});\n                }\n            }\n            if (i < N-1) {\n                double w = ver_est[i][j];\n                if (d + w < dist[i+1][j]) {\n                    dist[i+1][j] = d + w;\n                    parent[i+1][j] = make_tuple(i, j, 'D');\n                    pq.push({dist[i+1][j], i+1, j});\n                }\n            }\n            if (j > 0) {\n                double w = hor_est[i][j-1];\n                if (d + w < dist[i][j-1]) {\n                    dist[i][j-1] = d + w;\n                    parent[i][j-1] = make_tuple(i, j, 'L');\n                    pq.push({dist[i][j-1], i, j-1});\n                }\n            }\n            if (j < N-1) {\n                double w = hor_est[i][j];\n                if (d + w < dist[i][j+1]) {\n                    dist[i][j+1] = d + w;\n                    parent[i][j+1] = make_tuple(i, j, 'R');\n                    pq.push({dist[i][j+1], i, j+1});\n                }\n            }\n        }\n\n        string path_str = \"\";\n        int i = ti, j = tj;\n        while (i != si || j != sj) {\n            auto [pi, pj, dir] = parent[i][j];\n            path_str += dir;\n            i = pi;\n            j = pj;\n        }\n        reverse(path_str.begin(), path_str.end());\n\n        cout << path_str << endl;\n        cout.flush();\n\n        int y;\n        cin >> y;\n\n        double L_est = 0.0;\n        vector<double*> edges_in_path;\n        i = si; j = sj;\n        for (char c : path_str) {\n            if (c == 'U') {\n                L_est += ver_est[i-1][j];\n                edges_in_path.push_back(&ver_est[i-1][j]);\n                i--;\n            } else if (c == 'D') {\n                L_est += ver_est[i][j];\n                edges_in_path.push_back(&ver_est[i][j]);\n                i++;\n            } else if (c == 'L') {\n                L_est += hor_est[i][j-1];\n                edges_in_path.push_back(&hor_est[i][j-1]);\n                j--;\n            } else if (c == 'R') {\n                L_est += hor_est[i][j];\n                edges_in_path.push_back(&hor_est[i][j]);\n                j++;\n            }\n        }\n\n        int m = edges_in_path.size();\n        double error = y - L_est;\n        for (double* ptr : edges_in_path) {\n            *ptr += 0.1 * error / m;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <array>\n\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int N = 20;\nconstexpr char EMPTY = '.';\nconstexpr array<char, 8> CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Problem {\n    int M;\n    vector<string> strings;\n    vector<array<array<int, 8>, N>> char_freq;\n    vector<int> string_importance;\n    \n    Problem(int M, const vector<string>& strings) : M(M), strings(strings) {\n        char_freq.resize(N);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                char_freq[i][j].fill(0);\n            }\n        }\n        \n        string_importance.resize(M);\n        for (int i = 0; i < M; i++) {\n            string_importance[i] = strings[i].size();\n        }\n        \n        for (int idx = 0; idx < M; idx++) {\n            const auto& s = strings[idx];\n            int k = s.size();\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int p = 0; p < min(k, N); p++) {\n                        int c = s[p] - 'A';\n                        char_freq[i][(j + p) % N][c] += string_importance[idx];\n                        char_freq[(i + p) % N][j][c] += string_importance[idx];\n                    }\n                }\n            }\n        }\n    }\n};\n\nstruct Solution {\n    vector<string> matrix;\n    vector<bool> satisfied;\n    int score;\n    int satisfied_count;\n    int empty_count;\n    \n    Solution() : matrix(N, string(N, EMPTY)), score(0), satisfied_count(0), empty_count(N*N) {}\n    \n    void fill_based_on_freq(const Problem& problem) {\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (matrix[i][j] == EMPTY) {\n                    int max_freq = -1;\n                    char best_char = EMPTY;\n                    for (int c = 0; c < 8; c++) {\n                        if (problem.char_freq[i][j][c] > max_freq) {\n                            max_freq = problem.char_freq[i][j][c];\n                            best_char = 'A' + c;\n                        }\n                    }\n                    if (best_char != EMPTY) {\n                        matrix[i][j] = best_char;\n                    }\n                }\n            }\n        }\n        empty_count = 0;\n    }\n    \n    void random_partial_fill(double fill_ratio) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        int fill_count = static_cast<int>(N * N * fill_ratio);\n        vector<pair<int, int>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                positions.emplace_back(i, j);\n            }\n        }\n        shuffle(positions.begin(), positions.end(), rng);\n        for (int k = 0; k < fill_count; k++) {\n            auto [i, j] = positions[k];\n            matrix[i][j] = CHARS[char_dist(rng)];\n        }\n        empty_count = N * N - fill_count;\n    }\n    \n    bool is_subsequence(const string& s) const {\n        int k = s.size();\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                bool match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[i][(j + p) % N] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n                \n                match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[(i + p) % N][j] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    int calculate_score(const Problem& problem) {\n        satisfied.resize(problem.M);\n        satisfied_count = 0;\n        for (int i = 0; i < problem.M; i++) {\n            satisfied[i] = is_subsequence(problem.strings[i]);\n            if (satisfied[i]) {\n                satisfied_count++;\n            }\n        }\n        \n        if (satisfied_count < problem.M) {\n            score = static_cast<int>(round(1e8 * static_cast<double>(satisfied_count) / problem.M));\n        } else {\n            score = static_cast<int>(round(1e8 * (2.0 * N * N) / (2.0 * N * N - empty_count)));\n        }\n        \n        return score;\n    }\n    \n    void mutate(const Problem& problem) {\n        uniform_int_distribution<int> pos_dist(0, N-1);\n        uniform_int_distribution<int> char_dist(0, 7);\n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        double r = real_dist(rng);\n        \n        if (r < 0.6) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            if (matrix[i][j] != EMPTY) {\n                matrix[i][j] = CHARS[char_dist(rng)];\n            }\n        } else if (r < 0.8) {\n            int i1 = pos_dist(rng);\n            int j1 = pos_dist(rng);\n            int i2 = pos_dist(rng);\n            int j2 = pos_dist(rng);\n            swap(matrix[i1][j1], matrix[i2][j2]);\n        } else if (r < 0.9) {\n            if (real_dist(rng) < 0.5) {\n                int i = pos_dist(rng);\n                int shift = pos_dist(rng);\n                rotate(matrix[i].begin(), matrix[i].begin() + shift, matrix[i].end());\n            } else {\n                int j = pos_dist(rng);\n                int shift = pos_dist(rng);\n                vector<char> column(N);\n                for (int i = 0; i < N; i++) {\n                    column[i] = matrix[i][j];\n                }\n                rotate(column.begin(), column.begin() + shift, column.end());\n                for (int i = 0; i < N; i++) {\n                    matrix[i][j] = column[i];\n                }\n            }\n        } else {\n            vector<int> unsatisfied;\n            for (int i = 0; i < problem.M; i++) {\n                if (!satisfied[i]) {\n                    unsatisfied.push_back(i);\n                }\n            }\n            \n            if (!unsatisfied.empty()) {\n                uniform_int_distribution<int> unsat_dist(0, unsatisfied.size()-1);\n                int idx = unsatisfied[unsat_dist(rng)];\n                const string& s = problem.strings[idx];\n                int k = s.size();\n                \n                int i = pos_dist(rng);\n                int j = pos_dist(rng);\n                if (real_dist(rng) < 0.5) {\n                    for (int p = 0; p < k; p++) {\n                        matrix[i][(j + p) % N] = s[p];\n                    }\n                } else {\n                    for (int p = 0; p < k; p++) {\n                        matrix[(i + p) % N][j] = s[p];\n                    }\n                }\n            }\n        }\n    }\n    \n    void print() const {\n        for (const auto& row : matrix) {\n            cout << row << endl;\n        }\n    }\n};\n\nSolution solve(const Problem& problem) {\n    Solution best_solution;\n    int best_score = 0;\n    \n    vector<int> sorted_indices(problem.M);\n    for (int i = 0; i < problem.M; i++) {\n        sorted_indices[i] = i;\n    }\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return problem.string_importance[a] > problem.string_importance[b];\n    });\n    \n    for (int trial = 0; trial < 5; trial++) {\n        Solution solution;\n        \n        double fill_ratio = 0.3 + 0.1 * trial;\n        solution.random_partial_fill(fill_ratio);\n        solution.fill_based_on_freq(problem);\n        \n        for (int i = 0; i < min(30, problem.M); i++) {\n            int idx = sorted_indices[i];\n            const string& s = problem.strings[idx];\n            int k = s.size();\n            \n            uniform_int_distribution<int> pos_dist(0, N-1);\n            uniform_real_distribution<double> real_dist(0.0, 1.0);\n            int row = pos_dist(rng);\n            int col = pos_dist(rng);\n            \n            if (real_dist(rng) < 0.5) {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[row][(col + p) % N] = s[p];\n                }\n            } else {\n                for (int p = 0; p < k; p++) {\n                    solution.matrix[(row + p) % N][col] = s[p];\n                }\n            }\n        }\n        \n        solution.empty_count = 0;\n        int current_score = solution.calculate_score(problem);\n        \n        double temperature = 100.0;\n        double cooling_rate = 0.995;\n        int iterations = 15000;\n        \n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            Solution new_solution = solution;\n            new_solution.mutate(problem);\n            int new_score = new_solution.calculate_score(problem);\n            \n            if (new_score > current_score || real_dist(rng) < exp((new_score - current_score) / temperature)) {\n                solution = new_solution;\n                current_score = new_score;\n                \n                if (current_score > best_score) {\n                    best_solution = solution;\n                    best_score = current_score;\n                }\n            }\n            \n            temperature *= cooling_rate;\n            \n            if (iter % 1000 == 0) {\n                temperature = max(temperature, 1.0);\n            }\n        }\n    }\n    \n    if (best_solution.satisfied_count < problem.M) {\n        uniform_int_distribution<int> char_dist(0, 7);\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (best_solution.matrix[i][j] == EMPTY) {\n                    best_solution.matrix[i][j] = CHARS[char_dist(rng)];\n                }\n            }\n        }\n        best_solution.empty_count = 0;\n        best_solution.calculate_score(problem);\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    cin >> M;\n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Problem problem(M, strings);\n    Solution solution = solve(problem);\n    solution.print();\n    \n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <list>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <unordered_map>\n#include <unordered_set>\n#include <string>\n#include <utility>\n#include <array>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    Point(int i_=0, int j_=0) : i(i_), j(j_) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n};\n\nstruct Segment {\n    bool is_horizontal;\n    int fixed_index;\n    int start, end;\n    Segment(bool h, int idx, int s, int e) : is_horizontal(h), fixed_index(idx), start(s), end(e) {}\n    bool operator==(const Segment& other) const {\n        return is_horizontal == other.is_horizontal && fixed_index == other.fixed_index && start == other.start && end == other.end;\n    }\n    bool operator<(const Segment& other) const {\n        if (is_horizontal != other.is_horizontal) return is_horizontal < other.is_horizontal;\n        if (fixed_index != other.fixed_index) return fixed_index < other.fixed_index;\n        if (start != other.start) return start < other.start;\n        return end < other.end;\n    }\n};\n\nvector<Point> dial_shortest_path(const vector<vector<int>>& grid_cost, int N, Point start, Point end) {\n    int max_cost = 9 * N * N;\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n    vector<list<Point>> buckets(max_cost + 1);\n\n    dist[start.i][start.j] = 0;\n    buckets[0].push_back(start);\n\n    for (int idx = 0; idx <= max_cost; idx++) {\n        while (!buckets[idx].empty()) {\n            Point p = buckets[idx].front();\n            buckets[idx].pop_front();\n            if (dist[p.i][p.j] < idx) continue;\n            if (p == end) break;\n            for (auto [di, dj] : {array<int,2>{-1,0}, {1,0}, {0,-1}, {0,1}}) {\n                int ni = p.i + di;\n                int nj = p.j + dj;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid_cost[ni][nj] == -1) continue;\n                int new_cost = dist[p.i][p.j] + grid_cost[ni][nj];\n                if (new_cost < dist[ni][nj]) {\n                    dist[ni][nj] = new_cost;\n                    parent[ni][nj] = p;\n                    if (new_cost <= max_cost) {\n                        buckets[new_cost].push_front(Point(ni, nj));\n                    }\n                }\n            }\n        }\n    }\n\n    vector<Point> path;\n    if (dist[end.i][end.j] == INF) {\n        return path;\n    }\n    Point cur = end;\n    while (cur != start) {\n        path.push_back(cur);\n        cur = parent[cur.i][cur.j];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<int> bipartite_matching(const vector<vector<int>>& graph, int nH, int nV) {\n    vector<int> matchH(nH, -1);\n    vector<int> matchV(nV, -1);\n    vector<bool> visited;\n\n    function<bool(int)> dfs = [&](int u) {\n        visited[u] = true;\n        for (int v : graph[u]) {\n            if (matchV[v] == -1 || (!visited[matchV[v]] && dfs(matchV[v]))) {\n                matchH[u] = v;\n                matchV[v] = u;\n                return true;\n            }\n        }\n        return false;\n    };\n\n    for (int u = 0; u < nH; u++) {\n        visited.assign(nH, false);\n        dfs(u);\n    }\n\n    vector<int> matching(nH, -1);\n    for (int u = 0; u < nH; u++) {\n        if (matchH[u] != -1) {\n            matching[u] = matchH[u];\n        }\n    }\n    return matching;\n}\n\nvector<Segment> konig_vertex_cover(const vector<vector<int>>& graph, const vector<int>& matching, int nH, int nV) {\n    vector<vector<int>> residual_graph(nH + nV);\n    for (int u = 0; u < nH; u++) {\n        for (int v : graph[u]) {\n            if (matching[u] == v) {\n                residual_graph[nH + v].push_back(u);\n            } else {\n                residual_graph[u].push_back(nH + v);\n            }\n        }\n    }\n\n    vector<bool> marked(nH + nV, false);\n    queue<int> q;\n    for (int u = 0; u < nH; u++) {\n        if (matching[u] == -1) {\n            marked[u] = true;\n            q.push(u);\n        }\n    }\n\n    while (!q.empty()) {\n        int node = q.front();\n        q.pop();\n        for (int neighbor : residual_graph[node]) {\n            if (!marked[neighbor]) {\n                marked[neighbor] = true;\n                q.push(neighbor);\n            }\n        }\n    }\n\n    vector<Segment> vertex_cover;\n    for (int u = 0; u < nH; u++) {\n        if (!marked[u]) {\n            vertex_cover.push_back(Segment(true, u, 0, 0));\n        }\n    }\n    for (int v = 0; v < nV; v++) {\n        if (marked[nH + v]) {\n            vertex_cover.push_back(Segment(false, v, 0, 0));\n        }\n    }\n    return vertex_cover;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid_str[i];\n    }\n\n    vector<vector<int>> grid_cost(N, vector<int>(N, -1));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                grid_cost[i][j] = grid_str[i][j] - '0';\n            }\n        }\n    }\n\n    vector<Segment> h_segments, v_segments;\n    vector<vector<Segment*>> h_segment_ptr(N, vector<Segment*>(N, nullptr));\n    vector<vector<Segment*>> v_segment_ptr(N, vector<Segment*>(N, nullptr));\n\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid_str[i][j] == '#') {\n                j++;\n                continue;\n            }\n            int start = j;\n            while (j < N && grid_str[i][j] != '#') {\n                j++;\n            }\n            int end = j - 1;\n            h_segments.emplace_back(true, i, start, end);\n            Segment* seg = &h_segments.back();\n            for (int k = start; k <= end; k++) {\n                h_segment_ptr[i][k] = seg;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid_str[i][j] == '#') {\n                i++;\n                continue;\n            }\n            int start = i;\n            while (i < N && grid_str[i][j] != '#') {\n                i++;\n            }\n            int end = i - 1;\n            v_segments.emplace_back(false, j, start, end);\n            Segment* seg = &v_segments.back();\n            for (int k = start; k <= end; k++) {\n                v_segment_ptr[k][j] = seg;\n            }\n        }\n    }\n\n    unordered_map<Segment*, int> h_segment_to_id;\n    unordered_map<Segment*, int> v_segment_to_id;\n    for (int i = 0; i < h_segments.size(); i++) {\n        h_segment_to_id[&h_segments[i]] = i;\n    }\n    for (int i = 0; i < v_segments.size(); i++) {\n        v_segment_to_id[&v_segments[i]] = i;\n    }\n\n    vector<vector<int>> bipartite_graph(h_segments.size());\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                Segment* h_seg = h_segment_ptr[i][j];\n                Segment* v_seg = v_segment_ptr[i][j];\n                int h_id = h_segment_to_id[h_seg];\n                int v_id = v_segment_to_id[v_seg];\n                bipartite_graph[h_id].push_back(v_id);\n            }\n        }\n    }\n\n    vector<int> matching = bipartite_matching(bipartite_graph, h_segments.size(), v_segments.size());\n    vector<Segment> vertex_cover_segments = konig_vertex_cover(bipartite_graph, matching, h_segments.size(), v_segments.size());\n\n    Segment* h_start_seg = h_segment_ptr[si][sj];\n    Segment* v_start_seg = v_segment_ptr[si][sj];\n    vector<Segment> segments_to_cover;\n    for (const Segment& seg : vertex_cover_segments) {\n        if (seg.is_horizontal) {\n            if (&h_segments[seg.fixed_index] != h_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        } else {\n            if (&v_segments[seg.fixed_index] != v_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        }\n    }\n\n    vector<Point> candidate_points;\n    for (const Segment& seg : segments_to_cover) {\n        if (seg.is_horizontal) {\n            candidate_points.emplace_back(seg.fixed_index, seg.start);\n        } else {\n            candidate_points.emplace_back(seg.start, seg.fixed_index);\n        }\n    }\n\n    vector<Point> P;\n    P.emplace_back(si, sj);\n    P.insert(P.end(), candidate_points.begin(), candidate_points.end());\n    int total_points = P.size();\n\n    vector<vector<int>> dist_matrix(total_points, vector<int>(total_points, INF));\n    vector<vector<vector<Point>>> paths(total_points, vector<vector<Point>>(total_points));\n\n    for (int i = 0; i < total_points; i++) {\n        vector<Point> path_to_end = dial_shortest_path(grid_cost, N, P[i], P[i]);\n        for (int j = 0; j < total_points; j++) {\n            if (i == j) {\n                dist_matrix[i][j] = 0;\n                paths[i][j] = {P[i]};\n                continue;\n            }\n            vector<Point> path_ij = dial_shortest_path(grid_cost, N, P[i], P[j]);\n            if (path_ij.empty()) {\n                dist_matrix[i][j] = INF;\n                paths[i][j] = {};\n            } else {\n                int total_cost = 0;\n                Point cur = P[i];\n                for (const Point& p : path_ij) {\n                    total_cost += grid_cost[p.i][p.j];\n                }\n                dist_matrix[i][j] = total_cost;\n                paths[i][j] = path_ij;\n            }\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited(total_points, false);\n    visited[0] = true;\n    tour.push_back(0);\n    int current = 0;\n    for (int step = 1; step < total_points; step++) {\n        int best_next = -1;\n        int best_dist = INF;\n        for (int j = 0; j < total_points; j++) {\n            if (!visited[j] && dist_matrix[current][j] < best_dist) {\n                best_dist = dist_matrix[current][j];\n                best_next = j;\n            }\n        }\n        if (best_next == -1) break;\n        visited[best_next] = true;\n        tour.push_back(best_next);\n        current = best_next;\n    }\n    tour.push_back(0);\n\n    vector<Point> full_route;\n    full_route.push_back(P[0]);\n    for (int idx = 0; idx < tour.size() - 1; idx++) {\n        int i = tour[idx];\n        int j = tour[idx+1];\n        if (i == j) continue;\n        vector<Point>& path_segment = paths[i][j];\n        full_route.insert(full_route.end(), path_segment.begin(), path_segment.end());\n    }\n\n    string moves;\n    for (int i = 0; i < full_route.size() - 1; i++) {\n        Point a = full_route[i];\n        Point b = full_route[i+1];\n        if (b.i < a.i) moves += 'U';\n        else if (b.i > a.i) moves += 'D';\n        else if (b.j < a.j) moves += 'L';\n        else if (b.j > a.j) moves += 'R';\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n#include <cstring>\n#include <sys/select.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(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    vector<vector<int>> prerequisites(N);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        prerequisites[v].push_back(u);\n    }\n\n    vector<int> task_status(N, -1);\n    vector<int> member_status(M, -1);\n    vector<int> start_day(N, 0);\n\n    vector<vector<int>> S(M, vector<int>(K, 0));\n\n    int current_day = 1;\n\n    while (true) {\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        vector<int> tokens;\n        char* cstr = new char[line.length() + 1];\n        strcpy(cstr, line.c_str());\n        char* p = strtok(cstr, \" \");\n        while (p != nullptr) {\n            tokens.push_back(atoi(p));\n            p = strtok(nullptr, \" \");\n        }\n        delete[] cstr;\n\n        int n = tokens[0];\n        vector<int> completed_members;\n        for (int i = 1; i <= n; ++i) {\n            completed_members.push_back(tokens[i]);\n        }\n\n        for (int idx = 0; idx < n; ++idx) {\n            int j0 = completed_members[idx];\n            int j = j0 - 1;\n            if (member_status[j] == -1) {\n                continue;\n            }\n            int task_i = member_status[j];\n            task_status[task_i] = 1;\n            member_status[j] = -1;\n\n            int t_taken = current_day - start_day[task_i];\n\n            if (t_taken == 1) {\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        S[j][k] = d[task_i][k];\n                    }\n                }\n            } else {\n                int current_w = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        current_w += d[task_i][k] - S[j][k];\n                    }\n                }\n\n                if (current_w > t_taken + 3) {\n                    int reduction_needed = current_w - (t_taken + 3);\n                    vector<pair<int, int>> deficits;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task_i][k] > S[j][k]) {\n                            int deficit_k = d[task_i][k] - S[j][k];\n                            deficits.emplace_back(deficit_k, k);\n                        }\n                    }\n                    sort(deficits.begin(), deficits.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                        return a.first > b.first;\n                    });\n                    for (auto& def : deficits) {\n                        if (reduction_needed <= 0) break;\n                        int deficit_k = def.first;\n                        int k = def.second;\n                        int increase = min(deficit_k, reduction_needed);\n                        S[j][k] += increase;\n                        reduction_needed -= increase;\n                    }\n                }\n            }\n        }\n\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] != -1) continue;\n            bool available = true;\n            for (int pre : prerequisites[i]) {\n                if (task_status[pre] != 1) {\n                    available = false;\n                    break;\n                }\n            }\n            if (available) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> free_team_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_status[j] == -1) {\n                free_team_members.push_back(j);\n            }\n        }\n\n        vector<pair<int, int>> assignments;\n        if (!available_tasks.empty() && !free_team_members.empty()) {\n            vector<pair<int, int>> task_list;\n            for (int i : available_tasks) {\n                int min_exp = -1;\n                for (int j : free_team_members) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (min_exp == -1 || exp_time < min_exp) {\n                        min_exp = exp_time;\n                    }\n                }\n                task_list.emplace_back(min_exp, i);\n            }\n\n            sort(task_list.begin(), task_list.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                return a.first > b.first;\n            });\n\n            set<int> free_set(free_team_members.begin(), free_team_members.end());\n            for (auto& p : task_list) {\n                if (free_set.empty()) break;\n                int i = p.second;\n                int best_j = -1;\n                int best_exp = -1;\n                for (int j : free_set) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (best_j == -1 || exp_time < best_exp) {\n                        best_j = j;\n                        best_exp = exp_time;\n                    }\n                }\n                assignments.emplace_back(best_j, i);\n                free_set.erase(best_j);\n            }\n        }\n\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        for (auto& p : assignments) {\n            int j = p.first;\n            int i = p.second;\n            task_status[i] = 0;\n            member_status[j] = i;\n            start_day[i] = current_day;\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <set>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Order {\n    int id;\n    int a, b;  // restaurant\n    int c, d;  // destination\n};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    \n    int manhattan_distance(const Point& other) const {\n        return abs(x - other.x) + abs(y - other.y);\n    }\n};\n\nvector<Order> orders;\nvector<int> selected_orders;\nvector<Point> route;\n\nmt19937 rng;\n\nint calculate_total_distance(const vector<Point>& route) {\n    int total = 0;\n    for (size_t i = 0; i < route.size() - 1; i++) {\n        total += route[i].manhattan_distance(route[i + 1]);\n    }\n    return total;\n}\n\nbool is_valid_route(const vector<int>& selected, const vector<Point>& route) {\n    vector<pair<int, int>> positions(1001, {-1, -1});\n    \n    for (size_t i = 0; i < route.size(); i++) {\n        for (int order_id : selected) {\n            const auto& order = orders[order_id];\n            if (route[i].x == order.a && route[i].y == order.b) {\n                if (positions[order_id].first == -1) {\n                    positions[order_id].first = i;\n                }\n            } else if (route[i].x == order.c && route[i].y == order.d) {\n                if (positions[order_id].second == -1) {\n                    positions[order_id].second = i;\n                }\n            }\n        }\n    }\n    \n    for (int order_id : selected) {\n        if (positions[order_id].first == -1 || positions[order_id].second == -1) {\n            return false;\n        }\n        if (positions[order_id].first >= positions[order_id].second) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nvector<Point> construct_greedy_route(const vector<int>& selected) {\n    vector<Point> route = {Point(400, 400)};\n    set<int> remaining_orders(selected.begin(), selected.end());\n    \n    while (!remaining_orders.empty()) {\n        int best_order = -1;\n        int best_pos = -1;\n        int best_increase = 1e9;\n        \n        for (int order_id : remaining_orders) {\n            const auto& order = orders[order_id];\n            \n            // Try inserting restaurant and destination in all possible positions\n            for (size_t i = 0; i <= route.size(); i++) {\n                for (size_t j = i + 1; j <= route.size(); j++) {\n                    vector<Point> temp_route = route;\n                    temp_route.insert(temp_route.begin() + i, Point(order.a, order.b));\n                    temp_route.insert(temp_route.begin() + j, Point(order.c, order.d));\n                    \n                    int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n                    \n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_order = order_id;\n                        best_pos = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_order == -1) break;\n        \n        const auto& best_order_data = orders[best_order];\n        size_t insert_dest_pos = best_pos + 1;\n        \n        // Find best position for destination\n        for (size_t j = best_pos + 1; j <= route.size(); j++) {\n            vector<Point> temp_route = route;\n            temp_route.insert(temp_route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n            temp_route.insert(temp_route.begin() + j, Point(best_order_data.c, best_order_data.d));\n            \n            int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n            \n            if (increase < best_increase) {\n                best_increase = increase;\n                insert_dest_pos = j;\n            }\n        }\n        \n        route.insert(route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n        route.insert(route.begin() + insert_dest_pos, Point(best_order_data.c, best_order_data.d));\n        remaining_orders.erase(best_order);\n    }\n    \n    route.push_back(Point(400, 400));\n    \n    assert(is_valid_route(selected, route));\n    return route;\n}\n\nvector<int> select_initial_orders() {\n    // Calculate center of mass for all orders\n    double center_x = 0, center_y = 0;\n    for (const auto& order : orders) {\n        center_x += (order.a + order.c) / 2.0;\n        center_y += (order.b + order.d) / 2.0;\n    }\n    center_x /= orders.size();\n    center_y /= orders.size();\n    \n    // Calculate distances from center for each order\n    vector<pair<double, int>> order_distances;\n    for (size_t i = 0; i < orders.size(); i++) {\n        const auto& order = orders[i];\n        double mid_x = (order.a + order.c) / 2.0;\n        double mid_y = (order.b + order.d) / 2.0;\n        double dist = abs(mid_x - center_x) + abs(mid_y - center_y);\n        order_distances.emplace_back(dist, i);\n    }\n    \n    // Sort by distance and select the closest 50\n    sort(order_distances.begin(), order_distances.end());\n    vector<int> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(order_distances[i].second);\n    }\n    \n    return selected;\n}\n\nvector<Point> simulated_annealing(const vector<int>& initial_selected, const vector<Point>& initial_route) {\n    vector<int> current_selected = initial_selected;\n    vector<Point> current_route = initial_route;\n    int current_distance = calculate_total_distance(current_route);\n    \n    vector<int> best_selected = current_selected;\n    vector<Point> best_route = current_route;\n    int best_distance = current_distance;\n    \n    const double initial_temp = 1000.0;\n    const double final_temp = 1.0;\n    const int iterations = 100000;\n    \n    double temp = initial_temp;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        temp = initial_temp * pow(final_temp / initial_temp, (double)iter / iterations);\n        \n        // Choose a random operation\n        int operation = uniform_int_distribution<int>(0, 2)(rng);\n        \n        if (operation == 0) {\n            // Swap two points in the route\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            int j = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            \n            if (i == j) continue;\n            \n            vector<Point> new_route = current_route;\n            swap(new_route[i], new_route[j]);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else if (operation == 1) {\n            // Reverse a segment\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 3)(rng);\n            int j = uniform_int_distribution<int>(i + 1, current_route.size() - 2)(rng);\n            \n            vector<Point> new_route = current_route;\n            reverse(new_route.begin() + i, new_route.begin() + j + 1);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else {\n            // Swap an order in the selected set with one not in the set\n            vector<int> unselected;\n            for (size_t i = 0; i < orders.size(); i++) {\n                if (find(current_selected.begin(), current_selected.end(), i) == current_selected.end()) {\n                    unselected.push_back(i);\n                }\n            }\n            \n            if (unselected.empty()) continue;\n            \n            int idx_to_remove = uniform_int_distribution<int>(0, current_selected.size() - 1)(rng);\n            int idx_to_add = uniform_int_distribution<int>(0, unselected.size() - 1)(rng);\n            \n            vector<int> new_selected = current_selected;\n            new_selected[idx_to_remove] = unselected[idx_to_add];\n            sort(new_selected.begin(), new_selected.end());\n            \n            vector<Point> new_route = construct_greedy_route(new_selected);\n            int new_distance = calculate_total_distance(new_route);\n            int delta = new_distance - current_distance;\n            \n            if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_selected = new_selected;\n                current_route = new_route;\n                current_distance = new_distance;\n                \n                if (current_distance < best_distance) {\n                    best_selected = current_selected;\n                    best_route = current_route;\n                    best_distance = current_distance;\n                }\n            }\n        }\n    }\n    \n    return best_route;\n}\n\nvoid solve() {\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n    \n    // Initialize random number generator\n    rng = mt19937(high_resolution_clock::now().time_since_epoch().count());\n    \n    // Select initial orders\n    selected_orders = select_initial_orders();\n    \n    // Construct initial route\n    route = construct_greedy_route(selected_orders);\n    \n    // Optimize with simulated annealing\n    route = simulated_annealing(selected_orders, route);\n    \n    // Output the result\n    cout << selected_orders.size();\n    for (int order_id : selected_orders) {\n        cout << \" \" << order_id + 1;  // Convert to 1-based indexing\n    }\n    cout << endl;\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << endl;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\nusing namespace std;\n\nclass DSU {\nprivate:\n    vector<int> parent;\n    vector<int> rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n\n    void union_set(int x, int y) {\n        int rx = find(x);\n        int ry = find(y);\n        if (rx == ry) {\n            return;\n        }\n        if (rank[rx] < rank[ry]) {\n            parent[rx] = ry;\n        } else if (rank[rx] > rank[ry]) {\n            parent[ry] = rx;\n        } else {\n            parent[ry] = rx;\n            rank[rx]++;\n        }\n    }\n};\n\nstruct Edge {\n    int u, v;\n    double d;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N = 400;\n    int M = 1995;\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        edges[i].index = i;\n        int u = edges[i].u, v = edges[i].v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        edges[i].d = round(dist);\n    }\n\n    vector<int> tree_id(M, -1);\n    vector<Edge> remaining_edges = edges;\n    for (int t = 0; t < 5; t++) {\n        sort(remaining_edges.begin(), remaining_edges.end(), [](const Edge& a, const Edge& b) {\n            return a.d < b.d;\n        });\n\n        DSU dsu_temp(N);\n        vector<Edge> tree_edges;\n        vector<Edge> new_remaining;\n\n        for (Edge& e : remaining_edges) {\n            int u = e.u, v = e.v;\n            if (dsu_temp.find(u) != dsu_temp.find(v)) {\n                dsu_temp.union_set(u, v);\n                tree_edges.push_back(e);\n                tree_id[e.index] = t+1;\n            } else {\n                new_remaining.push_back(e);\n            }\n        }\n\n        remaining_edges = new_remaining;\n    }\n\n    DSU dsu_online(N);\n    vector<vector<int>> comp_edge_count(N, vector<int>(N, 0));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].u, v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n        if (a != b) {\n            comp_edge_count[a][b]++;\n            comp_edge_count[b][a]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n\n        if (a == b) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n\n        comp_edge_count[a][b]--;\n        comp_edge_count[b][a]--;\n\n        bool adopt = false;\n        if (comp_edge_count[a][b] == 0) {\n            adopt = true;\n        } else {\n            double progress = static_cast<double>(i) / M;\n            double base_threshold = 1.0;\n            double max_threshold = 3.0;\n            double factor = (6.0 - tree_id[i]) / 5.0;\n            double threshold = base_threshold + progress * (max_threshold - base_threshold) * factor;\n            if (l_i <= threshold * edges[i].d) {\n                adopt = true;\n            }\n        }\n\n        if (adopt) {\n            int root_a = a;\n            int root_b = b;\n            dsu_online.union_set(u, v);\n            int new_root = dsu_online.find(u);\n            int old_root = (new_root == root_a) ? root_b : root_a;\n\n            for (int c = 0; c < N; c++) {\n                int root_c = dsu_online.find(c);\n                if (root_c != c) continue;\n                if (root_c == new_root) continue;\n                if (comp_edge_count[old_root][root_c] > 0) {\n                    comp_edge_count[new_root][root_c] += comp_edge_count[old_root][root_c];\n                    comp_edge_count[root_c][new_root] += comp_edge_count[root_c][old_root];\n                    comp_edge_count[old_root][root_c] = 0;\n                    comp_edge_count[root_c][old_root] = 0;\n                }\n            }\n\n            cout << 1 << endl;\n            cout.flush();\n        } else {\n            cout << 0 << endl;\n            cout.flush();\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\n#include <cstring>\n#include <iomanip>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\n\nstruct Position {\n    int x, y;\n    Position(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Position& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nbool adjacent(const Position& a, const Position& b) {\n    return (abs(a.x - b.x) + abs(a.y - b.y) == 1);\n}\n\nbool is_buildable(int x, int y, const vector<Position>& pets, const vector<Position>& humans) {\n    for (const auto& pet : pets) {\n        if (pet.x == x && pet.y == y) {\n            return false;\n        }\n    }\n    for (const auto& human : humans) {\n        if (human.x == x && human.y == y) {\n            return false;\n        }\n    }\n\n    vector<pair<int,int>> adj = {{x-1,y}, {x+1,y}, {x,y-1}, {x,y+1}};\n    for (const auto& [ax, ay] : adj) {\n        if (ax < 1 || ax > 30 || ay < 1 || ay > 30) {\n            continue;\n        }\n        for (const auto& pet : pets) {\n            if (pet.x == ax && pet.y == ay) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nbool is_safe_to_move(int x, int y, bool grid[31][31], const set<Position>& building_set) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) {\n        return false;\n    }\n    if (!grid[x][y]) {\n        return false;\n    }\n    if (building_set.find(Position(x,y)) != building_set.end()) {\n        return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M;\n    cin >> N;\n    vector<Position> pets(N);\n    vector<int> pet_types(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n    }\n    cin >> M;\n    vector<Position> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n\n    bool grid[31][31];\n    for (int i = 1; i <= 30; i++) {\n        for (int j = 1; j <= 30; j++) {\n            grid[i][j] = true;\n        }\n    }\n\n    vector<Position> perimeter;\n    for (int y = 10; y <= 20; y++) {\n        perimeter.push_back(Position(10, y));\n    }\n    for (int x = 11; x <= 20; x++) {\n        perimeter.push_back(Position(x, 20));\n    }\n    for (int y = 19; y >= 10; y--) {\n        perimeter.push_back(Position(20, y));\n    }\n    for (int x = 19; x >= 11; x--) {\n        perimeter.push_back(Position(x, 10));\n    }\n\n    vector<queue<Position>> human_queues(M);\n    int segment_size = perimeter.size() / M;\n    int extra = perimeter.size() % M;\n    int index = 0;\n    for (int i = 0; i < M; i++) {\n        int size = segment_size + (i < extra ? 1 : 0);\n        for (int j = 0; j < size; j++) {\n            human_queues[i].push(perimeter[index++]);\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n\n        if (turn < 20) {\n            for (int i = 0; i < M; i++) {\n                int x = humans[i].x;\n                int y = humans[i].y;\n                if (x >= 10 && x <= 20 && y >= 10 && y <= 20) {\n                    actions[i] = '.';\n                } else {\n                    int dx = 15 - x;\n                    int dy = 15 - y;\n                    if (abs(dx) > abs(dy)) {\n                        actions[i] = (dx > 0) ? 'D' : 'U';\n                    } else {\n                        actions[i] = (dy > 0) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            set<Position> building_set;\n            vector<bool> will_build(M, false);\n\n            for (int i = 0; i < M; i++) {\n                if (human_queues[i].empty()) continue;\n                Position target = human_queues[i].front();\n                if (adjacent(humans[i], target) && is_buildable(target.x, target.y, pets, humans)) {\n                    building_set.insert(target);\n                    will_build[i] = true;\n                }\n            }\n\n            for (int i = 0; i < M; i++) {\n                if (will_build[i]) {\n                    Position target = human_queues[i].front();\n                    int dx = humans[i].x - target.x;\n                    int dy = humans[i].y - target.y;\n                    if (dx == -1) actions[i] = 'd';\n                    else if (dx == 1) actions[i] = 'u';\n                    else if (dy == -1) actions[i] = 'r';\n                    else if (dy == 1) actions[i] = 'l';\n                    human_queues[i].pop();\n                } else {\n                    if (human_queues[i].empty()) {\n                        actions[i] = '.';\n                    } else {\n                        Position target = human_queues[i].front();\n                        if (adjacent(humans[i], target)) {\n                            human_queues[i].pop();\n                            human_queues[i].push(target);\n                            actions[i] = '.';\n                        } else {\n                            vector<pair<int,int>> move_deltas = {{-1,0},{1,0},{0,-1},{0,1}};\n                            vector<char> move_dirs = {'U','D','L','R'};\n                            char best_move = '.';\n                            int best_dist = 1000000;\n                            for (int j = 0; j < 4; j++) {\n                                int nx = humans[i].x + move_deltas[j].first;\n                                int ny = humans[i].y + move_deltas[j].second;\n                                if (!is_safe_to_move(nx, ny, grid, building_set)) {\n                                    continue;\n                                }\n                                int d = abs(nx - target.x) + abs(ny - target.y);\n                                if (d < best_dist) {\n                                    best_dist = d;\n                                    best_move = move_dirs[j];\n                                }\n                            }\n                            actions[i] = best_move;\n                        }\n                    }\n                }\n            }\n\n            for (const auto& pos : building_set) {\n                grid[pos.x][pos.y] = false;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == '.') break;\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <climits>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    string path;\n};\n\nvector<string> h_global, v_global;\n\nstring bfs_shortest_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\"});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            return s.path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj]});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nstring bfs_alternative_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v, const string& shortest_path) {\n    vector<string> h_temp = h;\n    vector<string> v_temp = v;\n    string best_alt = \"\";\n    int best_len = INT_MAX;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \n    int ci = si, cj = sj;\n    for (char c : shortest_path) {\n        int ni = ci, nj = cj;\n        if (c == 'U') {\n            ni--;\n            if (ci > 0) v_temp[ci-1][cj] = '1';\n        } else if (c == 'D') {\n            ni++;\n            if (ci < 19) v_temp[ci][cj] = '1';\n        } else if (c == 'L') {\n            nj--;\n            if (cj > 0) h_temp[ci][cj-1] = '1';\n        } else if (c == 'R') {\n            nj++;\n            if (cj < 19) h_temp[ci][cj] = '1';\n        }\n        \n        string alt_path = bfs_shortest_path(si, sj, ti, tj, h_temp, v_temp);\n        if (!alt_path.empty() && alt_path.size() < best_len && alt_path != shortest_path) {\n            best_len = alt_path.size();\n            best_alt = alt_path;\n        }\n        \n        ci = ni;\n        cj = nj;\n    }\n    \n    return best_alt;\n}\n\ndouble compute_expected_score(const string& path, int r, int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v, double p) {\n    int L = path.size();\n    int total_steps = L * r;\n    vector<vector<double>> current(20, vector<double>(20, 0.0));\n    current[si][sj] = 1.0;\n    double expected_score = 0.0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \n    for (int t = 0; t < total_steps; t++) {\n        vector<vector<double>> next(20, vector<double>(20, 0.0));\n        for (int i = 0; i < 20; i++) {\n            for (int j = 0; j < 20; j++) {\n                if (current[i][j] == 0.0) continue;\n                if (i == ti && j == tj) continue;\n                \n                int move_index = t / r;\n                if (move_index >= L) {\n                    next[i][j] += current[i][j];\n                    continue;\n                }\n                \n                char c = path[move_index];\n                double prob_stay = p;\n                double prob_move = 1.0 - p;\n                int ni = i, nj = j;\n                bool move_possible = false;\n                \n                if (c == 'U') {\n                    if (i > 0 && v[i-1][j] == '0') {\n                        ni = i-1;\n                        move_possible = true;\n                    }\n                } else if (c == 'D') {\n                    if (i < 19 && v[i][j] == '0') {\n                        ni = i+1;\n                        move_possible = true;\n                    }\n                } else if (c == 'L') {\n                    if (j > 0 && h[i][j-1] == '0') {\n                        nj = j-1;\n                        move_possible = true;\n                    }\n                } else if (c == 'R') {\n                    if (j < 19 && h[i][j] == '0') {\n                        nj = j+1;\n                        move_possible = true;\n                    }\n                }\n                \n                if (move_possible) {\n                    next[i][j] += current[i][j] * prob_stay;\n                    next[ni][nj] += current[i][j] * prob_move;\n                } else {\n                    next[i][j] += current[i][j];\n                }\n            }\n        }\n        \n        double reached_this_step = next[ti][tj];\n        if (reached_this_step > 0) {\n            expected_score += (401 - (t+1)) * reached_this_step;\n            next[ti][tj] = 0;\n        }\n        \n        current = next;\n    }\n    \n    return expected_score;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    h_global = h;\n    v_global = v;\n    \n    string shortest_path = bfs_shortest_path(si, sj, ti, tj, h, v);\n    if (shortest_path.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    string alternative_path = bfs_alternative_path(si, sj, ti, tj, h, v, shortest_path);\n    \n    vector<string> candidate_paths = {shortest_path};\n    if (!alternative_path.empty()) {\n        candidate_paths.push_back(alternative_path);\n    }\n    \n    string best_path = \"\";\n    double best_score = -1;\n    int best_r = 1;\n    \n    for (const string& path : candidate_paths) {\n        int L = path.size();\n        int max_r = 200 / L;\n        vector<int> r_candidates = {1, 2, 3, 4, 5};\n        for (int r = 1; r <= max_r; r++) {\n            if (r > 5) break;\n            r_candidates.push_back(r);\n        }\n        \n        for (int r : r_candidates) {\n            double score = compute_expected_score(path, r, si, sj, ti, tj, h, v, p);\n            if (score > best_score) {\n                best_score = score;\n                best_path = path;\n                best_r = r;\n            }\n        }\n    }\n    \n    string robust_path;\n    for (char c : best_path) {\n        robust_path += string(best_r, c);\n    }\n    \n    cout << robust_path << endl;\n    \n    return 0;\n}","ahc010":"","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <unordered_set>\n#include <tuple>\n#include <cmath>\n#include <climits>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nconst int dx[] = {0, 0, -1, 1};\nconst int dy[] = {-1, 1, 0, 0};\nconst char dir_char[] = {'L', 'R', 'U', 'D'};\n\nstruct State {\n    vector<vector<int>> board;\n    int empty_x, empty_y;\n    int last_move;\n    int connections;\n    int max_component;\n    string moves;\n};\n\nbool are_connected(int tile1, int tile2, int direction) {\n    if (direction == 0) return (tile1 & 1) && (tile2 & 4);\n    if (direction == 1) return (tile1 & 4) && (tile2 & 1);\n    if (direction == 2) return (tile1 & 2) && (tile2 & 8);\n    if (direction == 3) return (tile1 & 8) && (tile2 & 2);\n    return false;\n}\n\nint count_connections_full(const vector<vector<int>>& board, int N) {\n    int connections = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            if (i < N - 1 && board[i+1][j] != 0) {\n                if (are_connected(tile, board[i+1][j], 3)) {\n                    connections++;\n                }\n            }\n            if (j < N - 1 && board[i][j+1] != 0) {\n                if (are_connected(tile, board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint compute_components(vector<vector<int>>& board, int N) {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_comp = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int comp_size = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                comp_size++;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d];\n                    int ny = y + dy[d];\n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && board[nx][ny] != 0) {\n                        if (are_connected(board[x][y], board[nx][ny], d)) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            max_comp = max(max_comp, comp_size);\n        }\n    }\n    return max_comp;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(0));\n\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int empty_x = -1, empty_y = -1;\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            if (c == '0') {\n                initial_board[i][j] = 0;\n                empty_x = i;\n                empty_y = j;\n            } else {\n                if (c >= '0' && c <= '9') {\n                    initial_board[i][j] = c - '0';\n                } else {\n                    initial_board[i][j] = 10 + (c - 'a');\n                }\n            }\n        }\n    }\n\n    vector<State> best_states;\n    int num_iterations = 2;\n    double gamma = 1.0;\n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        State current;\n        current.board = initial_board;\n        current.empty_x = empty_x;\n        current.empty_y = empty_y;\n        current.last_move = -1;\n        current.connections = count_connections_full(current.board, N);\n        current.max_component = compute_components(current.board, N);\n        current.moves = \"\";\n\n        for (int step = 0; step < T; ++step) {\n            if (step % 10 == 0) {\n                current.max_component = compute_components(current.board, N);\n                if (current.max_component == N * N - 1) {\n                    break;\n                }\n            }\n\n            int best_delta = -1000000;\n            int best_move = -1;\n            int best_new_connections = -1;\n\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == (current.last_move ^ 1)) continue;\n\n                int nx = current.empty_x + dx[dir];\n                int ny = current.empty_y + dy[dir];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n\n                int new_connections = current.connections;\n                int tile = current.board[nx][ny];\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = nx + dx[d];\n                    int y = ny + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections--;\n                        }\n                    }\n                }\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = current.empty_x + dx[d];\n                    int y = current.empty_y + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (x == nx && y == ny) continue;\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections++;\n                        }\n                    }\n                }\n\n                double delta = new_connections - current.connections;\n                delta += gamma * (current.max_component * 0.01);\n                delta += (rand() % 100) * 0.001;\n\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_move = dir;\n                    best_new_connections = new_connections;\n                }\n            }\n\n            if (best_move == -1) break;\n\n            int nx = current.empty_x + dx[best_move];\n            int ny = current.empty_y + dy[best_move];\n            swap(current.board[current.empty_x][current.empty_y], current.board[nx][ny]);\n            current.empty_x = nx;\n            current.empty_y = ny;\n            current.connections = best_new_connections;\n            current.moves += dir_char[best_move];\n            current.last_move = best_move;\n        }\n\n        current.max_component = compute_components(current.board, N);\n        best_states.push_back(current);\n    }\n\n    sort(best_states.begin(), best_states.end(), [](const State& a, const State& b) {\n        if (a.max_component != b.max_component) {\n            return a.max_component > b.max_component;\n        }\n        return a.moves.size() < b.moves.size();\n    });\n\n    cout << best_states[0].moves << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <set>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nusing Point = pair<long long, long long>;\nusing Line = pair<Point, Point>;\n\nconst long long RADIUS = 10000;\nconst long long RADIUS_SQ = 100000000;\n\nstruct Solution {\n    vector<Line> lines;\n    double score;\n};\n\nlong long cross(const Point& O, const Point& A, const Point& B) {\n    return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);\n}\n\nlong long side(const Line& line, const Point& P) {\n    const Point& A = line.first;\n    const Point& B = line.second;\n    return cross(A, B, P);\n}\n\nbool is_inside_circle(const Point& p) {\n    return p.first * p.first + p.second * p.second < RADIUS_SQ;\n}\n\ndouble calculate_score(const vector<int>& a, const vector<int>& b) {\n    int total_distributed = 0;\n    int total_attendees = 0;\n    \n    for (int d = 1; d <= 10; d++) {\n        total_distributed += min(a[d-1], b[d-1]);\n        total_attendees += a[d-1];\n    }\n    \n    return 1000000.0 * total_distributed / total_attendees;\n}\n\nvector<int> count_strawberries(const vector<Point>& strawberries, const vector<Line>& lines) {\n    if (lines.empty()) {\n        return {static_cast<int>(strawberries.size())};\n    }\n    \n    unordered_map<string, int> region_counts;\n    \n    for (const auto& strawberry : strawberries) {\n        string signature;\n        bool on_line = false;\n        \n        for (const auto& line : lines) {\n            long long s = side(line, strawberry);\n            if (s == 0) {\n                on_line = true;\n                break;\n            }\n            signature += (s > 0) ? '1' : '0';\n        }\n        \n        if (!on_line) {\n            region_counts[signature]++;\n        }\n    }\n    \n    vector<int> distribution(10, 0);\n    for (const auto& [_, count] : region_counts) {\n        if (count >= 1 && count <= 10) {\n            distribution[count-1]++;\n        }\n    }\n    \n    return distribution;\n}\n\nvector<Line> generate_candidate_lines(const vector<Point>& strawberries, mt19937& rng, int num_candidates = 20) {\n    vector<Line> candidates;\n    int n = strawberries.size();\n    \n    // Random lines through two strawberries\n    for (int i = 0; i < num_candidates / 2 && i < n * n / 2; i++) {\n        int idx1 = rng() % n;\n        int idx2 = rng() % n;\n        if (idx1 != idx2) {\n            candidates.push_back({strawberries[idx1], strawberries[idx2]});\n        }\n    }\n    \n    // Random lines in random directions\n    uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n    for (int i = 0; i < num_candidates / 2; i++) {\n        Point p1 = {coord_dist(rng), coord_dist(rng)};\n        Point p2 = {coord_dist(rng), coord_dist(rng)};\n        candidates.push_back({p1, p2});\n    }\n    \n    return candidates;\n}\n\nSolution solve(int N, int K, const vector<int>& a, const vector<Point>& strawberries) {\n    mt19937 rng(12345);\n    \n    Solution best_solution;\n    best_solution.lines = {};\n    vector<int> initial_dist = count_strawberries(strawberries, {});\n    best_solution.score = calculate_score(a, initial_dist);\n    \n    vector<Line> current_lines;\n    double current_score = best_solution.score;\n    \n    int no_improve_count = 0;\n    int max_no_improve = 5; // Stop after 5 consecutive non-improving iterations\n    \n    for (int iter = 0; iter < min(K, 50); iter++) { // Limit to 50 iterations\n        vector<Line> candidates = generate_candidate_lines(strawberries, rng);\n        \n        Line best_line;\n        double best_score = current_score;\n        bool improved = false;\n        \n        for (const auto& line : candidates) {\n            vector<Line> new_lines = current_lines;\n            new_lines.push_back(line);\n            \n            vector<int> distribution = count_strawberries(strawberries, new_lines);\n            double score = calculate_score(a, distribution);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = line;\n                improved = true;\n            }\n        }\n        \n        if (improved) {\n            current_lines.push_back(best_line);\n            current_score = best_score;\n            no_improve_count = 0;\n            \n            if (current_score > best_solution.score) {\n                best_solution.lines = current_lines;\n                best_solution.score = current_score;\n            }\n        } else {\n            no_improve_count++;\n            if (no_improve_count >= max_no_improve) {\n                break;\n            }\n            // Add a random line anyway to continue exploring\n            uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n            Point p1 = {coord_dist(rng), coord_dist(rng)};\n            Point p2 = {coord_dist(rng), coord_dist(rng)};\n            current_lines.push_back({p1, p2});\n        }\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(10);\n    for (int i = 0; i < 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].first >> strawberries[i].second;\n    }\n    \n    Solution solution = solve(N, K, a, strawberries);\n    \n    cout << solution.lines.size() << \"\\n\";\n    for (const auto& line : solution.lines) {\n        cout << line.first.first << \" \" << line.first.second << \" \"\n             << line.second.first << \" \" << line.second.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    int c = (N - 1) / 2;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> col_dots(N);\n    vector<set<int>> row_dots(N);\n    set<tuple<int, int, int, int>> segments;\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    while (true) {\n        vector<pair<int, int>> non_dot_points;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    non_dot_points.emplace_back(x, y);\n                }\n            }\n        }\n\n        if (non_dot_points.empty()) {\n            break;\n        }\n\n        sort(non_dot_points.begin(), non_dot_points.end(), \n            [c](const pair<int, int>& a, const pair<int, int>& b) {\n                int wa = (a.first - c) * (a.first - c) + (a.second - c) * (a.second - c) + 1;\n                int wb = (b.first - c) * (b.first - c) + (b.second - c) * (b.second - c) + 1;\n                return wa > wb;\n            });\n\n        tuple<int, int, int, int, int, int, int, int> best_op;\n        vector<tuple<int, int, int, int>> best_segments_list;\n        int best_weight = -1;\n        bool found = false;\n\n        for (auto [x, y] : non_dot_points) {\n            int weight = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n            bool found_axis = false;\n            for (int x2 = 0; x2 < N; x2++) {\n                if (x2 == x) continue;\n                if (!grid[x2][y]) continue;\n\n                if (col_dots[x].size() <= col_dots[x2].size()) {\n                    for (int y2 : col_dots[x]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x2].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                } else {\n                    for (int y2 : col_dots[x2]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                }\n            }\n\n            bool found_diamond = false;\n            for (int role = 0; role < 4; role++) {\n                int max_a;\n                if (role == 0) {\n                    max_a = min({(N - 1 - x) / 2, (N - 1 - y), y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x + a;\n                        int cy = y;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + 2 * a - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + i;\n                            int x2 = x + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a + i;\n                            int y1 = y + a - i;\n                            int x2 = x + a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + 2 * a - i;\n                            int y1 = y - i;\n                            int x2 = x + 2 * a - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a + i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 1) {\n                    max_a = min({x, N - 1 - x, y / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y - a;\n                        int Ax = cx - a, Ay = cy;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - 2 * a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y - i;\n                            int x2 = x + i + 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - 2 * a + i;\n                            int x2 = x - i - 1;\n                            int y2 = y - 2 * a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y - a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Dx, Dy, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 2) {\n                    max_a = min({x / 2, y, N - 1 - y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x - a;\n                        int cy = y;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - 2 * a + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - i;\n                            int x2 = x - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a - i;\n                            int y1 = y - a + i;\n                            int x2 = x - a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - 2 * a + i;\n                            int y1 = y + i;\n                            int x2 = x - 2 * a + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a - i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Ax, Ay, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 3) {\n                    max_a = min({x, N - 1 - x, (N - 1 - y) / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y + a;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + 2 * a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y + i;\n                            int x2 = x - i - 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + 2 * a - i;\n                            int x2 = x + i + 1;\n                            int y2 = y + 2 * a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y + a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                }\n            }\n        }\n\n        if (!found) {\n            break;\n        }\n\n        auto [x, y, x1, y1, x2, y2, x3, y3] = best_op;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n        for (auto& seg : best_segments_list) {\n            segments.insert(seg);\n        }\n        operations.push_back(best_op);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        auto [x, y, x1, y1, x2, y2, x3, y3] = op;\n        cout << x << \" \" << y << \" \" << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \" \" << x3 << \" \" << y3 << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> cells;\n    int rows, cols;\n    \n    Grid(int r = 10, int c = 10) : rows(r), cols(c), cells(r, vector<int>(c, 0)) {}\n    \n    bool is_valid(int r, int c) const {\n        return r >= 0 && r < rows && c >= 0 && c < cols;\n    }\n    \n    int get_empty_count() const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) count++;\n            }\n        }\n        return count;\n    }\n    \n    pair<int, int> get_nth_empty(int n) const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) {\n                    count++;\n                    if (count == n) return {r, c};\n                }\n            }\n        }\n        return {-1, -1}; // Should not happen\n    }\n    \n    void tilt(char direction) {\n        if (direction == 'F') { // Forward (up)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = 0;\n                for (int r = 0; r < rows; ++r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'B') { // Backward (down)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = rows - 1;\n                for (int r = rows - 1; r >= 0; --r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        } else if (direction == 'L') { // Left\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = 0;\n                for (int c = 0; c < cols; ++c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'R') { // Right\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = cols - 1;\n                for (int c = cols - 1; c >= 0; --c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    void place(int r, int c, int flavor) {\n        cells[r][c] = flavor;\n    }\n    \n    double calculate_score() const {\n        vector<bool> visited(rows * cols, false);\n        vector<int> component_sizes;\n        \n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0 && !visited[r * cols + c]) {\n                    int flavor = cells[r][c];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    visited[r * cols + c] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int dr = -1; dr <= 1; ++dr) {\n                            for (int dc = -1; dc <= 1; ++dc) {\n                                if (abs(dr) + abs(dc) != 1) continue;\n                                int nr = cr + dr;\n                                int nc = cc + dc;\n                                if (is_valid(nr, nc) && cells[nr][nc] == flavor && \n                                    !visited[nr * cols + nc]) {\n                                    visited[nr * cols + nc] = true;\n                                    q.push({nr, nc});\n                                }\n                            }\n                        }\n                    }\n                    \n                    component_sizes.push_back(size);\n                }\n            }\n        }\n        \n        double sum_squares = 0;\n        for (int size : component_sizes) {\n            sum_squares += size * size;\n        }\n        \n        array<int, 4> flavor_counts = {0, 0, 0, 0};\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0) {\n                    flavor_counts[cells[r][c]]++;\n                }\n            }\n        }\n        \n        double denominator = 0;\n        for (int i = 1; i <= 3; ++i) {\n            denominator += flavor_counts[i] * flavor_counts[i];\n        }\n        \n        return sum_squares / denominator;\n    }\n    \n    pair<int, int> get_tilted_position(int r, int c, char direction) const {\n        if (direction == 'F') { // Forward (up)\n            while (r > 0 && cells[r - 1][c] == 0) {\n                r--;\n            }\n        } else if (direction == 'B') { // Backward (down)\n            while (r < rows - 1 && cells[r + 1][c] == 0) {\n                r++;\n            }\n        } else if (direction == 'L') { // Left\n            while (c > 0 && cells[r][c - 1] == 0) {\n                c--;\n            }\n        } else if (direction == 'R') { // Right\n            while (c < cols - 1 && cells[r][c + 1] == 0) {\n                c++;\n            }\n        }\n        return {r, c};\n    }\n    \n    int count_same_flavor_neighbors(int r, int c, int flavor) const {\n        int count = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n    \n    bool would_break_cluster(int r, int c, int flavor, char direction) const {\n        // Check if tilting would disconnect this candy from its current cluster\n        int neighbors = count_same_flavor_neighbors(r, c, flavor);\n        if (neighbors <= 1) return false; // Can't break a cluster if already isolated or only one neighbor\n        \n        // Simulate the tilt and check if it disconnects the candy\n        auto [new_r, new_c] = get_tilted_position(r, c, direction);\n        if (new_r == r && new_c == c) return false; // No movement\n        \n        // After movement, check if it still has neighbors\n        int new_neighbors = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = new_r + dr;\n                int nc = new_c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    // Check if this neighbor would also move to a position adjacent to the candy\n                    auto [neighbor_new_r, neighbor_new_c] = get_tilted_position(nr, nc, direction);\n                    if (abs(neighbor_new_r - new_r) + abs(neighbor_new_c - new_c) == 1) {\n                        new_neighbors++;\n                    }\n                }\n            }\n        }\n        \n        return new_neighbors == 0;\n    }\n    \n    int count_flavor_in_area(int r, int c, int flavor, int radius) const {\n        int count = 0;\n        for (int dr = -radius; dr <= radius; ++dr) {\n            for (int dc = -radius; dc <= radius; ++dc) {\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nclass CandyClustering {\nprivate:\n    Grid grid;\n    vector<int> flavors;\n    array<int, 4> flavor_counts = {0, 0, 0, 0};\n    vector<pair<int, int>> flavor_region_centers; // Fixed centers based on regions\n    vector<pair<int, int>> flavor_centers; // Dynamic centers of mass\n    vector<vector<int>> flavor_regions; // Which region each cell belongs to\n    \npublic:\n    CandyClustering(const vector<int>& f) : flavors(f) {\n        // Count flavors\n        for (int f : flavors) {\n            flavor_counts[f]++;\n        }\n        \n        // Initialize regions and centers\n        initialize_flavor_regions();\n        initialize_flavor_centers();\n    }\n    \n    void initialize_flavor_regions() {\n        flavor_regions.assign(grid.rows, vector<int>(grid.cols, 0));\n        \n        // Sort flavors by count (descending)\n        vector<pair<int, int>> sorted_flavors;\n        for (int i = 1; i <= 3; ++i) {\n            sorted_flavors.emplace_back(flavor_counts[i], i);\n        }\n        sort(sorted_flavors.rbegin(), sorted_flavors.rend());\n        \n        // Assign regions proportional to flavor counts\n        int total = grid.rows * grid.cols;\n        int assigned = 0;\n        \n        for (auto [count, flavor] : sorted_flavors) {\n            if (count == 0) continue;\n            \n            // Calculate how many cells this flavor should get\n            int cells_needed = round(static_cast<double>(count) / 100 * total);\n            \n            // Assign contiguous blocks\n            int rows_needed = (cells_needed + grid.cols - 1) / grid.cols;\n            \n            // Start from the top-left and assign rows\n            for (int r = assigned / grid.cols; r < grid.rows && rows_needed > 0; ++r) {\n                for (int c = 0; c < grid.cols; ++c) {\n                    if (flavor_regions[r][c] == 0) {\n                        flavor_regions[r][c] = flavor;\n                        cells_needed--;\n                        if (cells_needed <= 0) break;\n                    }\n                }\n                if (cells_needed <= 0) break;\n                rows_needed--;\n            }\n            \n            assigned += count;\n        }\n    }\n    \n    void initialize_flavor_centers() {\n        flavor_region_centers.resize(4);\n        flavor_centers.resize(4);\n        \n        // Calculate the center of each flavor's region\n        array<vector<pair<int, int>>, 4> region_positions;\n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (flavor_regions[r][c] != 0) {\n                    region_positions[flavor_regions[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!region_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : region_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_region_centers[f] = {sum_r / region_positions[f].size(), \n                                          sum_c / region_positions[f].size()};\n                flavor_centers[f] = flavor_region_centers[f];\n            }\n        }\n    }\n    \n    char decide_direction(int step, int pos) {\n        auto [r, c] = grid.get_nth_empty(pos);\n        int flavor = flavors[step - 1];\n        grid.place(r, c, flavor);\n        \n        if (step == 100) return ' ';\n        \n        // Update centers more frequently\n        if (step % 5 == 0) {\n            update_flavor_centers();\n        }\n        \n        char best_dir = 'F';\n        double best_score = -1e9;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid temp_grid = grid;\n            temp_grid.tilt(dir);\n            \n            double score = calculate_direction_score(temp_grid, flavor, r, c, dir, step);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        grid.tilt(best_dir);\n        return best_dir;\n    }\n    \n    void update_flavor_centers() {\n        array<vector<pair<int, int>>, 4> flavor_positions;\n        \n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (grid.cells[r][c] != 0) {\n                    flavor_positions[grid.cells[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!flavor_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : flavor_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_centers[f] = {sum_r / flavor_positions[f].size(), \n                                     sum_c / flavor_positions[f].size()};\n            }\n        }\n    }\n    \n    double calculate_direction_score(const Grid& g, int flavor, int r, int c, char dir, int step) {\n        double score = 0;\n        \n        // Get new position after tilting\n        auto [new_r, new_c] = g.get_tilted_position(r, c, dir);\n        \n        // Distance to dynamic center (center of mass)\n        auto center = flavor_centers[flavor];\n        double distance_before = sqrt(pow(r - center.first, 2) + pow(c - center.second, 2));\n        double distance_after = sqrt(pow(new_r - center.first, 2) + pow(new_c - center.second, 2));\n        score += (distance_before - distance_after) * 15;\n        \n        // Distance to fixed region center\n        auto region_center = flavor_region_centers[flavor];\n        double region_distance_before = sqrt(pow(r - region_center.first, 2) + pow(c - region_center.second, 2));\n        double region_distance_after = sqrt(pow(new_r - region_center.first, 2) + pow(new_c - region_center.second, 2));\n        score += (region_distance_before - region_distance_after) * 5;\n        \n        // Same-flavor neighbors\n        int same_flavor_neighbors = g.count_same_flavor_neighbors(new_r, new_c, flavor);\n        score += same_flavor_neighbors * 100;\n        \n        // Density of same flavor in the area\n        int density = g.count_flavor_in_area(new_r, new_c, flavor, 2);\n        score += density * 10;\n        \n        // Penalty for isolation\n        if (same_flavor_neighbors == 0) {\n            score -= 30;\n        }\n        \n        // Penalty for breaking clusters\n        if (grid.would_break_cluster(r, c, flavor, dir)) {\n            score -= 50;\n        }\n        \n        // Stage-specific scoring\n        if (step < 30) {\n            // Early stage: prioritize moving to region\n            score += (region_distance_before - region_distance_after) * 10;\n        } else if (step < 70) {\n            // Middle stage: balance between region and clustering\n            score += (distance_before - distance_after) * 10;\n        } else {\n            // Late stage: prioritize clustering and overall score\n            double current_score = grid.calculate_score();\n            double new_score = g.calculate_score();\n            score += (new_score - current_score) * 5000;\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n    \n    CandyClustering solver(flavors);\n    \n    for (int t = 1; t <= 100; ++t) {\n        int pos;\n        cin >> pos;\n        \n        char direction = solver.decide_direction(t, pos);\n        \n        if (t < 100) {\n            cout << direction << endl;\n            cout.flush();\n        }\n    }\n    \n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n#include <utility>\n#include <iomanip>\n\nusing namespace std;\n\nvector<pair<int, int>> generate_clique_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int c = 2; c <= N; ++c) {\n        pairs.push_back({c, 0});\n    }\n    return pairs;\n}\n\nvector<pair<int, int>> generate_bipartite_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int a = 1; a <= N/2; ++a) {\n        for (int b = a; b <= N - a; ++b) {\n            pairs.push_back({a, b});\n        }\n    }\n    return pairs;\n}\n\nvector<double> get_expected_clique_degrees(int c, int N, double eps) {\n    double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    for (int i = 0; i < N - c; ++i) {\n        deg[i] = exp_iso;\n    }\n    for (int i = N - c; i < N; ++i) {\n        deg[i] = exp_clique;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_bipartite_degrees(int a, int b, int N, double eps) {\n    double exp_a = b * (1 - 2 * eps) + eps * (N - 1);\n    double exp_b = a * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    int idx = 0;\n    for (int i = 0; i < N - a - b; ++i) {\n        deg[idx++] = exp_iso;\n    }\n    for (int i = 0; i < b; ++i) {\n        deg[idx++] = exp_b;\n    }\n    for (int i = 0; i < a; ++i) {\n        deg[idx++] = exp_a;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_star_degrees(int N, double eps) {\n    double exp_center = (N - 1) * (1 - eps);\n    double exp_leaf = 1 + (N - 2) * eps;\n    vector<double> deg(N);\n    deg[0] = exp_center;\n    for (int i = 1; i < N; ++i) {\n        deg[i] = exp_leaf;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    int N = 4;\n    while (true) {\n        int num_cliques = max(0, N - 1);\n        int num_bipartite = (N / 2) * ((N + 1) / 2);\n        int num_graphs = num_cliques + num_bipartite;\n        if (num_graphs >= M) {\n            break;\n        }\n        N++;\n        if (N > 100) {\n            N = 100;\n            break;\n        }\n    }\n\n    vector<pair<int, int>> clique_pairs = generate_clique_pairs(N);\n    vector<pair<int, int>> bipartite_pairs = generate_bipartite_pairs(N);\n\n    vector<pair<int, int>> candidate_pairs;\n    candidate_pairs.insert(candidate_pairs.end(), clique_pairs.begin(), clique_pairs.end());\n    candidate_pairs.insert(candidate_pairs.end(), bipartite_pairs.begin(), bipartite_pairs.end());\n\n    vector<vector<double>> candidate_expected;\n    for (auto& p : candidate_pairs) {\n        if (p.second == 0) {\n            candidate_expected.push_back(get_expected_clique_degrees(p.first, N, eps));\n        } else {\n            candidate_expected.push_back(get_expected_bipartite_degrees(p.first, p.second, N, eps));\n        }\n    }\n\n    vector<int> selected_indices;\n    if (M > 0) {\n        selected_indices.push_back(0);\n    }\n\n    for (int i = 1; i < M; ++i) {\n        double max_min_dist_sq = -1.0;\n        int best_index = -1;\n\n        for (int idx = 0; idx < candidate_expected.size(); ++idx) {\n            if (find(selected_indices.begin(), selected_indices.end(), idx) != selected_indices.end()) {\n                continue;\n            }\n\n            double min_dist_sq = numeric_limits<double>::max();\n            for (int sel : selected_indices) {\n                double dist_sq = 0.0;\n                for (int j = 0; j < N; ++j) {\n                    double diff = candidate_expected[idx][j] - candidate_expected[sel][j];\n                    dist_sq += diff * diff;\n                }\n                if (dist_sq < min_dist_sq) {\n                    min_dist_sq = dist_sq;\n                }\n            }\n\n            if (min_dist_sq > max_min_dist_sq) {\n                max_min_dist_sq = min_dist_sq;\n                best_index = idx;\n            }\n        }\n\n        if (best_index != -1) {\n            selected_indices.push_back(best_index);\n        }\n    }\n\n    cout << N << endl;\n    for (int idx : selected_indices) {\n        auto p = candidate_pairs[idx];\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        if (p.second == 0) {\n            int c = p.first;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if (i < c && j < c) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        } else {\n            int a = p.first;\n            int b = p.second;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i < a && j >= a && j < a + b) || (j < a && i >= a && i < a + b)) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    vector<vector<double>> selected_expected;\n    for (int idx : selected_indices) {\n        selected_expected.push_back(candidate_expected[idx]);\n    }\n\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n\n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[idx] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                idx++;\n            }\n        }\n\n        sort(deg.begin(), deg.end());\n\n        int best_index = -1;\n        double best_dist_sq = numeric_limits<double>::max();\n\n        for (int t = 0; t < M; ++t) {\n            double dist_sq = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = deg[i] - selected_expected[t][i];\n                dist_sq += diff * diff;\n            }\n            if (dist_sq < best_dist_sq) {\n                best_dist_sq = dist_sq;\n                best_index = t;\n            }\n        }\n\n        cout << best_index << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n#include <unordered_map>\n#include <numeric>\n#include <stack>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int index;\n};\n\nusing ll = long long;\n\nll compute_alt(int u, int v, const Edge& e, const vector<vector<pair<int, int>>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, LLONG_MAX);\n    dist[u] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n    pq.push({0, u});\n\n    while (!pq.empty()) {\n        auto [d, node] = pq.top();\n        pq.pop();\n        if (d != dist[node]) continue;\n        if (node == v) return d;\n        for (auto [neighbor, weight] : adj[node]) {\n            if ((node == e.u && neighbor == e.v) || (node == e.v && neighbor == e.u)) {\n                continue;\n            }\n            ll new_dist = d + weight;\n            if (new_dist < dist[neighbor]) {\n                dist[neighbor] = new_dist;\n                pq.push({new_dist, neighbor});\n            }\n        }\n    }\n    return dist[v];\n}\n\nvector<double> compute_betweenness(const vector<vector<pair<int, int>>>& adj, int N) {\n    vector<double> betweenness(N, 0.0);\n    vector<vector<int>> predecessors(N);\n    vector<ll> dist(N);\n    vector<int> count(N);\n    vector<double> dependency(N, 0.0);\n    \n    for (int s = 0; s < N; s++) {\n        // Initialize\n        fill(predecessors.begin(), predecessors.end(), vector<int>());\n        fill(dist.begin(), dist.end(), LLONG_MAX);\n        fill(count.begin(), count.end(), 0);\n        fill(dependency.begin(), dependency.end(), 0.0);\n        \n        stack<int> stk;\n        queue<int> q;\n        \n        dist[s] = 0;\n        count[s] = 1;\n        q.push(s);\n        \n        while (!q.empty()) {\n            int v = q.front();\n            q.pop();\n            stk.push(v);\n            \n            for (auto [w, weight] : adj[v]) {\n                if (dist[w] > dist[v] + weight) {\n                    dist[w] = dist[v] + weight;\n                    predecessors[w].clear();\n                    predecessors[w].push_back(v);\n                    count[w] = count[v];\n                    q.push(w);\n                } else if (dist[w] == dist[v] + weight) {\n                    predecessors[w].push_back(v);\n                    count[w] += count[v];\n                }\n            }\n        }\n        \n        while (!stk.empty()) {\n            int w = stk.top();\n            stk.pop();\n            for (int v : predecessors[w]) {\n                double partial = (double)count[v] / count[w] * (1.0 + dependency[w]);\n                dependency[v] += partial;\n            }\n            if (w != s) {\n                betweenness[w] += dependency[w];\n            }\n        }\n    }\n    \n    // Normalize betweenness for undirected graph\n    for (int i = 0; i < N; i++) {\n        betweenness[i] /= 2.0;\n    }\n    \n    return betweenness;\n}\n\ndouble estimate_frustration(const vector<vector<pair<int, int>>>& adj, \n                           const vector<Edge>& edges,\n                           const vector<int>& day_edges,\n                           int N, int sample_size = 50) {\n    if (day_edges.empty()) return 0.0;\n    \n    // Create graph without the edges in day_edges\n    vector<vector<pair<int, int>>> temp_adj = adj;\n    for (int e_idx : day_edges) {\n        const Edge& e = edges[e_idx];\n        // Remove edge from adjacency list\n        auto it1 = find_if(temp_adj[e.u].begin(), temp_adj[e.u].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.v; });\n        if (it1 != temp_adj[e.u].end()) temp_adj[e.u].erase(it1);\n        \n        auto it2 = find_if(temp_adj[e.v].begin(), temp_adj[e.v].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.u; });\n        if (it2 != temp_adj[e.v].end()) temp_adj[e.v].erase(it2);\n    }\n    \n    double total_increase = 0.0;\n    int samples = 0;\n    \n    // Sample vertices to estimate frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    for (int i = 0; i < sample_size; i++) {\n        int s = dist(rng);\n        vector<ll> dist_s(N, LLONG_MAX);\n        dist_s[s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist_s[node]) continue;\n            for (auto [neighbor, weight] : temp_adj[node]) {\n                ll new_dist = d + weight;\n                if (new_dist < dist_s[neighbor]) {\n                    dist_s[neighbor] = new_dist;\n                    pq.push({new_dist, neighbor});\n                }\n            }\n        }\n        \n        // For now, we'll use a simplified frustration calculation\n        // In a real implementation, we would compare with original distances\n        for (int j = 0; j < N; j++) {\n            if (s == j) continue;\n            if (dist_s[j] == LLONG_MAX) {\n                total_increase += 1000000000; // Disconnected penalty\n            } else {\n                total_increase += max(0LL, dist_s[j] - 1000); // Placeholder\n            }\n            samples++;\n        }\n    }\n    \n    return total_increase / max(1, samples);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].index = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Precompute original distances (simplified for performance)\n    vector<vector<ll>> original_dist(N, vector<ll>(N, 1000)); // Placeholder\n\n    // Compute vertex betweenness centrality\n    vector<double> vertex_betweenness = compute_betweenness(adj, N);\n\n    // Enhanced criticality calculation\n    vector<double> criticality(M, 0.0);\n    for (int idx = 0; idx < M; idx++) {\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        int w = e.w;\n        \n        // Distance increase component\n        ll alt_dist = compute_alt(u, v, e, adj);\n        if (alt_dist == LLONG_MAX) {\n            alt_dist = 1000000000;\n        }\n        ll increase = alt_dist - w;\n        if (increase < 0) increase = 0;\n        \n        // Betweenness component\n        double betweenness_component = vertex_betweenness[u] + vertex_betweenness[v];\n        \n        // Connectivity penalty\n        int degree_u = adj[u].size();\n        int degree_v = adj[v].size();\n        double connectivity_penalty = 1.0 / min(degree_u, degree_v);\n        \n        // Combined criticality\n        criticality[idx] = (double)increase * (1.0 + betweenness_component) + \n                          connectivity_penalty * 1000000.0;\n    }\n\n    // Initial assignment using enhanced criticality\n    vector<int> edge_indices(M);\n    for (int i = 0; i < M; i++) {\n        edge_indices[i] = i;\n    }\n\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return criticality[a] > criticality[b];\n    });\n\n    double max_crit = *max_element(criticality.begin(), criticality.end());\n\n    vector<int> assignment(M, -1);\n    vector<double> day_criticality(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<vector<int>> vertex_day_count(N, vector<int>(D, 0));\n\n    // Phase 1: Initial assignment\n    for (int i = 0; i < M; i++) {\n        int idx = edge_indices[i];\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        double min_cost = 1e20;\n        int best_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict_count = vertex_day_count[u][d] + vertex_day_count[v][d];\n            double norm_crit = (max_crit > 0) ? (criticality[idx] / max_crit) : 0.0;\n            double cost = conflict_count + 10.0 * norm_crit;\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_day = d;\n            }\n        }\n        assignment[idx] = best_day;\n        day_criticality[best_day] += criticality[idx];\n        day_count[best_day]++;\n        vertex_day_count[u][best_day]++;\n        vertex_day_count[v][best_day]++;\n    }\n\n    // Phase 2: Local search to balance frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int num_iterations = 5000;\n    \n    for (int iter = 0; iter < num_iterations; iter++) {\n        // Select a random day\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        \n        // Get edges in this day\n        vector<int> edges_in_d1;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) {\n                edges_in_d1.push_back(i);\n            }\n        }\n        if (edges_in_d1.empty()) continue;\n        \n        // Select a random edge from this day\n        uniform_int_distribution<int> dist_edge(0, (int)edges_in_d1.size()-1);\n        int e_idx = edges_in_d1[dist_edge(rng)];\n        \n        // Find candidate days to move to\n        vector<int> candidate_days;\n        for (int d2 = 0; d2 < D; d2++) {\n            if (d2 == d1) continue;\n            if (day_count[d2] >= K) continue;\n            candidate_days.push_back(d2);\n        }\n        if (candidate_days.empty()) continue;\n        \n        // Try each candidate day\n        double best_delta = 1e20;\n        int best_d2 = -1;\n        \n        for (int d2 : candidate_days) {\n            // Estimate frustration change\n            double delta = day_criticality[d1] + day_criticality[d2];\n            double new_d1 = day_criticality[d1] - criticality[e_idx];\n            double new_d2 = day_criticality[d2] + criticality[e_idx];\n            delta -= (new_d1 + new_d2);\n            \n            if (delta < best_delta) {\n                best_delta = delta;\n                best_d2 = d2;\n            }\n        }\n        \n        if (best_delta < 0) {\n            // Make the move\n            assignment[e_idx] = best_d2;\n            day_criticality[d1] -= criticality[e_idx];\n            day_criticality[best_d2] += criticality[e_idx];\n            day_count[d1]--;\n            day_count[best_d2]++;\n            vertex_day_count[edges[e_idx].u][d1]--;\n            vertex_day_count[edges[e_idx].v][d1]--;\n            vertex_day_count[edges[e_idx].u][best_d2]++;\n            vertex_day_count[edges[e_idx].v][best_d2]++;\n        }\n    }\n\n    // Phase 3: Simulated annealing for further optimization\n    double temperature = 1000.0;\n    double cooling_rate = 0.99;\n    int sa_iterations = 2000;\n    \n    double current_cost = 0.0;\n    for (int d = 0; d < D; d++) {\n        current_cost += day_criticality[d] * day_criticality[d];\n    }\n    \n    for (int iter = 0; iter < sa_iterations; iter++) {\n        temperature *= cooling_rate;\n        \n        // Select two random days\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        int d2 = dist_day(rng);\n        if (d1 == d2) continue;\n        \n        // Select random edges from each day\n        vector<int> edges_d1, edges_d2;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) edges_d1.push_back(i);\n            if (assignment[i] == d2) edges_d2.push_back(i);\n        }\n        \n        if (edges_d1.empty() || edges_d2.empty()) continue;\n        \n        uniform_int_distribution<int> dist_e1(0, (int)edges_d1.size()-1);\n        uniform_int_distribution<int> dist_e2(0, (int)edges_d2.size()-1);\n        int e1 = edges_d1[dist_e1(rng)];\n        int e2 = edges_d2[dist_e2(rng)];\n        \n        // Compute cost change for swapping\n        double old_cost = day_criticality[d1] * day_criticality[d1] + \n                         day_criticality[d2] * day_criticality[d2];\n        \n        double new_d1 = day_criticality[d1] - criticality[e1] + criticality[e2];\n        double new_d2 = day_criticality[d2] - criticality[e2] + criticality[e1];\n        double new_cost = new_d1 * new_d1 + new_d2 * new_d2;\n        \n        double delta = new_cost - old_cost;\n        \n        // Accept with probability based on temperature\n        if (delta < 0 || exp(-delta / temperature) > (double)rng() / rng.max()) {\n            // Make the swap\n            assignment[e1] = d2;\n            assignment[e2] = d1;\n            day_criticality[d1] = new_d1;\n            day_criticality[d2] = new_d2;\n            \n            // Update vertex counts\n            vertex_day_count[edges[e1].u][d1]--;\n            vertex_day_count[edges[e1].v][d1]--;\n            vertex_day_count[edges[e1].u][d2]++;\n            vertex_day_count[edges[e1].v][d2]++;\n            \n            vertex_day_count[edges[e2].u][d2]--;\n            vertex_day_count[edges[e2].v][d2]--;\n            vertex_day_count[edges[e2].u][d1]++;\n            vertex_day_count[edges[e2].v][d1]++;\n            \n            current_cost += delta;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] + 1;\n        if (i < M - 1) {\n            cout << \" \";\n        } else {\n            cout << endl;\n        }\n    }\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n#include <map>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[6] = {1, 0, 0, -1, 0, 0};\nconst int dy[6] = {0, 1, 0, 0, -1, 0};\nconst int dz[6] = {0, 0, 1, 0, 0, -1};\n\nusing Point = tuple<int, int, int>;\n\nvector<set<Point>> get_connected_components_from_set(const set<Point>& points) {\n    set<Point> visited;\n    vector<set<Point>> components;\n    for (const auto& p : points) {\n        if (visited.find(p) == visited.end()) {\n            set<Point> comp;\n            queue<Point> q;\n            q.push(p);\n            visited.insert(p);\n            while (!q.empty()) {\n                auto [x, y, z] = q.front(); q.pop();\n                comp.insert({x, y, z});\n                for (int dir = 0; dir < 6; dir++) {\n                    int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                    Point np = {nx, ny, nz};\n                    if (points.find(np) != points.end() && visited.find(np) == visited.end()) {\n                        visited.insert(np);\n                        q.push(np);\n                    }\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\nvector<set<Point>> get_connected_components_from_grid(const vector<vector<vector<bool>>>& grid, int D) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<set<Point>> components;\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (grid[z][x][y] && !visited[z][x][y]) {\n                    set<Point> comp;\n                    queue<Point> q;\n                    q.push({x, y, z});\n                    visited[z][x][y] = true;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.insert({cx, cy, cz});\n                        for (int dir = 0; dir < 6; dir++) {\n                            int nx = cx + dx[dir], ny = cy + dy[dir], nz = cz + dz[dir];\n                            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) \n                                continue;\n                            if (grid[nz][nx][ny] && !visited[nz][nx][ny]) {\n                                visited[nz][nx][ny] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n    return components;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> cand1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> cand2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> Common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (f1[z][x] == '1' && r1[z][y] == '1') {\n                    cand1[z][x][y] = true;\n                }\n                if (f2[z][x] == '1' && r2[z][y] == '1') {\n                    cand2[z][x][y] = true;\n                }\n                if (cand1[z][x][y] && cand2[z][x][y]) {\n                    Common[z][x][y] = true;\n                }\n            }\n        }\n    }\n\n    auto process_object = [&](const vector<string>& f, const vector<string>& r, \n                              const vector<vector<vector<bool>>>& cand, \n                              const vector<vector<vector<bool>>>& common) {\n        set<Point> additional_set;\n        vector<vector<bool>> covered_front(D, vector<bool>(D, false));\n        vector<vector<bool>> covered_right(D, vector<bool>(D, false));\n\n        // Mark requirements covered by common cells\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (common[z][x][y]) {\n                        covered_front[z][x] = true;\n                        covered_right[z][y] = true;\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered front requirements\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (f[z][x] == '1' && !covered_front[z][x]) {\n                    bool found = false;\n                    for (int y = 0; y < D; y++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int y = 0; y < D; y++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered right requirements\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (r[z][y] == '1' && !covered_right[z][y]) {\n                    bool found = false;\n                    for (int x = 0; x < D; x++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int x = 0; x < D; x++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return additional_set;\n    };\n\n    set<Point> A1_set = process_object(f1, r1, cand1, Common);\n    set<Point> B1_set = process_object(f2, r2, cand2, Common);\n\n    auto common_components = get_connected_components_from_grid(Common, D);\n    auto a1_components = get_connected_components_from_set(A1_set);\n    auto b1_components = get_connected_components_from_set(B1_set);\n\n    int n = common_components.size() + a1_components.size() + b1_components.size();\n    vector<int> arr1(D*D*D, 0);\n    vector<int> arr2(D*D*D, 0);\n\n    int block_id = 1;\n    for (const auto& comp : common_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : a1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : b1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    cout << n << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr1[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr2[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <queue>\n#include <unordered_set>\n#include <chrono>\n#include <iomanip>\n#include <limits>\n\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    ll x, y;\n    \n    Point() : x(0), y(0) {}\n    Point(ll x, ll y) : x(x), y(y) {}\n    \n    ll dist2(const Point& other) const {\n        ll dx = x - other.x;\n        ll dy = y - other.y;\n        return dx * dx + dy * dy;\n    }\n    \n    double dist(const Point& other) const {\n        return sqrt(dist2(other));\n    }\n};\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int idx;\n    \n    Edge(int u, int v, ll w, int idx) : u(u), v(v), w(w), idx(idx) {}\n    \n    bool operator<(const Edge& other) const {\n        return w < other.w;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    ll cost;\n    int covered;\n    \n    Solution(int N, int M) : P(N, 0), B(M, 0), cost(0), covered(0) {}\n};\n\nclass TVNetworkOptimizer {\nprivate:\n    int N, M, K;\n    vector<Point> stations;\n    vector<Point> residents;\n    vector<Edge> edges;\n    vector<vector<pair<int, ll>>> adj; // adjacency list\n    \n    // Random number generation\n    mt19937 rng;\n    \n    // Best solution found\n    Solution best_solution;\n    \n    // Distance matrices\n    vector<vector<double>> station_to_resident_dist;\n    vector<vector<double>> station_to_station_dist;\n    \npublic:\n    TVNetworkOptimizer() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void read_input() {\n        cin >> N >> M >> K;\n        \n        stations.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> stations[i].x >> stations[i].y;\n        }\n        \n        edges.reserve(M);\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v;\n            ll w;\n            cin >> u >> v >> w;\n            u--; v--;\n            edges.emplace_back(u, v, w, i);\n            adj[u].emplace_back(v, w);\n            adj[v].emplace_back(u, w);\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].x >> residents[i].y;\n        }\n        \n        // Precompute distances\n        compute_distances();\n    }\n    \n    void compute_distances() {\n        station_to_resident_dist.resize(N, vector<double>(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                station_to_resident_dist[i][j] = stations[i].dist(residents[j]);\n            }\n        }\n        \n        station_to_station_dist.resize(N, vector<double>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                station_to_station_dist[i][j] = stations[i].dist(stations[j]);\n            }\n        }\n    }\n    \n    // Build initial MST solution\n    Solution build_mst_solution() {\n        Solution sol(N, M);\n        \n        // Prim's algorithm for MST\n        vector<bool> in_mst(N, false);\n        vector<ll> min_edge(N, numeric_limits<ll>::max());\n        vector<int> parent(N, -1);\n        \n        min_edge[0] = 0;\n        \n        for (int i = 0; i < N; i++) {\n            int u = -1;\n            for (int v = 0; v < N; v++) {\n                if (!in_mst[v] && (u == -1 || min_edge[v] < min_edge[u])) {\n                    u = v;\n                }\n            }\n            \n            if (min_edge[u] == numeric_limits<ll>::max()) break;\n            \n            in_mst[u] = true;\n            \n            if (parent[u] != -1) {\n                // Find the edge between u and parent[u]\n                for (const auto& edge : edges) {\n                    if ((edge.u == u && edge.v == parent[u]) || \n                        (edge.u == parent[u] && edge.v == u)) {\n                        sol.B[edge.idx] = 1;\n                        sol.cost += edge.w;\n                        break;\n                    }\n                }\n            }\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!in_mst[v] && w < min_edge[v]) {\n                    min_edge[v] = w;\n                    parent[v] = u;\n                }\n            }\n        }\n        \n        // Assign powers to cover residents\n        assign_powers(sol);\n        \n        return sol;\n    }\n    \n    // Assign powers to vertices to cover residents\n    void assign_powers(Solution& sol) {\n        vector<bool> covered(K, false);\n        sol.covered = 0;\n        \n        // First, find which vertices are reachable from vertex 1\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find the closest reachable station\n        vector<vector<int>> assignments(N);\n        for (int k = 0; k < K; k++) {\n            double min_dist = numeric_limits<double>::max();\n            int best_station = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (reachable[i] && station_to_resident_dist[i][k] < min_dist) {\n                    min_dist = station_to_resident_dist[i][k];\n                    best_station = i;\n                }\n            }\n            \n            if (best_station != -1) {\n                assignments[best_station].push_back(k);\n            }\n        }\n        \n        // Calculate power for each station\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            if (!assignments[i].empty()) {\n                double max_dist = 0;\n                for (int k : assignments[i]) {\n                    max_dist = max(max_dist, station_to_resident_dist[i][k]);\n                }\n                sol.P[i] = min(5000, static_cast<int>(ceil(max_dist)));\n                power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n                \n                for (int k : assignments[i]) {\n                    if (!covered[k]) {\n                        covered[k] = true;\n                        sol.covered++;\n                    }\n                }\n            } else {\n                sol.P[i] = 0;\n            }\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    // Find vertices reachable from vertex 1\n    vector<bool> find_reachable(const vector<int>& B) {\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!reachable[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                reachable[v] = true;\n                                q.push(v);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return reachable;\n    }\n    \n    // Calculate total edge cost\n    ll get_edge_cost(const vector<int>& B) {\n        ll cost = 0;\n        for (int i = 0; i < M; i++) {\n            if (B[i]) {\n                cost += edges[i].w;\n            }\n        }\n        return cost;\n    }\n    \n    // Try to improve solution by adding/removing edges\n    Solution local_search(const Solution& initial_sol) {\n        Solution best_sol = initial_sol;\n        Solution current_sol = initial_sol;\n        \n        uniform_int_distribution<int> edge_dist(0, M-1);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        double temperature = 1000.0;\n        double cooling_rate = 0.995;\n        int iterations = 10000;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Try random edge operation\n            int edge_idx = edge_dist(rng);\n            Solution new_sol = current_sol;\n            \n            if (new_sol.B[edge_idx] == 1) {\n                // Try removing edge\n                new_sol.B[edge_idx] = 0;\n                if (is_connected(new_sol.B)) {\n                    assign_powers(new_sol);\n                } else {\n                    new_sol.B[edge_idx] = 1; // Revert if disconnected\n                }\n            } else {\n                // Try adding edge\n                new_sol.B[edge_idx] = 1;\n                assign_powers(new_sol);\n            }\n            \n            // Accept or reject based on simulated annealing\n            if (accept_solution(current_sol, new_sol, temperature)) {\n                current_sol = new_sol;\n                if (current_sol.covered == K && \n                    (best_sol.covered < K || current_sol.cost < best_sol.cost)) {\n                    best_sol = current_sol;\n                }\n            }\n            \n            temperature *= cooling_rate;\n        }\n        \n        return best_sol;\n    }\n    \n    // Check if the graph with selected edges is connected\n    bool is_connected(const vector<int>& B) {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!visited[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                visited[v] = true;\n                                q.push(v);\n                                count++;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return count == N;\n    }\n    \n    // Simulated annealing acceptance criterion\n    bool accept_solution(const Solution& current, const Solution& new_sol, double temperature) {\n        if (new_sol.covered > current.covered) return true;\n        if (new_sol.covered < current.covered) return false;\n        \n        if (new_sol.cost < current.cost) return true;\n        \n        if (temperature < 1e-6) return false;\n        \n        double delta = new_sol.cost - current.cost;\n        double prob = exp(-delta / temperature);\n        \n        uniform_real_distribution<double> dist(0.0, 1.0);\n        return dist(rng) < prob;\n    }\n    \n    // Optimize power assignments given fixed network\n    void optimize_powers(Solution& sol) {\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find all stations that can cover it\n        vector<vector<int>> covering_stations(K);\n        for (int k = 0; k < K; k++) {\n            for (int i = 0; i < N; i++) {\n                if (reachable[i]) {\n                    double dist = station_to_resident_dist[i][k];\n                    if (dist <= 5000) {\n                        covering_stations[k].push_back(i);\n                    }\n                }\n            }\n        }\n        \n        // Greedily assign residents to minimize total power cost\n        vector<bool> covered(K, false);\n        vector<int> assignments(K, -1);\n        sol.covered = 0;\n        \n        // Sort residents by number of covering stations (ascending)\n        vector<int> resident_order(K);\n        for (int k = 0; k < K; k++) resident_order[k] = k;\n        sort(resident_order.begin(), resident_order.end(), \n             [&](int a, int b) { \n                 return covering_stations[a].size() < covering_stations[b].size(); \n             });\n        \n        for (int k : resident_order) {\n            if (covered[k]) continue;\n            \n            // Find best station for this resident\n            int best_station = -1;\n            double best_cost = numeric_limits<double>::max();\n            \n            for (int station : covering_stations[k]) {\n                double dist = station_to_resident_dist[station][k];\n                double additional_cost = dist * dist;\n                \n                // Check how many additional residents this station would cover\n                int additional_cover = 0;\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && station_to_resident_dist[station][other] <= dist) {\n                        additional_cover++;\n                    }\n                }\n                \n                double cost_per_resident = additional_cost / max(1, additional_cover);\n                \n                if (cost_per_resident < best_cost) {\n                    best_cost = cost_per_resident;\n                    best_station = station;\n                }\n            }\n            \n            if (best_station != -1) {\n                double required_power = station_to_resident_dist[best_station][k];\n                \n                // Assign this resident and others that can be covered\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && \n                        station_to_resident_dist[best_station][other] <= required_power) {\n                        covered[other] = true;\n                        assignments[other] = best_station;\n                        sol.covered++;\n                    }\n                }\n            }\n        }\n        \n        // Set powers based on assignments\n        vector<double> max_power(N, 0.0);\n        for (int k = 0; k < K; k++) {\n            if (assignments[k] != -1) {\n                max_power[assignments[k]] = max(max_power[assignments[k]], \n                                               station_to_resident_dist[assignments[k]][k]);\n            }\n        }\n        \n        // Calculate power cost\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            sol.P[i] = min(5000, static_cast<int>(ceil(max_power[i])));\n            power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    void solve() {\n        // Build initial MST solution\n        Solution sol = build_mst_solution();\n        \n        // Optimize power assignments\n        optimize_powers(sol);\n        best_solution = sol;\n        \n        // Run local search with simulated annealing\n        for (int trial = 0; trial < 5; trial++) {\n            Solution improved = local_search(best_solution);\n            optimize_powers(improved);\n            \n            if (improved.covered == K && \n                (best_solution.covered < K || improved.cost < best_solution.cost)) {\n                best_solution = improved;\n            }\n        }\n        \n        // Final power optimization\n        optimize_powers(best_solution);\n        \n        // Output solution\n        output_solution(best_solution);\n    }\n    \n    void output_solution(const Solution& sol) {\n        for (int i = 0; i < N; i++) {\n            cout << sol.P[i];\n            if (i < N - 1) cout << \" \";\n        }\n        cout << endl;\n        \n        for (int i = 0; i < M; i++) {\n            cout << sol.B[i];\n            if (i < M - 1) cout << \" \";\n        }\n        cout << endl;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TVNetworkOptimizer optimizer;\n    optimizer.read_input();\n    optimizer.solve();\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n\nusing namespace std;\n\nvector<vector<int>> pyramid;\nvector<tuple<int, int, int, int>> operations;\n\n// Check if two positions are adjacent\nbool is_adjacent(int x1, int y1, int x2, int y2) {\n    return (x1 == x2 - 1 && y1 == y2 - 1) ||\n           (x1 == x2 - 1 && y1 == y2) ||\n           (x1 == x2 && y1 == y2 - 1) ||\n           (x1 == x2 && y1 == y2 + 1) ||\n           (x1 == x2 + 1 && y1 == y2) ||\n           (x1 == x2 + 1 && y1 == y2 + 1);\n}\n\n// Count the number of violations\nint count_violations() {\n    int violations = 0;\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) violations++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) violations++;\n        }\n    }\n    return violations;\n}\n\n// Swap two balls and record the operation\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    if (!is_adjacent(x1, y1, x2, y2)) {\n        cerr << \"Error: Attempting to swap non-adjacent balls\" << endl;\n        return;\n    }\n    operations.emplace_back(x1, y1, x2, y2);\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n}\n\n// Top-down pass: ensure each ball is smaller than those below it\nvoid top_down_pass() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            int left_child = pyramid[x+1][y];\n            int right_child = pyramid[x+1][y+1];\n            \n            if (current > left_child || current > right_child) {\n                // Find the smaller child\n                if (left_child < right_child) {\n                    // Swap with left child\n                    swap_balls(x, y, x+1, y);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                } else {\n                    // Swap with right child\n                    swap_balls(x, y, x+1, y+1);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y+1;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Bubble up larger numbers towards the bottom\nvoid bubble_up() {\n    for (int x = 28; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check if current is larger than its parent\n            if (x > 0) {\n                int parent_y = -1;\n                if (y <= x-1 && pyramid[x-1][y] < current) {\n                    parent_y = y;\n                } else if (y > 0 && pyramid[x-1][y-1] < current) {\n                    parent_y = y-1;\n                }\n                \n                if (parent_y != -1) {\n                    // Swap with parent\n                    swap_balls(x, y, x-1, parent_y);\n                }\n            }\n        }\n    }\n}\n\n// Local refinement: fix specific violations\nvoid local_refinement() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check violation with left child\n            if (current > pyramid[x+1][y]) {\n                // Try to find a better position for current\n                bool found = false;\n                \n                // Check adjacent positions\n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    // Just swap with the child\n                    swap_balls(x, y, x+1, y);\n                }\n            }\n            \n            // Check violation with right child\n            if (current > pyramid[x+1][y+1]) {\n                // Similar logic as above\n                bool found = false;\n                \n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    swap_balls(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    pyramid.resize(30);\n    for (int x = 0; x < 30; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Apply our algorithm\n    int max_operations = 10000;\n    \n    // Initial top-down pass\n    top_down_pass();\n    \n    // Iterative improvement\n    while (operations.size() < max_operations) {\n        int violations_before = count_violations();\n        if (violations_before == 0) break;\n        \n        // Try different strategies\n        if (operations.size() % 3 == 0) {\n            bubble_up();\n        } else if (operations.size() % 3 == 1) {\n            top_down_pass();\n        } else {\n            local_refinement();\n        }\n        \n        // Check if we're making progress\n        int violations_after = count_violations();\n        if (violations_after >= violations_before) {\n            // Not making progress, try a different approach\n            break;\n        }\n    }\n    \n    // Final pass to fix remaining violations\n    if (operations.size() < max_operations) {\n        local_refinement();\n    }\n    \n    // Output the result\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <iomanip>\n\nusing namespace std;\n\nconst int D = 9;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nint grid[D][D];\nint base_distance[D][D];\n\nvoid bfs_base() {\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_distance[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_distance[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (base_distance[nx][ny] == -1 && grid[nx][ny] != -1) {\n                    base_distance[nx][ny] = base_distance[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nstruct BFSResult {\n    bool visited[D][D];\n    int dist[D][D];\n};\n\nBFSResult bfs_current() {\n    BFSResult res;\n    memset(res.visited, false, sizeof(res.visited));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            res.dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    res.visited[0][4] = true;\n    res.dist[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (!res.visited[nx][ny]) {\n                    if (grid[nx][ny] == 0 || grid[nx][ny] == -2) {\n                        res.visited[nx][ny] = true;\n                        res.dist[nx][ny] = res.dist[x][y] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n    }\n    return res;\n}\n\nbool check_reachability_after_placing(int i, int j, int t_d) {\n    grid[i][j] = t_d;\n    BFSResult res = bfs_current();\n    vector<pair<int, int>> container_cells;\n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            if (grid[x][y] >= 0) {\n                container_cells.push_back({x, y});\n            }\n        }\n    }\n    bool all_reachable = true;\n    for (auto [x, y] : container_cells) {\n        bool reachable = false;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (res.visited[nx][ny]) {\n                    reachable = true;\n                    break;\n                }\n            }\n        }\n        if (!reachable) {\n            all_reachable = false;\n            break;\n        }\n    }\n    grid[i][j] = 0;\n    return all_reachable;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    cin >> N;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            grid[i][j] = 0;\n        }\n    }\n    grid[0][4] = -2;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    bfs_base();\n\n    int min_base = INT_MAX, max_base = INT_MIN;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == 4) continue;\n            if (grid[i][j] == -1) continue;\n            if (base_distance[i][j] == -1) continue;\n            if (base_distance[i][j] < min_base) min_base = base_distance[i][j];\n            if (base_distance[i][j] > max_base) max_base = base_distance[i][j];\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    if (M > 0) {\n        for (int d = 0; d < M; d++) {\n            int t_d;\n            cin >> t_d;\n\n            double desired;\n            if (M == 1) {\n                desired = min_base;\n            } else {\n                desired = (double)(t_d) / (M - 1) * (max_base - min_base) + min_base;\n            }\n\n            BFSResult res1 = bfs_current();\n            vector<pair<int, int>> candidate_cells;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] == 0 && res1.visited[i][j]) {\n                        candidate_cells.push_back({i, j});\n                    }\n                }\n            }\n\n            vector<pair<int, int>> valid_candidates;\n            vector<double> costs;\n            vector<int> current_dists;\n\n            for (auto [i, j] : candidate_cells) {\n                if (check_reachability_after_placing(i, j, t_d)) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            if (valid_candidates.empty()) {\n                for (auto [i, j] : candidate_cells) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            int best_index = 0;\n            for (int idx = 1; idx < valid_candidates.size(); idx++) {\n                if (costs[idx] < costs[best_index]) {\n                    best_index = idx;\n                } else if (costs[idx] == costs[best_index]) {\n                    if (current_dists[idx] < current_dists[best_index]) {\n                        best_index = idx;\n                    } else if (current_dists[idx] == current_dists[best_index]) {\n                        if (base_distance[valid_candidates[idx].first][valid_candidates[idx].second] < \n                            base_distance[valid_candidates[best_index].first][valid_candidates[best_index].second]) {\n                            best_index = idx;\n                        }\n                    }\n                }\n            }\n\n            auto [i, j] = valid_candidates[best_index];\n            grid[i][j] = t_d;\n            cout << i << \" \" << j << endl;\n            cout.flush();\n        }\n    }\n\n    if (M > 0) {\n        vector<pair<int, int>> transport_order;\n        for (int step = 0; step < M; step++) {\n            BFSResult res = bfs_current();\n            vector<pair<int, int>> reachable_containers;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] >= 0) {\n                        for (int d = 0; d < 4; d++) {\n                            int ni = i + dx[d], nj = j + dy[d];\n                            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                                if (res.visited[ni][nj]) {\n                                    reachable_containers.push_back({i, j});\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int min_number = INT_MAX;\n            pair<int, int> min_cell = {-1, -1};\n            for (auto [i, j] : reachable_containers) {\n                if (grid[i][j] < min_number) {\n                    min_number = grid[i][j];\n                    min_cell = {i, j};\n                }\n            }\n\n            grid[min_cell.first][min_cell.second] = 0;\n            transport_order.push_back(min_cell);\n        }\n\n        for (auto [i, j] : transport_order) {\n            cout << i << \" \" << j << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nconst int dx[4] = {1, 0, -1, 0};\nconst int dy[4] = {0, 1, 0, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<vector<bool>> adj(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 = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    adj[c1][0] = true;\n                    adj[0][c1] = true;\n                } else {\n                    int c2 = grid[ni][nj];\n                    if (c1 != c2) {\n                        adj[c1][c2] = true;\n                        adj[c2][c1] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> new_grid(n, vector<int>(n, -1));\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<tuple<int, int, int>> q;\n\n    vector<int> A;\n    for (int c = 1; c <= m; c++) {\n        if (adj[c][0]) {\n            A.push_back(c);\n        }\n    }\n\n    vector<vector<int>> H(A.size());\n    for (int i = 0; i < A.size(); i++) {\n        for (int j = i+1; j < A.size(); j++) {\n            if (adj[A[i]][A[j]]) {\n                H[i].push_back(j);\n                H[j].push_back(i);\n            }\n        }\n    }\n\n    vector<int> order;\n    vector<bool> done(H.size(), false);\n    if (!H.empty()) {\n        queue<int> qq;\n        qq.push(0);\n        done[0] = true;\n        while (!qq.empty()) {\n            int u = qq.front(); qq.pop();\n            order.push_back(u);\n            for (int v : H[u]) {\n                if (!done[v]) {\n                    done[v] = true;\n                    qq.push(v);\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> boundary;\n    for (int j = 0; j < n; j++) {\n        boundary.emplace_back(0, j);\n    }\n    for (int i = 1; i < n; i++) {\n        boundary.emplace_back(i, n-1);\n    }\n    for (int j = n-2; j >= 0; j--) {\n        boundary.emplace_back(n-1, j);\n    }\n    for (int i = n-2; i >= 1; i--) {\n        boundary.emplace_back(i, 0);\n    }\n\n    vector<int> boundary_assignment;\n    if (!order.empty()) {\n        boundary_assignment.push_back(A[order[0]]);\n        for (int i = 1; i < order.size(); i++) {\n            int u = order[i-1];\n            int v = order[i];\n            bool adj_in_H = false;\n            for (int w : H[u]) {\n                if (w == v) {\n                    adj_in_H = true;\n                    break;\n                }\n            }\n            if (!adj_in_H) {\n                boundary_assignment.push_back(0);\n            }\n            boundary_assignment.push_back(A[v]);\n        }\n        int u = order.back();\n        int v = order[0];\n        bool adj_in_H = false;\n        for (int w : H[u]) {\n            if (w == v) {\n                adj_in_H = true;\n                break;\n            }\n        }\n        if (!adj_in_H) {\n            boundary_assignment.push_back(0);\n        }\n    }\n\n    for (int idx = 0; idx < boundary.size(); idx++) {\n        int color = (idx < boundary_assignment.size()) ? boundary_assignment[idx] : 0;\n        int i = boundary[idx].first;\n        int j = boundary[idx].second;\n        new_grid[i][j] = color;\n        visited[i][j] = true;\n        if (color != 0) {\n            q.push({i, j, color});\n        }\n    }\n\n    while (!q.empty()) {\n        auto [i, j, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n            if (visited[ni][nj]) continue;\n            bool can_assign = true;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + dx[dd];\n                int nnj = nj + dy[dd];\n                if (nni < 0 || nni >= n || nnj < 0 || nnj >= n) continue;\n                if (new_grid[nni][nnj] == -1) continue;\n                int d_color = new_grid[nni][nnj];\n                if (d_color == 0) continue;\n                if (d_color == c) continue;\n                if (!adj[c][d_color]) {\n                    can_assign = false;\n                    break;\n                }\n            }\n            if (can_assign) {\n                new_grid[ni][nj] = c;\n                visited[ni][nj] = true;\n                q.push({ni, nj, c});\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (new_grid[i][j] == -1) {\n                new_grid[i][j] = 0;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << new_grid[i][j] << (j < n-1 ? ' ' : '\\n');\n        }\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\n\n// Random number generator with proper seeding\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to output a query and get the result\nchar query(int nL, int nR, const vector<int>& L, const vector<int>& R) {\n    cout << nL << \" \" << nR;\n    for (int i : L) cout << \" \" << i;\n    for (int i : R) cout << \" \" << i;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\n// Function to partition items into D sets based on estimated weights\nvector<int> partition_items(int N, int D, const vector<double>& estimated_weights) {\n    // Create pairs of (item_index, estimated_weight)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.emplace_back(estimated_weights[i], i);\n    }\n    \n    // Sort items by estimated weight in descending order\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize D sets\n    vector<double> set_weights(D, 0.0);\n    vector<int> assignment(N, -1);\n    \n    // Greedy assignment: assign each item to the set with the smallest current total weight\n    for (const auto& [weight, idx] : items) {\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        assignment[idx] = min_set;\n        set_weights[min_set] += weight;\n    }\n    \n    // Improvement phase 1: Try to balance by swapping items between sets\n    for (int iter = 0; iter < 100; iter++) {\n        // Calculate the current variance\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        double variance = 0.0;\n        for (double w : set_weights) {\n            variance += (w - mean) * (w - mean);\n        }\n        variance /= D;\n        \n        // Try to find a swap that reduces the variance\n        bool improved = false;\n        \n        // Try swaps between sets\n        for (int trial = 0; trial < 50; trial++) {\n            int i = rng() % N;\n            int j = rng() % N;\n            while (i == j) {\n                j = rng() % N;\n            }\n            \n            if (assignment[i] != assignment[j]) {\n                // Calculate the new variance if we swap items i and j\n                int set_i = assignment[i];\n                int set_j = assignment[j];\n                \n                double new_weight_i = set_weights[set_i] - estimated_weights[i] + estimated_weights[j];\n                double new_weight_j = set_weights[set_j] - estimated_weights[j] + estimated_weights[i];\n                \n                double new_variance = variance;\n                new_variance -= (set_weights[set_i] - mean) * (set_weights[set_i] - mean) / D;\n                new_variance -= (set_weights[set_j] - mean) * (set_weights[set_j] - mean) / D;\n                new_variance += (new_weight_i - mean) * (new_weight_i - mean) / D;\n                new_variance += (new_weight_j - mean) * (new_weight_j - mean) / D;\n                \n                if (new_variance < variance) {\n                    // Swap the items\n                    assignment[i] = set_j;\n                    assignment[j] = set_i;\n                    set_weights[set_i] = new_weight_i;\n                    set_weights[set_j] = new_weight_j;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Improvement phase 2: Try to move items to balance sets\n    for (int iter = 0; iter < 50; iter++) {\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        \n        // Find the set with the highest weight and the set with the lowest weight\n        int max_set = max_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        \n        if (set_weights[max_set] - set_weights[min_set] < 1e-6) break;\n        \n        // Find an item in the max_set that can be moved to min_set to reduce difference\n        bool moved = false;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == max_set) {\n                double new_max = set_weights[max_set] - estimated_weights[i];\n                double new_min = set_weights[min_set] + estimated_weights[i];\n                \n                double current_diff = set_weights[max_set] - set_weights[min_set];\n                double new_diff = abs(new_max - new_min);\n                \n                if (new_diff < current_diff) {\n                    // Move the item\n                    assignment[i] = min_set;\n                    set_weights[max_set] = new_max;\n                    set_weights[min_set] = new_min;\n                    moved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!moved) break;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Initialize estimated weights\n    vector<double> estimated_weights(N, 1.0);\n    \n    // Keep track of how many times each item has been compared\n    vector<int> compare_count(N, 0);\n    \n    // Use queries to estimate relative weights\n    for (int q = 0; q < Q; q++) {\n        if (q < Q / 2) {\n            // First half: Compare individual items using tournament method\n            // Find two items with the lowest comparison counts\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            int i = -1, j = -1;\n            for (int idx : indices) {\n                if (i == -1) {\n                    i = idx;\n                } else if (j == -1) {\n                    j = idx;\n                    break;\n                }\n            }\n            \n            char result = query(1, 1, {i}, {j});\n            compare_count[i]++;\n            compare_count[j]++;\n            \n            // Update estimates based on result\n            double adjustment = 0.15;\n            if (result == '>') {\n                estimated_weights[i] *= (1.0 + adjustment);\n                estimated_weights[j] *= (1.0 - adjustment);\n            } else if (result == '<') {\n                estimated_weights[i] *= (1.0 - adjustment);\n                estimated_weights[j] *= (1.0 + adjustment);\n            }\n        } else {\n            // Second half: Compare groups of items to refine estimates\n            // Sort items by estimated weight\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return estimated_weights[a] < estimated_weights[b];\n            });\n            \n            // Create two groups of similar weight items\n            int group_size = 2 + rng() % min(4, N / 5);\n            int start = rng() % (N - 2 * group_size);\n            \n            vector<int> group1, group2;\n            for (int k = 0; k < group_size; k++) {\n                group1.push_back(indices[start + k]);\n                group2.push_back(indices[start + group_size + k]);\n            }\n            \n            char result = query(group_size, group_size, group1, group2);\n            \n            // Update estimates based on result\n            double adjustment = 0.08;\n            if (result == '>') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n            } else if (result == '<') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n            }\n            \n            for (int k : group1) compare_count[k]++;\n            for (int k : group2) compare_count[k]++;\n        }\n    }\n    \n    // Normalize estimated weights to a reasonable scale\n    double min_weight = *min_element(estimated_weights.begin(), estimated_weights.end());\n    for (int i = 0; i < N; i++) {\n        estimated_weights[i] /= min_weight;\n    }\n    \n    // Partition items into D sets\n    vector<int> assignment = partition_items(N, D, estimated_weights);\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> position(n + 1);  // position[v] = stack_index\n    \n    // Read input and initialize data structures\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            position[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int next_box = 1;\n    \n    while (next_box <= n) {\n        // Check if next_box is at the top of any stack\n        bool found_at_top = false;\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_box) {\n                // Carry out operation\n                stacks[i].pop_back();\n                operations.emplace_back(next_box, 0);\n                next_box++;\n                found_at_top = true;\n                break;\n            }\n        }\n        \n        if (found_at_top) continue;\n        \n        // Find the stack containing next_box\n        int stack_idx = -1;\n        int pos_in_stack = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                if (stacks[i][j] == next_box) {\n                    stack_idx = i;\n                    pos_in_stack = j;\n                    break;\n                }\n            }\n            if (stack_idx != -1) break;\n        }\n        \n        // The box immediately above next_box\n        int box_above = stacks[stack_idx][pos_in_stack + 1];\n        \n        // Choose destination stack\n        int best_dest = -1;\n        \n        // Prefer empty stacks\n        for (int i = 0; i < m; i++) {\n            if (i != stack_idx && stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n        }\n        \n        // If no empty stack, prefer stacks with larger bottom elements\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx && !stacks[i].empty() && stacks[i][0] > next_box) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Otherwise, choose any non-source stack\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Move boxes above next_box (including box_above) to destination\n        vector<int> moved_boxes;\n        for (int i = pos_in_stack + 1; i < stacks[stack_idx].size(); i++) {\n            moved_boxes.push_back(stacks[stack_idx][i]);\n            position[stacks[stack_idx][i]] = best_dest;\n        }\n        \n        // Update source stack\n        stacks[stack_idx].resize(pos_in_stack + 1);\n        \n        // Update destination stack\n        stacks[best_dest].insert(stacks[best_dest].end(), \n                                 moved_boxes.begin(), moved_boxes.end());\n        \n        // Record operation\n        operations.emplace_back(box_above, best_dest + 1);\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <utility>\n#include <unordered_set>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    Point operator+(const Point& other) const {\n        return Point(i + other.i, j + other.j);\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<Point> {\n        size_t operator()(const Point& p) const {\n            return static_cast<size_t>(p.i) * 1000 + p.j;\n        }\n    };\n}\n\nclass Solution {\npublic:\n    int N;\n    vector<string> h, v;\n    vector<vector<int>> d;\n    vector<vector<bool>> visited;\n    vector<Point> path;\n    string route;\n    \n    // Directions: R, D, L, U\n    const vector<Point> directions = {Point(0, 1), Point(1, 0), Point(0, -1), Point(-1, 0)};\n    const string dir_chars = \"RDLU\";\n    \n    Solution(int n, const vector<string>& h, const vector<string>& v, const vector<vector<int>>& d)\n        : N(n), h(h), v(v), d(d), visited(n, vector<bool>(n, false)) {\n        // Initialize path with starting point\n        path.emplace_back(0, 0);\n    }\n    \n    bool can_move(const Point& from, const Point& to) const {\n        if (to.i < 0 || to.i >= N || to.j < 0 || to.j >= N) return false;\n        \n        // Check horizontal wall\n        if (from.i == to.i) {\n            int j = min(from.j, to.j);\n            if (v[from.i][j] == '1') return false;\n        }\n        // Check vertical wall\n        else if (from.j == to.j) {\n            int i = min(from.i, to.i);\n            if (h[i][from.j] == '1') return false;\n        }\n        return true;\n    }\n    \n    void dfs(Point p) {\n        visited[p.i][p.j] = true;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            Point next = p + directions[dir];\n            if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                !visited[next.i][next.j] && can_move(p, next)) {\n                path.push_back(next);\n                route += dir_chars[dir];\n                dfs(next);\n                path.push_back(p);\n                route += dir_chars[(dir + 2) % 4];\n            }\n        }\n    }\n    \n    vector<Point> bfs(const Point& start, const Point& end) {\n        vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n        vector<vector<bool>> bfs_visited(N, vector<bool>(N, false));\n        queue<Point> q;\n        \n        q.push(start);\n        bfs_visited[start.i][start.j] = true;\n        \n        while (!q.empty()) {\n            Point current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Point> result;\n                Point p = end;\n                while (p != start) {\n                    result.push_back(p);\n                    p = parent[p.i][p.j];\n                }\n                result.push_back(start);\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (const Point& dir : directions) {\n                Point next = current + dir;\n                if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                    !bfs_visited[next.i][next.j] && can_move(current, next)) {\n                    bfs_visited[next.i][next.j] = true;\n                    parent[next.i][next.j] = current;\n                    q.push(next);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    string get_route_string(const vector<Point>& path) {\n        string result;\n        for (size_t i = 1; i < path.size(); i++) {\n            Point from = path[i-1];\n            Point to = path[i];\n            for (int dir = 0; dir < 4; dir++) {\n                if (from + directions[dir] == to) {\n                    result += dir_chars[dir];\n                    break;\n                }\n            }\n        }\n        return result;\n    }\n    \n    void optimize_route() {\n        // Find cells with high dirt susceptibility\n        vector<pair<int, Point>> high_dirt_cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                high_dirt_cells.emplace_back(d[i][j], Point(i, j));\n            }\n        }\n        sort(high_dirt_cells.rbegin(), high_dirt_cells.rend());\n        \n        // Try to create shortcuts to high dirt cells\n        for (int iter = 0; iter < 100; iter++) {\n            if (route.length() > 90000) break; // Don't exceed the limit\n            \n            // Select a random high dirt cell\n            int idx = rng() % min(10, (int)high_dirt_cells.size());\n            Point target = high_dirt_cells[idx].second;\n            \n            // Find random positions in the current path\n            int pos1 = rng() % (path.size() - 1);\n            int pos2 = rng() % (path.size() - 1);\n            if (pos1 > pos2) swap(pos1, pos2);\n            \n            // Try to create a shortcut from pos1 to target and back to pos2\n            vector<Point> path1 = bfs(path[pos1], target);\n            vector<Point> path2 = bfs(target, path[pos2]);\n            \n            if (!path1.empty() && !path2.empty() && \n                path1.size() + path2.size() < pos2 - pos1) {\n                // Create new path\n                vector<Point> new_path;\n                for (int i = 0; i <= pos1; i++) {\n                    new_path.push_back(path[i]);\n                }\n                for (size_t i = 1; i < path1.size(); i++) {\n                    new_path.push_back(path1[i]);\n                }\n                for (size_t i = 1; i < path2.size(); i++) {\n                    new_path.push_back(path2[i]);\n                }\n                for (size_t i = pos2 + 1; i < path.size(); i++) {\n                    new_path.push_back(path[i]);\n                }\n                \n                // Update path and route\n                path = new_path;\n                route = get_route_string(path);\n            }\n        }\n        \n        // Ensure we return to (0,0)\n        if (path.back() != Point(0, 0)) {\n            vector<Point> return_path = bfs(path.back(), Point(0, 0));\n            for (size_t i = 1; i < return_path.size(); i++) {\n                path.push_back(return_path[i]);\n            }\n            route = get_route_string(path);\n        }\n        \n        // Ensure length constraint\n        if (route.length() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    \n    string solve() {\n        // Generate initial route using DFS\n        dfs(Point(0, 0));\n        \n        // Optimize the route\n        optimize_route();\n        \n        return route;\n    }\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> d(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    Solution solution(N, h, v, d);\n    string route = solution.solve();\n    cout << route << endl;\n    \n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct TargetInfo {\n    string target;\n    int prefix_len;\n    TargetInfo(string t, int pl) : target(t), prefix_len(pl) {}\n    bool operator<(const TargetInfo& other) const {\n        return prefix_len < other.prefix_len; // Longer prefixes first\n    }\n};\n\nint main() {\n    srand(time(0));\n\n    int N, M;\n    cin >> N >> M;\n    int s_i, s_j;\n    cin >> s_i >> s_j;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<string> targets(M);\n    set<string> uncovered_targets;\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n        uncovered_targets.insert(targets[i]);\n    }\n\n    map<string, int> prefix_count;\n    map<string, map<char, int>> next_char_count;\n    priority_queue<TargetInfo> target_queue;\n\n    for (const string& t : targets) {\n        for (int len = 1; len <= 4; len++) {\n            string p = t.substr(0, len);\n            prefix_count[p]++;\n        }\n        for (int len = 0; len < 5; len++) {\n            string p = t.substr(0, len);\n            if (len < 5) {\n                char next_char = t[len];\n                next_char_count[p][next_char]++;\n            }\n        }\n        target_queue.push(TargetInfo(t, 0));\n    }\n\n    int current_i = s_i, current_j = s_j;\n    string current_last4 = string(1, grid[s_i][s_j]);\n    vector<pair<int, int>> path;\n    path.emplace_back(s_i, s_j);\n\n    int steps_since_cover = 0;\n    int total_covered = 0;\n\n    for (int step = 1; step < 5000; step++) {\n        double best_score = -1e18;\n        pair<int, int> best_move = {-1, -1};\n        string best_new_last4;\n        string best_completed_target = \"\";\n\n        // Dynamic bonus based on progress\n        double completion_bonus = 1000000.0 * (1.0 + (double)total_covered / M);\n\n        // Check if we need to explore randomly\n        if (steps_since_cover > 50) {\n            int random_i = rand() % N;\n            int random_j = rand() % N;\n            best_move = {random_i, random_j};\n            steps_since_cover = 0; // Reset counter\n        } else {\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    char c = grid[i][j];\n                    int cost_move = abs(current_i - i) + abs(current_j - j) + 1;\n\n                    string new_last4;\n                    if (current_last4.size() == 4) {\n                        new_last4 = current_last4.substr(1) + c;\n                    } else {\n                        new_last4 = current_last4 + c;\n                    }\n\n                    double score = -cost_move;\n\n                    // Type 1: Complete a target\n                    if (current_last4.size() == 4) {\n                        string candidate = current_last4 + c;\n                        if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                            score += completion_bonus;\n                        }\n                    }\n\n                    // Type 2: Extend existing prefix\n                    if (next_char_count.find(current_last4) != next_char_count.end()) {\n                        const auto& char_count = next_char_count.at(current_last4);\n                        auto it = char_count.find(c);\n                        if (it != char_count.end()) {\n                            // Higher bonus for longer prefixes\n                            score += 10000.0 * it->second * (current_last4.size() + 1);\n                        }\n                    }\n\n                    // Type 3: Create new prefix\n                    if (prefix_count.find(new_last4) != prefix_count.end()) {\n                        score += 1000.0 * prefix_count.at(new_last4);\n                    }\n\n                    // Small random component for exploration\n                    score += (rand() % 1000) * 0.1;\n\n                    if (score > best_score) {\n                        best_score = score;\n                        best_move = {i, j};\n                        best_new_last4 = new_last4;\n                        if (current_last4.size() == 4) {\n                            string candidate = current_last4 + c;\n                            if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                                best_completed_target = candidate;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Make the move\n        path.push_back(best_move);\n        current_i = best_move.first;\n        current_j = best_move.second;\n        current_last4 = best_new_last4;\n\n        // Update if we completed a target\n        if (!best_completed_target.empty()) {\n            uncovered_targets.erase(best_completed_target);\n            total_covered++;\n            steps_since_cover = 0;\n\n            // Update data structures\n            for (int len = 1; len <= 4; len++) {\n                string p = best_completed_target.substr(0, len);\n                prefix_count[p]--;\n            }\n            for (int len = 0; len < 5; len++) {\n                string p = best_completed_target.substr(0, len);\n                if (len < 5) {\n                    char next_char = best_completed_target[len];\n                    next_char_count[p][next_char]--;\n                }\n            }\n        } else {\n            steps_since_cover++;\n        }\n\n        if (uncovered_targets.empty()) {\n            break;\n        }\n    }\n\n    for (const auto& p : path) {\n        cout << p.first << \" \" << p.second << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        return tie(i, j) < tie(other.i, other.j);\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct OilField {\n    vector<Point> cells;\n    int size;\n};\n\nstruct GridInfo {\n    int N, M;\n    double epsilon;\n    vector<OilField> oil_fields;\n    vector<vector<int>> drilled_values;\n    vector<vector<double>> estimated_values;\n    set<Point> oil_squares;\n    \n    GridInfo(int N, int M, double epsilon) : N(N), M(M), epsilon(epsilon) {\n        drilled_values.assign(N, vector<int>(N, -1));\n        estimated_values.assign(N, vector<double>(N, 0.0));\n    }\n};\n\nvoid read_input(GridInfo& grid) {\n    cin >> grid.N >> grid.M >> grid.epsilon;\n    grid.oil_fields.resize(grid.M);\n    \n    for (int k = 0; k < grid.M; ++k) {\n        int d;\n        cin >> d;\n        grid.oil_fields[k].size = d;\n        grid.oil_fields[k].cells.resize(d);\n        for (int i = 0; i < d; ++i) {\n            cin >> grid.oil_fields[k].cells[i].i >> grid.oil_fields[k].cells[i].j;\n        }\n    }\n}\n\nint drill(GridInfo& grid, int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    grid.drilled_values[i][j] = value;\n    grid.estimated_values[i][j] = value;\n    if (value > 0) {\n        grid.oil_squares.insert(Point(i, j));\n    }\n    return value;\n}\n\nint divine(GridInfo& grid, const vector<Point>& squares) {\n    cout << \"q \" << squares.size();\n    for (const auto& p : squares) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    return value;\n}\n\nbool submit_answer(GridInfo& grid, const set<Point>& answer) {\n    cout << \"a \" << answer.size();\n    for (const auto& p : answer) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nvector<Point> get_region_points(int i1, int j1, int i2, int j2, int N) {\n    vector<Point> points;\n    for (int i = i1; i <= i2; ++i) {\n        for (int j = j1; j <= j2; ++j) {\n            if (i >= 0 && i < N && j >= 0 && j < N) {\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    return points;\n}\n\nvoid explore_grid(GridInfo& grid, int max_operations) {\n    int operations_used = 0;\n    \n    if (operations_used < max_operations) {\n        auto all_points = get_region_points(0, 0, grid.N-1, grid.N-1, grid.N);\n        if (all_points.size() >= 2) {\n            int total_oil_estimate = divine(grid, all_points);\n            operations_used++;\n            \n            double avg_oil = static_cast<double>(total_oil_estimate) / (grid.N * grid.N);\n            for (int i = 0; i < grid.N; ++i) {\n                for (int j = 0; j < grid.N; ++j) {\n                    grid.estimated_values[i][j] = avg_oil;\n                }\n            }\n        }\n    }\n    \n    queue<tuple<int, int, int, int>> regions;\n    regions.push({0, 0, grid.N-1, grid.N-1});\n    \n    while (!regions.empty() && operations_used < max_operations) {\n        auto [i1, j1, i2, j2] = regions.front();\n        regions.pop();\n        \n        auto points = get_region_points(i1, j1, i2, j2, grid.N);\n        if (points.size() < 2) continue;\n        \n        int oil_estimate = divine(grid, points);\n        operations_used++;\n        \n        if (oil_estimate > 0) {\n            int mid_i = (i1 + i2) / 2;\n            int mid_j = (j1 + j2) / 2;\n            \n            if (i2 - i1 > 1 || j2 - j1 > 1) {\n                regions.push({i1, j1, mid_i, mid_j});\n                regions.push({i1, mid_j + 1, mid_i, j2});\n                regions.push({mid_i + 1, j1, i2, mid_j});\n                regions.push({mid_i + 1, mid_j + 1, i2, j2});\n            } else {\n                for (const auto& p : points) {\n                    if (operations_used < max_operations) {\n                        drill(grid, p.i, p.j);\n                        operations_used++;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (operations_used < max_operations) {\n        vector<pair<double, Point>> candidates;\n        for (int i = 0; i < grid.N; ++i) {\n            for (int j = 0; j < grid.N; ++j) {\n                if (grid.drilled_values[i][j] == -1) {\n                    candidates.emplace_back(grid.estimated_values[i][j], Point(i, j));\n                }\n            }\n        }\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        for (const auto& [_, p] : candidates) {\n            if (operations_used >= max_operations) break;\n            drill(grid, p.i, p.j);\n            operations_used++;\n        }\n    }\n}\n\nvoid infer_oil_fields(GridInfo& grid) {\n    for (const auto& field : grid.oil_fields) {\n        vector<pair<int, Point>> possible_positions;\n        \n        for (int di = 0; di <= grid.N - field.cells.back().i; ++di) {\n            for (int dj = 0; dj <= grid.N - field.cells.back().j; ++dj) {\n                int score = 0;\n                for (const auto& cell : field.cells) {\n                    int i = di + cell.i;\n                    int j = dj + cell.j;\n                    if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                        if (grid.drilled_values[i][j] > 0) {\n                            score += grid.drilled_values[i][j];\n                        } else if (grid.drilled_values[i][j] == 0) {\n                            score = -1;\n                            break;\n                        }\n                    }\n                }\n                if (score > 0) {\n                    possible_positions.emplace_back(score, Point(di, dj));\n                }\n            }\n        }\n        \n        sort(possible_positions.rbegin(), possible_positions.rend());\n        \n        for (int idx = 0; idx < min(3, (int)possible_positions.size()); ++idx) {\n            const auto& [_, pos] = possible_positions[idx];\n            double weight = idx == 0 ? 1.0 : 0.5;\n            \n            for (const auto& cell : field.cells) {\n                int i = pos.i + cell.i;\n                int j = pos.j + cell.j;\n                if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                    if (grid.drilled_values[i][j] == -1) {\n                        grid.estimated_values[i][j] += weight;\n                    }\n                }\n            }\n        }\n    }\n}\n\nset<Point> determine_answer(GridInfo& grid) {\n    set<Point> answer;\n    \n    answer.insert(grid.oil_squares.begin(), grid.oil_squares.end());\n    \n    for (int i = 0; i < grid.N; ++i) {\n        for (int j = 0; j < grid.N; ++j) {\n            if (grid.drilled_values[i][j] == -1 && grid.estimated_values[i][j] > 0.5) {\n                answer.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return answer;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double epsilon;\n    cin >> N >> M >> epsilon;\n    \n    GridInfo grid(N, M, epsilon);\n    read_input(grid);\n    \n    int max_operations = 2 * N * N;\n    \n    explore_grid(grid, max_operations / 2);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations * 3 / 4);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations);\n    \n    set<Point> answer = determine_answer(grid);\n    \n    bool correct = submit_answer(grid, answer);\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <cassert>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    \n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int i0, int j0, int i1, int j1) : i0(i0), j0(j0), i1(i1), j1(j1) {}\n    \n    int area() const {\n        return (i1 - i0) * (j1 - j0);\n    }\n    \n    bool operator==(const Rectangle& other) const {\n        return i0 == other.i0 && j0 == other.j0 && i1 == other.i1 && j1 == other.j1;\n    }\n};\n\nstruct DayLayout {\n    vector<Rectangle> rectangles;\n    vector<vector<int>> horizontal_partitions;  // H_{d,i,j}\n    vector<vector<int>> vertical_partitions;    // V_{d,i,j}\n    \n    DayLayout(int W) {\n        horizontal_partitions.resize(W-1, vector<int>(W, 0));\n        vertical_partitions.resize(W, vector<int>(W-1, 0));\n    }\n    \n    void update_partitions(int W) {\n        // Reset partitions\n        for (auto& row : horizontal_partitions) fill(row.begin(), row.end(), 0);\n        for (auto& row : vertical_partitions) fill(row.begin(), row.end(), 0);\n        \n        // Set partitions based on rectangles\n        for (const auto& rect : rectangles) {\n            // Horizontal partitions (top and bottom edges)\n            if (rect.i0 > 0) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i0-1][j] = 1;\n                }\n            }\n            if (rect.i1 < W) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i1-1][j] = 1;\n                }\n            }\n            \n            // Vertical partitions (left and right edges)\n            if (rect.j0 > 0) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j0-1] = 1;\n                }\n            }\n            if (rect.j1 < W) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j1-1] = 1;\n                }\n            }\n        }\n    }\n};\n\nclass EventHallOptimizer {\nprivate:\n    int W, D, N;\n    vector<vector<int>> desired_areas;\n    vector<DayLayout> layouts;\n    mt19937 rng;\n    \npublic:\n    EventHallOptimizer(int W, int D, int N, const vector<vector<int>>& areas)\n        : W(W), D(D), N(N), desired_areas(areas) {\n        // Initialize random number generator\n        rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n        \n        layouts.reserve(D);\n        for (int d = 0; d < D; ++d) {\n            layouts.emplace_back(W);\n        }\n    }\n    \n    void solve() {\n        // Generate initial layout for day 0\n        generate_initial_layout(0);\n        layouts[0].update_partitions(W);\n        \n        // Generate layouts for subsequent days\n        for (int d = 1; d < D; ++d) {\n            // Start with previous day's layout as base\n            layouts[d] = layouts[d-1];\n            \n            // Optimize layout for day d\n            optimize_layout(d);\n            layouts[d].update_partitions(W);\n        }\n    }\n    \n    void generate_initial_layout(int day) {\n        vector<pair<int, int>> area_indices;\n        for (int k = 0; k < N; ++k) {\n            area_indices.emplace_back(desired_areas[day][k], k);\n        }\n        sort(area_indices.begin(), area_indices.end(), greater<pair<int, int>>());\n        \n        vector<Rectangle> rects(N);\n        vector<bool> used(N, false);\n        \n        // Use a space-filling curve approach\n        int current_i = 0, current_j = 0;\n        \n        for (const auto& [area, idx] : area_indices) {\n            // Find best fitting rectangle\n            Rectangle best_rect;\n            int best_score = -1;\n            \n            // Try different starting positions and sizes\n            for (int start_i = current_i; start_i < W - 1; ++start_i) {\n                for (int start_j = (start_i == current_i ? current_j : 0); start_j < W - 1; ++start_j) {\n                    // Try different aspect ratios\n                    for (int aspect = 1; aspect <= 4; ++aspect) {\n                        int height = sqrt(area * aspect);\n                        int width = area / height;\n                        if (width * height < area) width++;\n                        \n                        // Ensure rectangle fits\n                        if (start_i + height > W || start_j + width > W) continue;\n                        \n                        Rectangle rect(start_i, start_j, start_i + height, start_j + width);\n                        \n                        // Check for overlaps\n                        bool overlap = false;\n                        for (int k = 0; k < N; ++k) {\n                            if (used[k] && rectangles_overlap(rect, rects[k])) {\n                                overlap = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!overlap) {\n                            int score = rect.area();\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (best_score == -1) {\n                // Fallback: place at current position with minimum size\n                int side = ceil(sqrt(area));\n                best_rect = Rectangle(current_i, current_j, \n                                    min(current_i + side, W), \n                                    min(current_j + side, W));\n            }\n            \n            rects[idx] = best_rect;\n            used[idx] = true;\n            \n            // Update current position\n            current_j = best_rect.j1;\n            if (current_j >= W - 1) {\n                current_j = 0;\n                current_i = best_rect.i1;\n            }\n        }\n        \n        layouts[day].rectangles = rects;\n    }\n    \n    void optimize_layout(int day) {\n        const double initial_temp = 1000.0;\n        const double cooling_rate = 0.95;\n        const int iterations = 1000;\n        \n        double temp = initial_temp;\n        vector<Rectangle> current_rects = layouts[day].rectangles;\n        int current_cost = calculate_total_cost(day, current_rects);\n        \n        for (int iter = 0; iter < iterations; ++iter) {\n            // Generate neighbor solution\n            vector<Rectangle> neighbor_rects = current_rects;\n            apply_random_move(day, neighbor_rects);\n            \n            // Calculate cost\n            int neighbor_cost = calculate_total_cost(day, neighbor_rects);\n            \n            // Accept or reject\n            int delta = neighbor_cost - current_cost;\n            if (delta < 0 || exp(-delta / temp) > generate_random_double()) {\n                current_rects = neighbor_rects;\n                current_cost = neighbor_cost;\n            }\n            \n            // Cool down\n            temp *= cooling_rate;\n        }\n        \n        layouts[day].rectangles = current_rects;\n    }\n    \n    void apply_random_move(int day, vector<Rectangle>& rects) {\n        uniform_int_distribution<int> move_dist(0, 2);\n        int move_type = move_dist(rng);\n        \n        switch (move_type) {\n            case 0: // Resize rectangle\n                resize_random_rectangle(rects);\n                break;\n            case 1: // Move rectangle\n                move_random_rectangle(rects);\n                break;\n            case 2: // Swap two rectangles\n                swap_random_rectangles(rects);\n                break;\n        }\n        \n        // Ensure no overlaps\n        fix_overlaps(rects);\n    }\n    \n    void resize_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-10, 10);\n        int di0 = delta_dist(rng);\n        int dj0 = delta_dist(rng);\n        int di1 = delta_dist(rng);\n        int dj1 = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        rect.i0 = max(0, min(W-1, rect.i0 + di0));\n        rect.j0 = max(0, min(W-1, rect.j0 + dj0));\n        rect.i1 = max(rect.i0+1, min(W, rect.i1 + di1));\n        rect.j1 = max(rect.j0+1, min(W, rect.j1 + dj1));\n    }\n    \n    void move_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-5, 5);\n        int di = delta_dist(rng);\n        int dj = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        int height = rect.i1 - rect.i0;\n        int width = rect.j1 - rect.j0;\n        \n        rect.i0 = max(0, min(W - height, rect.i0 + di));\n        rect.j0 = max(0, min(W - width, rect.j0 + dj));\n        rect.i1 = rect.i0 + height;\n        rect.j1 = rect.j0 + width;\n    }\n    \n    void swap_random_rectangles(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx1 = rect_dist(rng);\n        int idx2 = rect_dist(rng);\n        \n        if (idx1 != idx2) {\n            swap(rects[idx1], rects[idx2]);\n        }\n    }\n    \n    void fix_overlaps(vector<Rectangle>& rects) {\n        // Simple overlap resolution: shrink overlapping rectangles\n        for (int i = 0; i < N; ++i) {\n            for (int j = i+1; j < N; ++j) {\n                if (rectangles_overlap(rects[i], rects[j])) {\n                    // Shrink the smaller rectangle\n                    if (rects[i].area() < rects[j].area()) {\n                        shrink_rectangle(rects[i], rects[j]);\n                    } else {\n                        shrink_rectangle(rects[j], rects[i]);\n                    }\n                }\n            }\n        }\n    }\n    \n    void shrink_rectangle(Rectangle& to_shrink, const Rectangle& other) {\n        // Find intersection and shrink accordingly\n        int left = max(to_shrink.j0, other.j0);\n        int right = min(to_shrink.j1, other.j1);\n        int top = max(to_shrink.i0, other.i0);\n        int bottom = min(to_shrink.i1, other.i1);\n        \n        if (left < right && top < bottom) {\n            // Calculate overlap sizes\n            int overlap_width = right - left;\n            int overlap_height = bottom - top;\n            \n            // Shrink in the direction with smaller overlap\n            if (overlap_width < overlap_height) {\n                if (other.j0 <= to_shrink.j0) {\n                    to_shrink.j0 = right;\n                } else {\n                    to_shrink.j1 = left;\n                }\n            } else {\n                if (other.i0 <= to_shrink.i0) {\n                    to_shrink.i0 = bottom;\n                } else {\n                    to_shrink.i1 = top;\n                }\n            }\n        }\n    }\n    \n    int calculate_total_cost(int day, const vector<Rectangle>& rects) {\n        int cost = 0;\n        \n        // Area penalty cost\n        for (int k = 0; k < N; ++k) {\n            int actual_area = rects[k].area();\n            if (actual_area < desired_areas[day][k]) {\n                cost += 100 * (desired_areas[day][k] - actual_area);\n            }\n        }\n        \n        // Partition change cost (except for day 0)\n        if (day > 0) {\n            // Create temporary layout to calculate partitions\n            DayLayout temp_layout(W);\n            temp_layout.rectangles = rects;\n            temp_layout.update_partitions(W);\n            \n            // Calculate partition differences\n            for (int i = 0; i < W-1; ++i) {\n                for (int j = 0; j < W; ++j) {\n                    if (layouts[day-1].horizontal_partitions[i][j] != temp_layout.horizontal_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n            \n            for (int i = 0; i < W; ++i) {\n                for (int j = 0; j < W-1; ++j) {\n                    if (layouts[day-1].vertical_partitions[i][j] != temp_layout.vertical_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n        }\n        \n        return cost;\n    }\n    \n    bool rectangles_overlap(const Rectangle& r1, const Rectangle& r2) {\n        return !(r1.i1 <= r2.i0 || r2.i1 <= r1.i0 || r1.j1 <= r2.j0 || r2.j1 <= r1.j0);\n    }\n    \n    double generate_random_double() {\n        return uniform_real_distribution<double>(0.0, 1.0)(rng);\n    }\n    \n    void output_solution() {\n        for (int d = 0; d < D; ++d) {\n            for (int k = 0; k < N; ++k) {\n                const auto& rect = layouts[d].rectangles[k];\n                cout << rect.i0 << \" \" << rect.j0 << \" \" << rect.i1 << \" \" << rect.j1 << \"\\n\";\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> desired_areas(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> desired_areas[d][k];\n        }\n    }\n    \n    EventHallOptimizer optimizer(W, D, N, desired_areas);\n    optimizer.solve();\n    optimizer.output_solution();\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<pair<int, pair<int, int>>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_improvement = -1;\n        int best_stamp = -1;\n        int best_p = -1;\n        int best_q = -1;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    int improvement = 0;\n                    \n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int v = board[p + i][q + j];\n                            int x = stamps[m][i][j];\n                            \n                            // Calculate the improvement\n                            int current_mod = v % MOD;\n                            int new_mod = (v + x) % MOD;\n                            int cell_improvement = new_mod - current_mod;\n                            if (cell_improvement < 0) cell_improvement += MOD;\n                            \n                            improvement += cell_improvement;\n                        }\n                    }\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_stamp = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_improvement <= 0) {\n            // No improvement, stop early\n            break;\n        }\n        \n        operations.push_back({best_stamp, {best_p, best_q}});\n        \n        // Apply the stamp\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_stamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << endl;\n    for (auto &op : operations) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <set>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 5;\n\nchar move_towards(int i0, int j0, int i1, int j1, int grid[N][N], int crane_pos[N][2], int crane_id, bool is_large, int crane_carrying[N]) {\n    vector<char> dirs = {'U', 'D', 'L', 'R'};\n    vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    int current_dist = abs(i0 - i1) + abs(j0 - j1);\n    vector<char> good_moves;\n    vector<char> ok_moves;\n\n    for (int idx = 0; idx < 4; idx++) {\n        int ni = i0 + moves[idx].first;\n        int nj = j0 + moves[idx].second;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n            continue;\n        }\n\n        if (crane_carrying[crane_id] != -1 && !is_large) {\n            if (grid[ni][nj] != -1) {\n                continue;\n            }\n        }\n\n        int new_dist = abs(ni - i1) + abs(nj - j1);\n        if (new_dist < current_dist) {\n            good_moves.push_back(dirs[idx]);\n        } else if (new_dist == current_dist) {\n            ok_moves.push_back(dirs[idx]);\n        }\n    }\n\n    if (!good_moves.empty()) {\n        return good_moves[0];\n    } else if (!ok_moves.empty()) {\n        return ok_moves[0];\n    } else {\n        return '.';\n    }\n}\n\nint main() {\n    int n_val;\n    cin >> n_val;\n    int A[N][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    int grid[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n\n    int crane_pos[N][2];\n    for (int i = 0; i < N; i++) {\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n    }\n\n    int crane_carrying[N];\n    for (int i = 0; i < N; i++) {\n        crane_carrying[i] = -1;\n    }\n\n    int next_container_index[N] = {0};\n    int next_dispatch[N];\n    for (int i = 0; i < N; i++) {\n        next_dispatch[i] = 5 * i;\n    }\n\n    bool bombed[N] = {false};\n    vector<string> crane_actions(N);\n\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) {\n            if (next_container_index[i] < N) {\n                bool crane_holding_at_gate = false;\n                for (int c = 0; c < N; c++) {\n                    if (!bombed[c] && crane_pos[c][0] == i && crane_pos[c][1] == 0 && crane_carrying[c] != -1) {\n                        crane_holding_at_gate = true;\n                        break;\n                    }\n                }\n                if (grid[i][0] == -1 && !crane_holding_at_gate) {\n                    grid[i][0] = A[i][next_container_index[i]];\n                    next_container_index[i]++;\n                }\n            }\n        }\n\n        vector<char> actions(N, '.');\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                actions[c] = '.';\n                continue;\n            }\n\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            int carrying = crane_carrying[c];\n\n            if (carrying != -1) {\n                int container_id = carrying;\n                int target_gate = container_id / N;\n\n                if (container_id == next_dispatch[target_gate]) {\n                    if (i0 == target_gate && j0 == N-1) {\n                        actions[c] = 'Q';\n                    } else {\n                        actions[c] = move_towards(i0, j0, target_gate, N-1, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (j0 >= 1 && j0 <= 3 && grid[i0][j0] == -1) {\n                        actions[c] = 'Q';\n                    } else {\n                        vector<pair<int, int>> candidates;\n                        for (int i = 0; i < N; i++) {\n                            for (int j = 1; j <= 3; j++) {\n                                if (grid[i][j] == -1) {\n                                    candidates.push_back({i, j});\n                                }\n                            }\n                        }\n                        if (!candidates.empty()) {\n                            auto best = candidates[0];\n                            int best_dist = abs(i0 - best.first) + abs(j0 - best.second);\n                            for (auto cand : candidates) {\n                                int dist = abs(i0 - cand.first) + abs(j0 - cand.second);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best = cand;\n                                }\n                            }\n                            actions[c] = move_towards(i0, j0, best.first, best.second, grid, crane_pos, c, (c==0), crane_carrying);\n                        } else {\n                            actions[c] = '.';\n                        }\n                    }\n                }\n            } else {\n                vector<tuple<int, int, int>> containers;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int cid = grid[i][j];\n                            if (cid / N == c) {\n                                containers.push_back(make_tuple(i, j, cid));\n                            }\n                        }\n                    }\n                }\n                if (!containers.empty()) {\n                    auto best = containers[0];\n                    int best_dist = abs(i0 - get<0>(best)) + abs(j0 - get<1>(best));\n                    for (auto cont : containers) {\n                        int dist = abs(i0 - get<0>(cont)) + abs(j0 - get<1>(cont));\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best = cont;\n                        }\n                    }\n                    int ti = get<0>(best), tj = get<1>(best);\n                    if (i0 == ti && j0 == tj) {\n                        actions[c] = 'P';\n                    } else {\n                        actions[c] = move_towards(i0, j0, ti, tj, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (i0 == c && j0 == 0) {\n                        actions[c] = '.';\n                    } else {\n                        actions[c] = move_towards(i0, j0, c, 0, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> next_pos(N);\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'U') {\n                next_pos[c] = {i0-1, j0};\n            } else if (act == 'D') {\n                next_pos[c] = {i0+1, j0};\n            } else if (act == 'L') {\n                next_pos[c] = {i0, j0-1};\n            } else if (act == 'R') {\n                next_pos[c] = {i0, j0+1};\n            } else {\n                next_pos[c] = {i0, j0};\n            }\n        }\n\n        set<int> involved;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == make_pair(crane_pos[j][0], crane_pos[j][1]) && \n                    next_pos[j] == make_pair(crane_pos[i][0], crane_pos[i][1])) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n\n        for (int c : involved) {\n            if (!bombed[c]) {\n                actions[c] = '.';\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'P') {\n                if (crane_carrying[c] == -1 && grid[i0][j0] != -1) {\n                    crane_carrying[c] = grid[i0][j0];\n                    grid[i0][j0] = -1;\n                }\n            } else if (act == 'Q') {\n                if (crane_carrying[c] != -1 && grid[i0][j0] == -1) {\n                    grid[i0][j0] = crane_carrying[c];\n                    crane_carrying[c] = -1;\n                }\n            } else if (act == 'B') {\n                if (crane_carrying[c] == -1) {\n                    bombed[c] = true;\n                }\n            } else if (act == 'U' || act == 'D' || act == 'L' || act == 'R') {\n                crane_pos[c][0] = next_pos[c].first;\n                crane_pos[c][1] = next_pos[c].second;\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container_id = grid[i][N-1];\n                grid[i][N-1] = -1;\n                next_dispatch[i] = container_id + 1;\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            crane_actions[c] += actions[c];\n        }\n\n        int total_dispatched = 0;\n        for (int i = 0; i < N; i++) {\n            total_dispatched += (next_dispatch[i] - 5*i);\n        }\n        if (total_dispatched == N*N) {\n            break;\n        }\n    }\n\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        if (crane_actions[i].size() > max_len) {\n            max_len = crane_actions[i].size();\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        while (crane_actions[i].size() < max_len) {\n            crane_actions[i] += '.';\n        }\n        cout << crane_actions[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <tuple>\n#include <string>\nusing namespace std;\n\nvector<string> get_manhattan_path(pair<int, int> start, pair<int, int> end) {\n    vector<string> path;\n    int x1 = start.first, y1 = start.second;\n    int x2 = end.first, y2 = end.second;\n    while (x1 < x2) {\n        path.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        path.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        path.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        path.push_back(\"L\");\n        y1--;\n    }\n    return path;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    long long base = 0;\n    vector<tuple<int, int, int>> sources;\n    vector<tuple<int, int, int>> sinks;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                sources.emplace_back(i, j, grid[i][j]);\n                base += grid[i][j];\n            } else if (grid[i][j] < 0) {\n                sinks.emplace_back(i, j, -grid[i][j]);\n                base += -grid[i][j];\n            }\n        }\n    }\n\n    long long total_soil = base / 2;\n\n    if (total_soil == 0) {\n        cout << endl;\n        return 0;\n    }\n\n    pair<int, int> best_hub;\n    long long best_cost = LLONG_MAX;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pair<int, int> hub = {i, j};\n\n            vector<tuple<int, int, int>> sorted_sources = sources;\n            sort(sorted_sources.begin(), sorted_sources.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            vector<tuple<int, int, int>> sorted_sinks = sinks;\n            sort(sorted_sinks.begin(), sorted_sinks.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            long long cost_transport = 0;\n            pair<int, int> current = {0, 0};\n            long long load = 0;\n\n            if (!sorted_sources.empty()) {\n                auto first = sorted_sources[0];\n                int d = abs(current.first - get<0>(first)) + abs(current.second - get<1>(first));\n                cost_transport += d * 100;\n                current = {get<0>(first), get<1>(first)};\n                load += get<2>(first);\n\n                for (int idx = 1; idx < sorted_sources.size(); idx++) {\n                    auto src = sorted_sources[idx];\n                    d = abs(current.first - get<0>(src)) + abs(current.second - get<1>(src));\n                    cost_transport += d * (100 + load);\n                    current = {get<0>(src), get<1>(src)};\n                    load += get<2>(src);\n                }\n\n                d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * (100 + load);\n            } else {\n                int d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * 100;\n            }\n\n            current = hub;\n            load = total_soil;\n\n            for (int idx = 0; idx < sorted_sinks.size(); idx++) {\n                auto sink = sorted_sinks[idx];\n                int d = abs(current.first - get<0>(sink)) + abs(current.second - get<1>(sink));\n                cost_transport += d * (100 + load);\n                current = {get<0>(sink), get<1>(sink)};\n                load -= get<2>(sink);\n            }\n\n            long long total_cost = base + cost_transport;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                best_hub = hub;\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> sorted_sources = sources;\n    sort(sorted_sources.begin(), sorted_sources.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<tuple<int, int, int>> sorted_sinks = sinks;\n    sort(sorted_sinks.begin(), sorted_sinks.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<string> operations;\n    pair<int, int> current_pos = {0, 0};\n\n    if (!sorted_sources.empty()) {\n        auto first = sorted_sources[0];\n        pair<int, int> first_pos = {get<0>(first), get<1>(first)};\n        vector<string> path = get_manhattan_path(current_pos, first_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"+\" + to_string(get<2>(first)));\n        current_pos = first_pos;\n\n        for (int idx = 1; idx < sorted_sources.size(); idx++) {\n            auto src = sorted_sources[idx];\n            pair<int, int> src_pos = {get<0>(src), get<1>(src)};\n            vector<string> path = get_manhattan_path(current_pos, src_pos);\n            operations.insert(operations.end(), path.begin(), path.end());\n            operations.push_back(\"+\" + to_string(get<2>(src)));\n            current_pos = src_pos;\n        }\n\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    } else {\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    }\n\n    for (auto sink : sorted_sinks) {\n        pair<int, int> sink_pos = {get<0>(sink), get<1>(sink)};\n        vector<string> path = get_manhattan_path(current_pos, sink_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"-\" + to_string(get<2>(sink)));\n        current_pos = sink_pos;\n    }\n\n    for (const string& op : operations) {\n        cout << op << endl;\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    // For each turn\n    for (int t = 0; t < T; t++) {\n        // Calculate scores for each seed\n        vector<pair<double, int>> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            // Calculate total value\n            int total_value = accumulate(X[i].begin(), X[i].end(), 0);\n            \n            // Find maximum value in any single criterion\n            int max_criterion = *max_element(X[i].begin(), X[i].end());\n            \n            // Calculate sum of top 5 criteria\n            vector<int> sorted_criteria = X[i];\n            sort(sorted_criteria.rbegin(), sorted_criteria.rend());\n            int top5_sum = accumulate(sorted_criteria.begin(), sorted_criteria.begin() + min(5, M), 0);\n            \n            // Combined score with weights\n            double score = 0.5 * total_value + 0.3 * max_criterion + 0.2 * top5_sum;\n            seed_scores[i] = {score, i};\n        }\n        \n        // Sort seeds by score in descending order\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Select top 36 seeds\n        vector<int> selected_seeds;\n        for (int i = 0; i < N * N; i++) {\n            selected_seeds.push_back(seed_scores[i].second);\n        }\n        \n        // Create grid arrangement\n        vector<vector<int>> A(N, vector<int>(N, 0));\n        \n        // Strategy: Place seeds with complementary strengths adjacent to each other\n        // Sort selected seeds by their strongest criterion\n        vector<pair<int, int>> seeds_by_max_criterion;\n        for (int seed : selected_seeds) {\n            int max_val = *max_element(X[seed].begin(), X[seed].end());\n            seeds_by_max_criterion.push_back({max_val, seed});\n        }\n        \n        // Sort by maximum criterion value\n        sort(seeds_by_max_criterion.rbegin(), seeds_by_max_criterion.rend());\n        \n        // Place in a checkerboard pattern, alternating high and medium seeds\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if ((i + j) % 2 == 0) {\n                    // Place a seed with high maximum criterion\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                } else {\n                    // Place a seed with balanced criteria\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                }\n            }\n        }\n        \n        // Output the arrangement\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds for next turn\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> X[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <climits>\n#include <queue>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s_grid(N);\n    vector<string> t_grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> s_grid[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t_grid[i];\n    }\n    \n    set<pair<int, int>> S;\n    set<pair<int, int>> T;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0') {\n                S.insert({i, j});\n            }\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0') {\n                T.insert({i, j});\n            }\n        }\n    }\n    \n    const vector<int> dx = {0, 1, 0, -1};\n    const vector<int> dy = {1, 0, -1, 0};\n    const vector<char> move_dir = {'R', 'D', 'L', 'U'};\n    \n    int V_prime = 2;\n    cout << V_prime << '\\n';\n    cout << \"0 1\\n\";\n    int rx0 = (N-1)/2;\n    int ry0 = (N-1)/2;\n    cout << rx0 << \" \" << ry0 << '\\n';\n    cout.flush();\n    \n    int rx = rx0;\n    int ry = ry0;\n    int dir = 0;\n    \n    auto manhattan_move = [&](int x1, int y1, int x2, int y2) {\n        vector<char> moves;\n        while (x1 < x2) {\n            moves.push_back('D');\n            x1++;\n        }\n        while (x1 > x2) {\n            moves.push_back('U');\n            x1--;\n        }\n        while (y1 < y2) {\n            moves.push_back('R');\n            y1++;\n        }\n        while (y1 > y2) {\n            moves.push_back('L');\n            y1--;\n        }\n        return moves;\n    };\n    \n    while (!S.empty()) {\n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq;\n        \n        for (const auto& pos : S) {\n            int i = pos.first, j = pos.second;\n            for (int d = 0; d < 4; d++) {\n                int x = i + dx[d];\n                int y = j + dy[d];\n                if (x >= 0 && x < N && y >= 0 && y < N) {\n                    int dist = abs(rx - x) + abs(ry - y);\n                    pq.push({dist, {pos, {x, y}}});\n                }\n            }\n        }\n        \n        auto best = pq.top();\n        pq.pop();\n        pair<int, int> best_pos = best.second.first;\n        pair<int, int> best_adj = best.second.second;\n        \n        int a = best_pos.first;\n        int b = best_pos.second;\n        int x = best_adj.first;\n        int y = best_adj.second;\n        \n        vector<char> path = manhattan_move(rx, ry, x, y);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        int desired_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (dx[d] == a - x && dy[d] == b - y) {\n                desired_dir = d;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string grab_command(2 * V_prime, '.');\n        grab_command[V_prime + 1] = 'P';\n        cout << grab_command << '\\n';\n        cout.flush();\n        S.erase({a, b});\n        \n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq_t;\n        \n        for (const auto& target : T) {\n            int i = target.first, j = target.second;\n            for (int d = 0; d < 4; d++) {\n                int x_target = i + dx[d];\n                int y_target = j + dy[d];\n                if (x_target >= 0 && x_target < N && y_target >= 0 && y_target < N) {\n                    int dist = abs(rx - x_target) + abs(ry - y_target);\n                    pq_t.push({dist, {target, {x_target, y_target}}});\n                }\n            }\n        }\n        \n        auto best_t = pq_t.top();\n        pq_t.pop();\n        pair<int, int> best_target = best_t.second.first;\n        pair<int, int> best_adj_target = best_t.second.second;\n        \n        int c = best_target.first;\n        int d = best_target.second;\n        int x_target = best_adj_target.first;\n        int y_target = best_adj_target.second;\n        \n        path = manhattan_move(rx, ry, x_target, y_target);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        desired_dir = -1;\n        for (int d_val = 0; d_val < 4; d_val++) {\n            if (dx[d_val] == c - x_target && dy[d_val] == d - y_target) {\n                desired_dir = d_val;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string release_command(2 * V_prime, '.');\n        release_command[V_prime + 1] = 'P';\n        cout << release_command << '\\n';\n        cout.flush();\n        T.erase({c, d});\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <chrono>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Point {\n    int x, y;\n    \n    bool operator<(const Point& other) const {\n        return tie(x, y) < tie(other.x, other.y);\n    }\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Polygon {\n    vector<Point> vertices;\n    \n    void add_vertex(const Point& p) {\n        vertices.push_back(p);\n    }\n    \n    double perimeter() const {\n        double perim = 0;\n        for (int i = 0; i < vertices.size(); ++i) {\n            int j = (i + 1) % vertices.size();\n            perim += abs(vertices[i].x - vertices[j].x) + abs(vertices[i].y - vertices[j].y);\n        }\n        return perim;\n    }\n    \n    bool contains(const Point& p) const {\n        int n = vertices.size();\n        bool inside = false;\n        \n        for (int i = 0, j = n - 1; i < n; j = i++) {\n            const Point& vi = vertices[i];\n            const Point& vj = vertices[j];\n            \n            if ((vi.y == vj.y) && (p.y == vi.y) && \n                (p.x >= min(vi.x, vj.x)) && (p.x <= max(vi.x, vj.x))) {\n                return true;\n            }\n            \n            if ((vi.x == vj.x) && (p.x == vi.x) && \n                (p.y >= min(vi.y, vj.y)) && (p.y <= max(vi.y, vj.y))) {\n                return true;\n            }\n            \n            if (((vi.y > p.y) != (vj.y > p.y)) &&\n                (p.x < (vj.x - vi.x) * (p.y - vi.y) / (vj.y - vi.y) + vi.x)) {\n                inside = !inside;\n            }\n        }\n        \n        return inside;\n    }\n    \n    bool is_simple() const {\n        int n = vertices.size();\n        if (n < 3) return false;\n        \n        for (int i = 0; i < n; ++i) {\n            int j = (i + 1) % n;\n            const Point& a = vertices[i];\n            const Point& b = vertices[j];\n            \n            for (int k = i + 1; k < n; ++k) {\n                int l = (k + 1) % n;\n                if (k == j || l == i || k == i) continue;\n                \n                const Point& c = vertices[k];\n                const Point& d = vertices[l];\n                \n                if (segments_intersect(a, b, c, d)) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \nprivate:\n    bool segments_intersect(const Point& a, const Point& b, const Point& c, const Point& d) const {\n        if (max(a.x, b.x) < min(c.x, d.x) || max(c.x, d.x) < min(a.x, b.x)) return false;\n        if (max(a.y, b.y) < min(c.y, d.y) || max(c.y, d.y) < min(a.y, b.y)) return false;\n        \n        long long cross1 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n        long long cross2 = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);\n        long long cross3 = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);\n        long long cross4 = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);\n        \n        if ((cross1 * cross2 < 0) && (cross3 * cross4 < 0)) return true;\n        \n        if (cross1 == 0 && on_segment(a, b, c)) return true;\n        if (cross2 == 0 && on_segment(a, b, d)) return true;\n        if (cross3 == 0 && on_segment(c, d, a)) return true;\n        if (cross4 == 0 && on_segment(c, d, b)) return true;\n        \n        return false;\n    }\n    \n    bool on_segment(const Point& a, const Point& b, const Point& c) const {\n        return c.x >= min(a.x, b.x) && c.x <= max(a.x, b.x) &&\n               c.y >= min(a.y, b.y) && c.y <= max(a.y, b.y);\n    }\n};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<Point> mackerels(N);\n    vector<Point> sardines(N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].x >> mackerels[i].y;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].x >> sardines[i].y;\n    }\n    \n    const int cluster_size = 50;\n    vector<vector<Point>> mackerel_clusters;\n    vector<bool> used(N, false);\n    \n    for (int i = 0; i < N; ++i) {\n        if (!used[i]) {\n            vector<Point> cluster;\n            cluster.push_back(mackerels[i]);\n            used[i] = true;\n            \n            for (int j = i + 1; j < N && cluster.size() < cluster_size; ++j) {\n                if (!used[j]) {\n                    int dx = mackerels[i].x - mackerels[j].x;\n                    int dy = mackerels[i].y - mackerels[j].y;\n                    if (dx * dx + dy * dy < 10000 * 10000) {\n                        cluster.push_back(mackerels[j]);\n                        used[j] = true;\n                    }\n                }\n            }\n            \n            if (cluster.size() >= 10) {\n                mackerel_clusters.push_back(cluster);\n            }\n        }\n    }\n    \n    sort(mackerel_clusters.begin(), mackerel_clusters.end(), \n         [](const vector<Point>& a, const vector<Point>& b) {\n             return a.size() > b.size();\n         });\n    \n    vector<tuple<int, int, int, int>> cluster_boxes;\n    for (const auto& cluster : mackerel_clusters) {\n        int min_x = 100000, max_x = 0;\n        int min_y = 100000, max_y = 0;\n        \n        for (const auto& p : cluster) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        cluster_boxes.emplace_back(min_x, min_y, max_x, max_y);\n    }\n    \n    Polygon best_polygon;\n    int best_score = 0;\n    \n    auto calculate_score = [](const Polygon& poly, const vector<Point>& macks, const vector<Point>& sards) {\n        int a = 0, b = 0;\n        for (const auto& p : macks) {\n            if (poly.contains(p)) {\n                a++;\n            }\n        }\n        for (const auto& p : sards) {\n            if (poly.contains(p)) {\n                b++;\n            }\n        }\n        return max(0, a - b + 1);\n    };\n    \n    for (size_t i = 0; i < min(mackerel_clusters.size(), size_t(10)); ++i) {\n        const auto& box = cluster_boxes[i];\n        int min_x = get<0>(box);\n        int min_y = get<1>(box);\n        int max_x = get<2>(box);\n        int max_y = get<3>(box);\n        \n        Polygon polygon;\n        polygon.add_vertex({min_x, min_y});\n        polygon.add_vertex({max_x, min_y});\n        polygon.add_vertex({max_x, max_y});\n        polygon.add_vertex({min_x, max_y});\n        \n        const int max_expansions = 10;\n        for (int expansion = 0; expansion < max_expansions; ++expansion) {\n            vector<Polygon> expansions;\n            \n            if (polygon.vertices[0].x > 0) {\n                Polygon left_poly = polygon;\n                left_poly.vertices[0].x = max(0, left_poly.vertices[0].x - 1000);\n                left_poly.vertices[3].x = left_poly.vertices[0].x;\n                if (left_poly.is_simple()) {\n                    expansions.push_back(left_poly);\n                }\n            }\n            \n            if (polygon.vertices[1].x < 100000) {\n                Polygon right_poly = polygon;\n                right_poly.vertices[1].x = min(100000, right_poly.vertices[1].x + 1000);\n                right_poly.vertices[2].x = right_poly.vertices[1].x;\n                if (right_poly.is_simple()) {\n                    expansions.push_back(right_poly);\n                }\n            }\n            \n            if (polygon.vertices[0].y > 0) {\n                Polygon down_poly = polygon;\n                down_poly.vertices[0].y = max(0, down_poly.vertices[0].y - 1000);\n                down_poly.vertices[1].y = down_poly.vertices[0].y;\n                if (down_poly.is_simple()) {\n                    expansions.push_back(down_poly);\n                }\n            }\n            \n            if (polygon.vertices[2].y < 100000) {\n                Polygon up_poly = polygon;\n                up_poly.vertices[2].y = min(100000, up_poly.vertices[2].y + 1000);\n                up_poly.vertices[3].y = up_poly.vertices[2].y;\n                if (up_poly.is_simple()) {\n                    expansions.push_back(up_poly);\n                }\n            }\n            \n            Polygon best_expansion = polygon;\n            int best_expansion_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& exp : expansions) {\n                if (exp.perimeter() <= 400000) {\n                    int score = calculate_score(exp, mackerels, sardines);\n                    if (score > best_expansion_score) {\n                        best_expansion = exp;\n                        best_expansion_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_expansion;\n        }\n        \n        vector<Point> inside_sardines;\n        for (const auto& p : sardines) {\n            if (polygon.contains(p)) {\n                inside_sardines.push_back(p);\n            }\n        }\n        \n        if (!inside_sardines.empty()) {\n            uniform_int_distribution<int> dist(0, inside_sardines.size() - 1);\n            Point target = inside_sardines[dist(rng)];\n            \n            vector<Polygon> adjusted_polygons;\n            \n            // Try shrinking from each direction\n            if (target.x < polygon.vertices[0].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].x = max(0, new_poly.vertices[0].x - 1000);\n                new_poly.vertices[3].x = new_poly.vertices[0].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.x > polygon.vertices[1].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[1].x = min(100000, new_poly.vertices[1].x + 1000);\n                new_poly.vertices[2].x = new_poly.vertices[1].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y < polygon.vertices[0].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].y = max(0, new_poly.vertices[0].y - 1000);\n                new_poly.vertices[1].y = new_poly.vertices[0].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y > polygon.vertices[2].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[2].y = min(100000, new_poly.vertices[2].y + 1000);\n                new_poly.vertices[3].y = new_poly.vertices[2].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            Polygon best_adjusted = polygon;\n            int best_adjusted_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& adj : adjusted_polygons) {\n                if (adj.perimeter() <= 400000) {\n                    int score = calculate_score(adj, mackerels, sardines);\n                    if (score > best_adjusted_score) {\n                        best_adjusted = adj;\n                        best_adjusted_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_adjusted;\n        }\n        \n        int score = calculate_score(polygon, mackerels, sardines);\n        if (score > best_score) {\n            best_score = score;\n            best_polygon = polygon;\n        }\n    }\n    \n    if (best_polygon.vertices.empty()) {\n        best_polygon.add_vertex({0, 0});\n        best_polygon.add_vertex({100000, 0});\n        best_polygon.add_vertex({100000, 100000});\n        best_polygon.add_vertex({0, 100000});\n    }\n    \n    cout << best_polygon.vertices.size() << \"\\n\";\n    for (const auto& p : best_polygon.vertices) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <cctype>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<tuple<double, double, double, double, int>> placed_rectangles;\n        double current_width = 0.0;\n        double current_height = 0.0;\n        double penalty = 0.0;\n        vector<tuple<int, int, char, int>> sequence;\n\n        for (int i = 0; i < N; i++) {\n            tuple<int, int, char, int, double, double, double, double> best_option;\n            double best_cost = 1e18;\n            bool found = false;\n\n            double cost_skip = current_width + current_height + penalty + (w_est[i] + h_est[i]);\n\n            for (int rotation : {0, 1}) {\n                double w_i = (rotation == 0) ? w_est[i] : h_est[i];\n                double h_i = (rotation == 0) ? h_est[i] : w_est[i];\n\n                for (char direction : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (const auto& rect : placed_rectangles) {\n                        refs.push_back(get<4>(rect));\n                    }\n\n                    for (int ref : refs) {\n                        double x0, y0;\n                        if (direction == 'U') {\n                            if (ref == -1) {\n                                x0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                x0 = get<0>(*it) + get<2>(*it);\n                            }\n                            y0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_x, x0) < min(r_x + r_w, x0 + w_i)) {\n                                    double candidate = r_y + r_h;\n                                    if (candidate > y0) {\n                                        y0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        } else {\n                            if (ref == -1) {\n                                y0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                y0 = get<1>(*it) + get<3>(*it);\n                            }\n                            x0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_y, y0) < min(r_y + r_h, y0 + h_i)) {\n                                    double candidate = r_x + r_w;\n                                    if (candidate > x0) {\n                                        x0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (found && best_cost < cost_skip) {\n                auto [i_opt, rot_opt, dir_opt, ref_opt, x0_opt, y0_opt, w_i_opt, h_i_opt] = best_option;\n                current_width = max(current_width, x0_opt + w_i_opt);\n                current_height = max(current_height, y0_opt + h_i_opt);\n                placed_rectangles.emplace_back(x0_opt, y0_opt, w_i_opt, h_i_opt, i_opt);\n                sequence.emplace_back(i_opt, rot_opt, dir_opt, ref_opt);\n            } else {\n                penalty += (w_est[i] + h_est[i]);\n            }\n        }\n\n        cout << sequence.size() << '\\n';\n        for (const auto& [i, rot, dir, ref] : sequence) {\n            cout << i << ' ' << rot << ' ' << dir << ' ' << ref << '\\n';\n        }\n        cout << flush;\n\n        if (turn < T - 1) {\n            int W_prime, H_prime;\n            cin >> W_prime >> H_prime;\n\n            double width_factor = 1.0;\n            if (current_width > 0) {\n                width_factor = static_cast<double>(W_prime) / current_width;\n            }\n            double height_factor = 1.0;\n            if (current_height > 0) {\n                height_factor = static_cast<double>(H_prime) / current_height;\n            }\n\n            double alpha = 0.2;\n            width_factor = 1.0 + alpha * (width_factor - 1.0);\n            height_factor = 1.0 + alpha * (height_factor - 1.0);\n\n            for (const auto& rect : placed_rectangles) {\n                int idx = get<4>(rect);\n                w_est[idx] *= width_factor;\n                h_est[idx] *= height_factor;\n                w_est[idx] = max(1.0, min(1e9, w_est[idx]));\n                h_est[idx] = max(1.0, min(1e9, h_est[idx]));\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <unordered_set>\n\nusing namespace std;\n\nstruct Vertex {\n    int id;\n    int x, y;\n    int beauty;\n    vector<int> neighbors;\n    int parent;\n    int height;\n    int root;\n};\n\nint H;  // Global height limit\nvector<vector<bool>> is_adjacent;  // Adjacency matrix for O(1) edge checks\n\n// Function to calculate attractiveness of a solution\nlong long calculate_attractiveness(const vector<Vertex>& vertices) {\n    long long attractiveness = 0;\n    for (const auto& v : vertices) {\n        attractiveness += (long long)(v.height + 1) * v.beauty;\n    }\n    return attractiveness;\n}\n\n// Function to update heights after changing a parent\nvoid update_heights(vector<Vertex>& vertices, int v) {\n    if (vertices[v].parent == -1) {\n        vertices[v].height = 0;\n        vertices[v].root = v;\n    } else {\n        vertices[v].height = vertices[vertices[v].parent].height + 1;\n        vertices[v].root = vertices[vertices[v].parent].root;\n    }\n    \n    // Recursively update children\n    for (int u : vertices[v].neighbors) {\n        if (vertices[u].parent == v) {\n            update_heights(vertices, u);\n        }\n    }\n}\n\n// Function to check if a parent assignment is valid (height <= H and edge exists)\nbool is_valid_parent(const vector<Vertex>& vertices, int v, int parent) {\n    if (parent == -1) return true;\n    if (vertices[parent].height >= H) return false;\n    return is_adjacent[v][parent];\n}\n\n// Function to check if u is a descendant of v\nbool is_descendant(const vector<Vertex>& vertices, int u, int v) {\n    int current = u;\n    while (current != -1) {\n        if (current == v) {\n            return true;\n        }\n        current = vertices[current].parent;\n    }\n    return false;\n}\n\n// Function to calculate Euclidean distance between two vertices\ndouble distance(const Vertex& a, const Vertex& b) {\n    double dx = a.x - b.x;\n    double dy = a.y - b.y;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Function to find the best parent for a vertex\nint find_best_parent(const vector<Vertex>& vertices, int v, const vector<bool>& is_root) {\n    int best_parent = -1;\n    long long best_gain = 0;\n    \n    // Consider neighbors that are roots or from different trees\n    for (int u : vertices[v].neighbors) {\n        if (is_root[u] || vertices[u].root != vertices[v].root) {\n            if (is_valid_parent(vertices, v, u)) {\n                // Calculate the gain in attractiveness if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                // Prefer parents that allow for deeper nesting in the future\n                if (new_height < H) {\n                    gain += vertices[v].beauty / 2;  // Bonus for potential future gains\n                }\n                \n                // Add a spatial component: prefer closer parents\n                double dist = distance(vertices[v], vertices[u]);\n                double spatial_factor = 1.0 / (1.0 + dist / 100.0);  // Normalize distance\n                gain = (long long)(gain * spatial_factor);\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n    }\n    \n    return best_parent;\n}\n\n// Function to perform local search\nvoid local_search(vector<Vertex>& vertices, const vector<vector<int>>& adj, int max_iterations) {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> vertex_dist(0, vertices.size() - 1);\n    \n    long long current_attractiveness = calculate_attractiveness(vertices);\n    vector<bool> is_root(vertices.size(), false);\n    for (const auto& v : vertices) {\n        if (v.parent == -1) {\n            is_root[v.id] = true;\n        }\n    }\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        int v = vertex_dist(gen);\n        \n        // Try to find a better parent for v\n        int current_parent = vertices[v].parent;\n        int best_parent = current_parent;\n        long long best_gain = 0;\n        \n        for (int u : adj[v]) {\n            if (u != current_parent && vertices[u].parent != v && \n                !is_descendant(vertices, u, v) &&  // Avoid creating cycles\n                is_valid_parent(vertices, v, u)) {\n                \n                // Calculate the gain if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n        \n        // If we found a better parent, update the solution\n        if (best_parent != current_parent && best_gain > 0) {\n            // Remove v from its current parent's children\n            if (current_parent != -1) {\n                // No need to explicitly remove, just update parent pointer\n            }\n            \n            // Add v to its new parent\n            vertices[v].parent = best_parent;\n            update_heights(vertices, v);\n            \n            // Update root status\n            if (current_parent == -1) {\n                is_root[v] = false;\n            }\n            if (best_parent == -1) {\n                is_root[v] = true;\n            }\n            \n            current_attractiveness += best_gain;\n        }\n        \n        // Occasionally try to make a vertex a root\n        if (iter % 100 == 0 && vertices[v].parent != -1) {\n            // Check if all children of v are actually adjacent to v\n            bool all_children_adjacent = true;\n            for (int u : adj[v]) {\n                if (vertices[u].parent == v && !is_adjacent[v][u]) {\n                    all_children_adjacent = false;\n                    break;\n                }\n            }\n            \n            if (all_children_adjacent) {\n                int old_parent = vertices[v].parent;\n                vertices[v].parent = -1;\n                update_heights(vertices, v);\n                \n                long long new_attractiveness = calculate_attractiveness(vertices);\n                if (new_attractiveness > current_attractiveness) {\n                    current_attractiveness = new_attractiveness;\n                    is_root[v] = true;\n                } else {\n                    // Revert the change\n                    vertices[v].parent = old_parent;\n                    update_heights(vertices, v);\n                }\n            }\n        }\n    }\n}\n\n// Function to validate the solution\nbool validate_solution(const vector<Vertex>& vertices, const vector<vector<int>>& adj) {\n    // Check that all parent-child relationships correspond to edges in the graph\n    for (const auto& v : vertices) {\n        if (v.parent != -1) {\n            if (!is_adjacent[v.id][v.parent]) {\n                return false;\n            }\n        }\n    }\n    \n    // Check that there are no cycles\n    for (const auto& v : vertices) {\n        unordered_set<int> visited;\n        int current = v.id;\n        while (current != -1) {\n            if (visited.count(current)) {\n                return false;  // Cycle detected\n            }\n            visited.insert(current);\n            current = vertices[current].parent;\n        }\n    }\n    \n    // Check height constraints\n    for (const auto& v : vertices) {\n        if (v.height > H) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M >> H;\n    \n    is_adjacent.assign(N, vector<bool>(N, false));\n    \n    vector<Vertex> vertices(N);\n    for (int i = 0; i < N; i++) {\n        vertices[i].id = i;\n        cin >> vertices[i].beauty;\n    }\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        vertices[u].neighbors.push_back(v);\n        vertices[v].neighbors.push_back(u);\n        is_adjacent[u][v] = true;\n        is_adjacent[v][u] = true;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].x >> vertices[i].y;\n    }\n    \n    // Initialize with each vertex as its own tree\n    for (auto& v : vertices) {\n        v.parent = -1;\n        v.height = 0;\n        v.root = v.id;\n    }\n    \n    // Sort vertices by beauty (higher beauty first) to prioritize them\n    vector<int> vertex_ids(N);\n    for (int i = 0; i < N; i++) {\n        vertex_ids[i] = i;\n    }\n    sort(vertex_ids.begin(), vertex_ids.end(), [&](int a, int b) {\n        return vertices[a].beauty > vertices[b].beauty;\n    });\n    \n    // Greedily assign parents\n    vector<bool> is_root(N, true);\n    for (int v : vertex_ids) {\n        // Only try to assign parents to vertices that can gain from having a parent\n        if (vertices[v].beauty > 20) {  // Lower threshold for more assignments\n            int best_parent = find_best_parent(vertices, v, is_root);\n            if (best_parent != -1) {\n                vertices[v].parent = best_parent;\n                is_root[v] = false;\n                update_heights(vertices, v);\n            }\n        }\n    }\n    \n    // Perform local search with more iterations\n    local_search(vertices, adj, 50000);  // Increased iterations for better results\n    \n    // Final validation\n    if (!validate_solution(vertices, adj)) {\n        // If validation fails, reset to a safe solution (each vertex as root)\n        for (auto& v : vertices) {\n            v.parent = -1;\n            v.height = 0;\n            v.root = v.id;\n        }\n    }\n    \n    // Output the solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertices[i].parent;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <climits>\n#include <algorithm>\n\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    set<pair<int, int>> oni_set;\n    set<pair<int, int>> fuku_set;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == 'x') {\n                oni_set.insert({i, j});\n            } else if (grid[i][j] == 'o') {\n                fuku_set.insert({i, j});\n            }\n        }\n    }\n\n    vector<pair<char, int>> moves;\n\n    while (!oni_set.empty()) {\n        int best_cost = INT_MAX;\n        pair<int, int> best_oni;\n        char best_dir;\n        int best_index;\n\n        for (auto oni : oni_set) {\n            int i = oni.first;\n            int j = oni.second;\n\n            bool safe_up = true;\n            for (int r = 0; r < i; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_up = false;\n                    break;\n                }\n            }\n\n            bool safe_down = true;\n            for (int r = i+1; r < N; r++) {\n                if (grid[r][j] == 'o') {\n                    safe_down = false;\n                    break;\n                }\n            }\n\n            bool safe_left = true;\n            for (int c = 0; c < j; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_left = false;\n                    break;\n                }\n            }\n\n            bool safe_right = true;\n            for (int c = j+1; c < N; c++) {\n                if (grid[i][c] == 'o') {\n                    safe_right = false;\n                    break;\n                }\n            }\n\n            if (safe_up) {\n                int cost = i + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'U';\n                    best_index = j;\n                }\n            }\n            if (safe_down) {\n                int cost = N - i;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'D';\n                    best_index = j;\n                }\n            }\n            if (safe_left) {\n                int cost = j + 1;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'L';\n                    best_index = i;\n                }\n            }\n            if (safe_right) {\n                int cost = N - j;\n                if (cost < best_cost) {\n                    best_cost = cost;\n                    best_oni = oni;\n                    best_dir = 'R';\n                    best_index = i;\n                }\n            }\n        }\n\n        if (best_cost == INT_MAX) {\n            break;\n        }\n\n        for (int step = 0; step < best_cost; step++) {\n            moves.push_back({best_dir, best_index});\n\n            if (best_dir == 'U') {\n                char top = grid[0][best_index];\n                grid[0][best_index] = '.';\n                if (top == 'x') {\n                    oni_set.erase({0, best_index});\n                } else if (top == 'o') {\n                    fuku_set.erase({0, best_index});\n                }\n\n                for (int r = 1; r < N; r++) {\n                    char c = grid[r][best_index];\n                    grid[r-1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r-1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r-1, best_index});\n                    }\n                }\n                grid[N-1][best_index] = '.';\n            } else if (best_dir == 'D') {\n                char bottom = grid[N-1][best_index];\n                grid[N-1][best_index] = '.';\n                if (bottom == 'x') {\n                    oni_set.erase({N-1, best_index});\n                } else if (bottom == 'o') {\n                    fuku_set.erase({N-1, best_index});\n                }\n\n                for (int r = N-2; r >= 0; r--) {\n                    char c = grid[r][best_index];\n                    grid[r+1][best_index] = c;\n                    if (c == 'x') {\n                        oni_set.erase({r, best_index});\n                        oni_set.insert({r+1, best_index});\n                    } else if (c == 'o') {\n                        fuku_set.erase({r, best_index});\n                        fuku_set.insert({r+1, best_index});\n                    }\n                }\n                grid[0][best_index] = '.';\n            } else if (best_dir == 'L') {\n                char leftmost = grid[best_index][0];\n                grid[best_index][0] = '.';\n                if (leftmost == 'x') {\n                    oni_set.erase({best_index, 0});\n                } else if (leftmost == 'o') {\n                    fuku_set.erase({best_index, 0});\n                }\n\n                for (int c = 1; c < N; c++) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c-1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c-1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c-1});\n                    }\n                }\n                grid[best_index][N-1] = '.';\n            } else if (best_dir == 'R') {\n                char rightmost = grid[best_index][N-1];\n                grid[best_index][N-1] = '.';\n                if (rightmost == 'x') {\n                    oni_set.erase({best_index, N-1});\n                } else if (rightmost == 'o') {\n                    fuku_set.erase({best_index, N-1});\n                }\n\n                for (int c = N-2; c >= 0; c--) {\n                    char c_char = grid[best_index][c];\n                    grid[best_index][c+1] = c_char;\n                    if (c_char == 'x') {\n                        oni_set.erase({best_index, c});\n                        oni_set.insert({best_index, c+1});\n                    } else if (c_char == 'o') {\n                        fuku_set.erase({best_index, c});\n                        fuku_set.insert({best_index, c+1});\n                    }\n                }\n                grid[best_index][0] = '.';\n            }\n        }\n    }\n\n    for (auto move : moves) {\n        cout << move.first << \" \" << move.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    srand(0);\n    int N = 100;\n    int L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<long long, int>> candidates;\n        for (int j = 0; j < N; j++) {\n            if (j == i) continue;\n            candidates.push_back({T[j], j});\n        }\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, int>>());\n        if (candidates.size() >= 2) {\n            a[i] = candidates[0].second;\n            b[i] = candidates[1].second;\n        } else if (candidates.size() == 1) {\n            a[i] = candidates[0].second;\n            b[i] = i;\n        } else {\n            a[i] = i;\n            b[i] = i;\n        }\n    }\n\n    auto simulate = [&](const vector<int>& a_vec, const vector<int>& b_vec) {\n        vector<long long> count(N, 0);\n        int current = 0;\n        count[0] = 1;\n        for (int week = 1; week < L; week++) {\n            int next;\n            if (count[current] & 1) {\n                next = a_vec[current];\n            } else {\n                next = b_vec[current];\n            }\n            count[next]++;\n            current = next;\n        }\n        long long error = 0;\n        for (int i = 0; i < N; i++) {\n            error += abs(count[i] - T[i]);\n        }\n        return error;\n    };\n\n    long long best_error = simulate(a, b);\n    vector<int> best_a = a;\n    vector<int> best_b = b;\n\n    for (int iter = 0; iter < 100; iter++) {\n        int i = rand() % N;\n        int old_a = a[i];\n        int old_b = b[i];\n\n        a[i] = rand() % N;\n        b[i] = rand() % N;\n\n        long long new_error = simulate(a, b);\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n        } else {\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <iomanip>\n#include <sstream>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\n\nstruct City {\n    int id;\n    double cx, cy;  // estimated center coordinates\n    int lx, rx, ly, ry;  // given rectangle bounds\n    double uncertainty;  // size of the rectangle, representing uncertainty\n};\n\nstruct Edge {\n    int u, v;\n    int weight;  // estimated or actual weight\n    double estimated_dist;  // estimated distance based on center coordinates\n    \n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nstruct QueryResult {\n    vector<pair<int, int>> edges;  // edges in the MST\n};\n\nclass Solution {\npublic:\n    int N, M, Q, L, W;\n    vector<int> G;\n    vector<City> cities;\n    vector<vector<int>> groups;\n    vector<vector<Edge>> group_edges;\n    int query_count = 0;\n    \n    void read_input() {\n        cin >> N >> M >> Q >> L >> W;\n        G.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> G[i];\n        }\n        \n        cities.resize(N);\n        for (int i = 0; i < N; i++) {\n            cities[i].id = i;\n            cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n            cities[i].cx = (cities[i].lx + cities[i].rx) / 2.0;\n            cities[i].cy = (cities[i].ly + cities[i].ry) / 2.0;\n            // Calculate uncertainty as the diagonal of the rectangle\n            cities[i].uncertainty = sqrt(pow(cities[i].rx - cities[i].lx, 2) + \n                                        pow(cities[i].ry - cities[i].ly, 2));\n        }\n    }\n    \n    double estimated_distance(int i, int j) {\n        double dx = cities[i].cx - cities[j].cx;\n        double dy = cities[i].cy - cities[j].cy;\n        return sqrt(dx * dx + dy * dy);\n    }\n    \n    void group_cities() {\n        // Sort cities by their estimated center coordinates\n        vector<int> city_ids(N);\n        for (int i = 0; i < N; i++) {\n            city_ids[i] = i;\n        }\n        \n        // We'll use a simple approach: divide the sorted list into groups of the required sizes\n        sort(city_ids.begin(), city_ids.end(), [this](int a, int b) {\n            if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n            return cities[a].cy < cities[b].cy;\n        });\n        \n        // Divide into groups of specified sizes\n        groups.resize(M);\n        int start_idx = 0;\n        for (int i = 0; i < M; i++) {\n            groups[i].resize(G[i]);\n            for (int j = 0; j < G[i]; j++) {\n                groups[i][j] = city_ids[start_idx + j];\n            }\n            start_idx += G[i];\n        }\n    }\n    \n    QueryResult query_mst(const vector<int>& city_subset) {\n        assert(city_subset.size() >= 2 && city_subset.size() <= L);\n        assert(query_count < Q);\n        \n        cout << \"? \" << city_subset.size();\n        for (int city : city_subset) {\n            cout << \" \" << city;\n        }\n        cout << endl;\n        cout.flush();\n        \n        QueryResult result;\n        result.edges.resize(city_subset.size() - 1);\n        for (int i = 0; i < city_subset.size() - 1; i++) {\n            cin >> result.edges[i].first >> result.edges[i].second;\n            if (result.edges[i].first > result.edges[i].second) {\n                swap(result.edges[i].first, result.edges[i].second);\n            }\n        }\n        \n        query_count++;\n        return result;\n    }\n    \n    void gather_mst_info() {\n        group_edges.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            // For each group, perform queries to gather MST information\n            int group_size = G[i];\n            \n            // If the group is small enough, query the entire group at once\n            if (group_size <= L) {\n                vector<int> subset = groups[i];\n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n                continue;\n            }\n            \n            // For larger groups, we'll use a more sophisticated approach\n            // First, sort cities within the group by their estimated positions\n            vector<int> sorted_group = groups[i];\n            sort(sorted_group.begin(), sorted_group.end(), [this](int a, int b) {\n                if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n                return cities[a].cy < cities[b].cy;\n            });\n            \n            // We'll create a list of potential edges, sorted by estimated distance\n            vector<pair<double, pair<int, int>>> potential_edges;\n            for (int u = 0; u < group_size; u++) {\n                for (int v = u + 1; v < group_size; v++) {\n                    double dist = estimated_distance(sorted_group[u], sorted_group[v]);\n                    potential_edges.emplace_back(dist, make_pair(u, v));\n                }\n            }\n            \n            sort(potential_edges.begin(), potential_edges.end());\n            \n            // We'll select subsets for querying based on the shortest potential edges\n            set<int> selected_cities;\n            vector<vector<int>> subsets;\n            \n            // Start with the cities connected by the shortest edges\n            for (const auto& [dist, edge] : potential_edges) {\n                if (query_count >= Q) break;\n                \n                int u = edge.first;\n                int v = edge.second;\n                \n                // If both cities are already in a subset, skip\n                if (selected_cities.count(u) && selected_cities.count(v)) continue;\n                \n                // Create a new subset containing these cities and some nearby ones\n                vector<int> subset;\n                subset.push_back(sorted_group[u]);\n                subset.push_back(sorted_group[v]);\n                selected_cities.insert(u);\n                selected_cities.insert(v);\n                \n                // Add nearby cities until we reach the maximum subset size\n                for (const auto& [dist2, edge2] : potential_edges) {\n                    if (subset.size() >= L) break;\n                    \n                    int u2 = edge2.first;\n                    int v2 = edge2.second;\n                    \n                    if (u2 == u || u2 == v || v2 == u || v2 == v) {\n                        int new_city = (selected_cities.count(u2) == 0) ? u2 : v2;\n                        if (selected_cities.count(new_city) == 0) {\n                            subset.push_back(sorted_group[new_city]);\n                            selected_cities.insert(new_city);\n                        }\n                    }\n                }\n                \n                subsets.push_back(subset);\n                \n                // If we've selected all cities, we're done\n                if (selected_cities.size() >= group_size) break;\n            }\n            \n            // If we haven't selected all cities, add the remaining ones\n            for (int j = 0; j < group_size; j++) {\n                if (selected_cities.count(j) == 0) {\n                    // Create a subset with this city and some nearby ones\n                    vector<int> subset;\n                    subset.push_back(sorted_group[j]);\n                    selected_cities.insert(j);\n                    \n                    // Add the closest cities\n                    for (const auto& [dist, edge] : potential_edges) {\n                        if (subset.size() >= L) break;\n                        \n                        int u = edge.first;\n                        int v = edge.second;\n                        \n                        if (u == j || v == j) {\n                            int other = (u == j) ? v : u;\n                            if (selected_cities.count(other) == 0) {\n                                subset.push_back(sorted_group[other]);\n                                selected_cities.insert(other);\n                            }\n                        }\n                    }\n                    \n                    subsets.push_back(subset);\n                }\n            }\n            \n            // Query each subset\n            for (const auto& subset : subsets) {\n                if (query_count >= Q) break;\n                if (subset.size() < 2) continue;\n                \n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n            }\n            \n            if (query_count >= Q) break;  // We've used all our queries\n        }\n    }\n    \n    void construct_final_msts() {\n        // For each group, we'll use the edges we've gathered to construct a connected graph\n        // If we don't have enough edges to form a spanning tree, we'll add more\n        \n        for (int i = 0; i < M; i++) {\n            // We need G[i] - 1 edges to connect G[i] cities\n            \n            // First, let's create a graph from the edges we've gathered\n            vector<vector<int>> graph(G[i]);\n            map<pair<int, int>, int> edge_to_index;\n            \n            for (int j = 0; j < group_edges[i].size(); j++) {\n                const Edge& e = group_edges[i][j];\n                int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                \n                graph[u_idx].push_back(v_idx);\n                graph[v_idx].push_back(u_idx);\n                \n                edge_to_index[{min(u_idx, v_idx), max(u_idx, v_idx)}] = j;\n            }\n            \n            // Check if the graph is connected\n            vector<bool> visited(G[i], false);\n            queue<int> q;\n            q.push(0);\n            visited[0] = true;\n            int visited_count = 1;\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                for (int v : graph[u]) {\n                    if (!visited[v]) {\n                        visited[v] = true;\n                        visited_count++;\n                        q.push(v);\n                    }\n                }\n            }\n            \n            if (visited_count == G[i]) {\n                // The graph is already connected, so we can use a subset of the edges\n                // We'll use Kruskal's algorithm to find the MST\n                vector<Edge> mst_edges;\n                vector<int> parent(G[i]);\n                for (int j = 0; j < G[i]; j++) {\n                    parent[j] = j;\n                }\n                \n                function<int(int)> find = [&](int x) {\n                    if (parent[x] != x) {\n                        parent[x] = find(parent[x]);\n                    }\n                    return parent[x];\n                };\n                \n                auto unite = [&](int x, int y) {\n                    x = find(x);\n                    y = find(y);\n                    if (x != y) {\n                        parent[x] = y;\n                        return true;\n                    }\n                    return false;\n                };\n                \n                // Sort edges by estimated distance\n                sort(group_edges[i].begin(), group_edges[i].end(), \n                    [](const Edge& a, const Edge& b) {\n                        return a.estimated_dist < b.estimated_dist;\n                    });\n                \n                for (const Edge& e : group_edges[i]) {\n                    int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                    int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                    \n                    if (unite(u_idx, v_idx)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == G[i] - 1) break;\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            } else {\n                // The graph is not connected, so we need to add more edges\n                // We'll use Prim's algorithm starting from the visited component\n                \n                // First, let's create a complete graph with estimated distances\n                vector<vector<pair<int, double>>> complete_graph(G[i]);\n                for (int u = 0; u < G[i]; u++) {\n                    for (int v = u + 1; v < G[i]; v++) {\n                        double dist = estimated_distance(groups[i][u], groups[i][v]);\n                        complete_graph[u].emplace_back(v, dist);\n                        complete_graph[v].emplace_back(u, dist);\n                    }\n                }\n                \n                // Use Prim's algorithm to find the MST\n                vector<bool> in_mst(G[i], false);\n                vector<Edge> mst_edges;\n                priority_queue<pair<double, pair<int, int>>, \n                              vector<pair<double, pair<int, int>>>, \n                              greater<pair<double, pair<int, int>>>> pq;\n                \n                // Start with the visited component\n                for (int u = 0; u < G[i]; u++) {\n                    if (visited[u]) {\n                        in_mst[u] = true;\n                        for (const auto& [v, dist] : complete_graph[u]) {\n                            if (!in_mst[v]) {\n                                pq.emplace(dist, make_pair(u, v));\n                            }\n                        }\n                    }\n                }\n                \n                while (!pq.empty() && mst_edges.size() < G[i] - 1) {\n                    auto [dist, edge] = pq.top();\n                    pq.pop();\n                    int u = edge.first;\n                    int v = edge.second;\n                    \n                    if (!in_mst[v]) {\n                        in_mst[v] = true;\n                        Edge e;\n                        e.u = groups[i][u];\n                        e.v = groups[i][v];\n                        e.weight = 0;\n                        e.estimated_dist = dist;\n                        mst_edges.push_back(e);\n                        \n                        for (const auto& [next_v, next_dist] : complete_graph[v]) {\n                            if (!in_mst[next_v]) {\n                                pq.emplace(next_dist, make_pair(v, next_v));\n                            }\n                        }\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            }\n        }\n    }\n    \n    void output_solution() {\n        cout << \"!\" << endl;\n        \n        for (int i = 0; i < M; i++) {\n            // Output the cities in the group\n            for (int j = 0; j < G[i]; j++) {\n                if (j > 0) cout << \" \";\n                cout << groups[i][j];\n            }\n            cout << endl;\n            \n            // Output the edges\n            for (const auto& edge : group_edges[i]) {\n                cout << edge.u << \" \" << edge.v << endl;\n            }\n        }\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        group_cities();\n        gather_mst_info();\n        construct_final_msts();\n        output_solution();\n    }\n};\n\nint main() {\n    Solution solution;\n    solution.solve();\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <array>\n#include <string>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int MAX_ACTIONS = 2 * N * M;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> blocks;\n    vector<string> actions;\n    int remaining_actions;\n    \n    State(int i, int j, int budget = MAX_ACTIONS) : i(i), j(j), blocks(N, vector<bool>(N, false)), remaining_actions(budget) {}\n    \n    bool is_valid(int ni, int nj) const {\n        return ni >= 0 && ni < N && nj >= 0 && nj < N;\n    }\n    \n    bool can_move(int dir) const {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        return is_valid(ni, nj) && !blocks[ni][nj];\n    }\n    \n    State move(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        new_state.i += di[dir];\n        new_state.j += dj[dir];\n        new_state.actions.push_back(string(1, 'M') + dir_chars[dir]);\n        new_state.remaining_actions--;\n        return new_state;\n    }\n    \n    pair<State, int> slide(int dir) const {\n        if (remaining_actions <= 0) return {*this, 0};\n        State new_state = *this;\n        int ni = i, nj = j;\n        int steps = 0;\n        \n        while (true) {\n            int nni = ni + di[dir];\n            int nnj = nj + dj[dir];\n            \n            if (!is_valid(nni, nnj) || blocks[nni][nnj]) {\n                break;\n            }\n            \n            ni = nni;\n            nj = nnj;\n            steps++;\n        }\n        \n        if (steps > 0) {\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.actions.push_back(string(1, 'S') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return {new_state, steps};\n    }\n    \n    State alter(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (is_valid(ni, nj)) {\n            new_state.blocks[ni][nj] = !blocks[ni][nj];\n            new_state.actions.push_back(string(1, 'A') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return new_state;\n    }\n    \n    int manhattan_distance(int ti, int tj) const {\n        return abs(i - ti) + abs(j - tj);\n    }\n    \n    vector<string> find_path(int target_i, int target_j) const {\n        if (remaining_actions <= 0) return vector<string>();\n        \n        queue<tuple<int, int, vector<string>>> q;\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n        \n        q.push({i, j, vector<string>()});\n        visited[i][j] = true;\n        \n        while (!q.empty()) {\n            auto [ci, cj, path] = q.front();\n            q.pop();\n            \n            if (ci == target_i && cj == target_j) {\n                vector<string> result;\n                while (ci != i || cj != j) {\n                    auto [pi, pj] = parent[ci][cj];\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (pi + di[dir] == ci && pj + dj[dir] == cj) {\n                            result.push_back(string(1, 'M') + dir_chars[dir]);\n                            break;\n                        }\n                    }\n                    ci = pi;\n                    cj = pj;\n                }\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ci + di[dir];\n                int nj = cj + dj[dir];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj] && !blocks[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent[ni][nj] = {ci, cj};\n                    vector<string> new_path = path;\n                    new_path.push_back(string(1, 'M') + dir_chars[dir]);\n                    q.push({ni, nj, new_path});\n                }\n            }\n        }\n        \n        return vector<string>();\n    }\n    \n    bool try_slide_to_target(int target_i, int target_j) {\n        if (remaining_actions < 10) return false; // Not enough actions for sliding\n        \n        int initial_manhattan = manhattan_distance(target_i, target_j);\n        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n        \n        // Try all directions as primary\n        for (int primary_dir = 0; primary_dir < 4; primary_dir++) {\n            State temp_state = *this;\n            \n            // Slide in primary direction\n            auto [slide_state, slide_steps] = temp_state.slide(primary_dir);\n            temp_state = slide_state;\n            \n            if (temp_state.manhattan_distance(target_i, target_j) >= initial_manhattan) {\n                continue; // No improvement\n            }\n            \n            // Try to place a block to stop at target\n            for (int stop_dir = 0; stop_dir < 4; stop_dir++) {\n                if (stop_dir == primary_dir || stop_dir == (primary_dir ^ 1)) {\n                    continue; // Same or opposite direction\n                }\n                \n                State temp_state2 = temp_state;\n                \n                // Calculate where to place the stopping block\n                int stop_i = target_i + di[stop_dir];\n                int stop_j = target_j + dj[stop_dir];\n                \n                if (temp_state2.is_valid(stop_i, stop_j)) {\n                    // Try to place block if not already there\n                    if (!temp_state2.blocks[stop_i][stop_j]) {\n                        temp_state2 = temp_state2.alter(stop_dir);\n                        \n                        // Try sliding to target\n                        auto [slide_result, steps] = temp_state2.slide(stop_dir);\n                        if (slide_result.i == target_i && slide_result.j == target_j) {\n                            *this = slide_result;\n                            return true;\n                        }\n                        \n                        // If slide didn't reach target, try moving from there\n                        auto path = slide_result.find_path(target_i, target_j);\n                        if (!path.empty() && path.size() <= 5) {\n                            for (const auto& action : path) {\n                                for (int dir = 0; dir < 4; dir++) {\n                                    if (action[1] == dir_chars[dir]) {\n                                        slide_result = slide_result.move(dir);\n                                        break;\n                                    }\n                                }\n                            }\n                            \n                            if (slide_result.i == target_i && slide_result.j == target_j) {\n                                *this = slide_result;\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return false;\n    }\n    \n    void remove_unnecessary_blocks(const vector<pair<int, int>>& future_targets) {\n        // Remove blocks that are not needed for future targets\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (blocks[i][j]) {\n                    bool needed = false;\n                    \n                    // Check if block is near any future target\n                    for (const auto& target : future_targets) {\n                        if (abs(i - target.first) <= 2 && abs(j - target.second) <= 2) {\n                            needed = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!needed) {\n                        // Remove the block\n                        for (int dir = 0; dir < 4; dir++) {\n                            if (i - di[dir] == this->i && j - dj[dir] == this->j) {\n                                *this = alter(dir);\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    void optimize_blocks(const vector<pair<int, int>>& targets, int current_target_idx) {\n        // Only optimize if we have enough actions\n        if (remaining_actions < 50) return;\n        \n        vector<pair<int, int>> future_targets(targets.begin() + current_target_idx + 1, \n                                            targets.begin() + min(current_target_idx + 6, (int)targets.size()));\n        \n        // Remove unnecessary blocks first\n        remove_unnecessary_blocks(future_targets);\n        \n        // Place blocks for future targets only if beneficial\n        for (const auto& target : future_targets) {\n            int target_i = target.first;\n            int target_j = target.second;\n            \n            // Only place blocks if we're far from the target\n            if (manhattan_distance(target_i, target_j) > 5) {\n                // Try to place a block that will help slide to this target\n                for (int dir = 0; dir < 4; dir++) {\n                    int block_i = target_i + di[dir];\n                    int block_j = target_j + dj[dir];\n                    \n                    if (is_valid(block_i, block_j) && !blocks[block_i][block_j]) {\n                        // Check if placing this block would create a good sliding opportunity\n                        int path_cost = manhattan_distance(block_i, block_j) + 2; // Move to adjacent + alter\n                        if (path_cost < manhattan_distance(target_i, target_j) * 0.7) {\n                            auto path = find_path(block_i, block_j);\n                            if (!path.empty() && path.size() <= 5) {\n                                for (const auto& action : path) {\n                                    for (int d = 0; d < 4; d++) {\n                                        if (action[1] == dir_chars[d]) {\n                                            *this = move(d);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                *this = alter(dir);\n                                break; // Only place one block per target\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<pair<int, int>> targets(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    State current(targets[0].first, targets[0].second);\n    \n    for (int k = 1; k < m; k++) {\n        int target_i = targets[k].first;\n        int target_j = targets[k].second;\n        \n        // If we're running low on actions, use BFS only\n        if (current.remaining_actions < 100) {\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n            continue;\n        }\n        \n        int manhattan = current.manhattan_distance(target_i, target_j);\n        \n        // Try sliding for medium to long distances\n        if (manhattan > 3 && current.try_slide_to_target(target_i, target_j)) {\n            // Sliding succeeded, continue\n        } else {\n            // Use BFS for short distances or when sliding fails\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Optimize blocks for future targets\n        current.optimize_blocks(targets, k);\n    }\n    \n    for (const auto& action : current.actions) {\n        cout << action[0] << \" \" << action[1] << '\\n';\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;  // (a, b) and (c, d) are diagonal vertices\n    \n    Rectangle(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {\n        if (a > c) swap(a, c);\n        if (b > d) swap(b, d);\n    }\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(int x, int y) const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n    \n    int overlap_area(const Rectangle& other) const {\n        int overlap_a = max(a, other.a);\n        int overlap_b = max(b, other.b);\n        int overlap_c = min(c, other.c);\n        int overlap_d = min(d, other.d);\n        \n        if (overlap_a >= overlap_c || overlap_b >= overlap_d) return 0;\n        return (overlap_c - overlap_a) * (overlap_d - overlap_b);\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rectangle rect;\n    \n    double satisfaction() const {\n        int s = rect.area();\n        if (!rect.contains(x, y)) return 0.0;\n        \n        double min_val = min(r, s);\n        double max_val = max(r, s);\n        return 1.0 - pow(1.0 - min_val / max_val, 2);\n    }\n};\n\nvector<Rectangle> solve(int n, const vector<pair<int, int>>& points, const vector<int>& rs) {\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        companies[i].x = points[i].first;\n        companies[i].y = points[i].second;\n        companies[i].r = rs[i];\n    }\n    \n    // Sort companies by desired area (largest first)\n    vector<int> indices(n);\n    for (int i = 0; i < n; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return companies[i].r > companies[j].r;\n    });\n    \n    // Create a space-filling curve based initial placement\n    vector<pair<int, int>> space_order;\n    for (int y = 0; y < 100; ++y) {\n        for (int x = 0; x < 100; ++x) {\n            space_order.emplace_back(x, y);\n        }\n    }\n    \n    // Shuffle the space order for better distribution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(space_order.begin(), space_order.end(), rng);\n    \n    // Initialize rectangles\n    vector<Rectangle> placed_rectangles;\n    for (int i : indices) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Find dimensions that give area close to r\n        int w = min(10000, static_cast<int>(sqrt(r)) + 1);\n        int h = r / w;\n        if (w * h < r) h++;\n        \n        // Try to place the rectangle at different positions\n        Rectangle best_rect;\n        double best_score = -1.0;\n        \n        // Try positions based on the space order\n        for (const auto& pos : space_order) {\n            int base_x = pos.first * 100;\n            int base_y = pos.second * 100;\n            \n            // Try to place the rectangle with the desired point inside\n            int a = max(0, min(base_x, x - w/2));\n            int c = min(10000, a + w);\n            if (c - a < w) a = c - w;\n            \n            int b = max(0, min(base_y, y - h/2));\n            int d = min(10000, b + h);\n            if (d - b < h) b = d - h;\n            \n            Rectangle rect(a, b, c, d);\n            \n            // Check if the rectangle contains the desired point\n            if (!rect.contains(x, y)) continue;\n            \n            // Check for overlaps with already placed rectangles\n            bool has_overlap = false;\n            for (const auto& placed : placed_rectangles) {\n                if (rect.overlaps(placed)) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            \n            if (!has_overlap) {\n                // Calculate a score based on how close the area is to the desired area\n                int area = rect.area();\n                double score = 1.0 - abs(area - r) / max(area, r);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect;\n                }\n            }\n        }\n        \n        // If we couldn't find a non-overlapping position, use a minimal rectangle\n        if (best_score < 0) {\n            best_rect = Rectangle(x, y, x + 1, y + 1);\n        }\n        \n        companies[i].rect = best_rect;\n        placed_rectangles.push_back(best_rect);\n    }\n    \n    // Resolve overlaps iteratively\n    const int MAX_ITERATIONS = 100;\n    for (int iter = 0; iter < MAX_ITERATIONS; ++iter) {\n        bool has_overlap = false;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = i + 1; j < n; ++j) {\n                if (companies[i].rect.overlaps(companies[j].rect)) {\n                    has_overlap = true;\n                    \n                    // Calculate overlap area\n                    int overlap_area = companies[i].rect.overlap_area(companies[j].rect);\n                    \n                    // Resolve overlap by shrinking the rectangle with smaller desired area\n                    if (companies[i].r < companies[j].r) {\n                        // Shrink company i's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_i.a < rect_j.a) {\n                                rect_i.c = min(rect_i.c, rect_j.a);\n                            } else {\n                                rect_i.a = max(rect_i.a, rect_j.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_i.b < rect_j.b) {\n                                rect_i.d = min(rect_i.d, rect_j.b);\n                            } else {\n                                rect_i.b = max(rect_i.b, rect_j.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                            // Try a different approach\n                            rect_i = companies[i].rect;\n                            if (rect_j.a < rect_i.a) {\n                                rect_i.a = rect_j.c;\n                            } else {\n                                rect_i.c = rect_j.a;\n                            }\n                            \n                            if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_i = Rectangle(companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1);\n                            }\n                        }\n                    } else {\n                        // Shrink company j's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_j.a < rect_i.a) {\n                                rect_j.c = min(rect_j.c, rect_i.a);\n                            } else {\n                                rect_j.a = max(rect_j.a, rect_i.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_j.b < rect_i.b) {\n                                rect_j.d = min(rect_j.d, rect_i.b);\n                            } else {\n                                rect_j.b = max(rect_j.b, rect_i.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                            // Try a different approach\n                            rect_j = companies[j].rect;\n                            if (rect_i.a < rect_j.a) {\n                                rect_j.a = rect_i.c;\n                            } else {\n                                rect_j.c = rect_i.a;\n                            }\n                            \n                            if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_j = Rectangle(companies[j].x, companies[j].y, companies[j].x + 1, companies[j].y + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!has_overlap) break;\n    }\n    \n    // Final optimization using simulated annealing\n    rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n    double temperature = 100.0;\n    const double COOLING_RATE = 0.95;\n    const int SA_ITERATIONS = 1000;\n    \n    double current_score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        current_score += companies[i].satisfaction();\n    }\n    \n    for (int iter = 0; iter < SA_ITERATIONS; ++iter) {\n        temperature *= COOLING_RATE;\n        \n        // Choose a random company to modify\n        int i = rng() % n;\n        Rectangle old_rect = companies[i].rect;\n        double old_satisfaction = companies[i].satisfaction();\n        \n        // Choose a random modification\n        int mod_type = rng() % 8;\n        \n        switch (mod_type) {\n            case 0: {  // Move left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                companies[i].rect.c -= delta;\n                break;\n            }\n            case 1: {  // Move right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.a += delta;\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 2: {  // Move up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                companies[i].rect.d -= delta;\n                break;\n            }\n            case 3: {  // Move down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.b += delta;\n                companies[i].rect.d += delta;\n                break;\n            }\n            case 4: {  // Expand left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                break;\n            }\n            case 5: {  // Expand right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 6: {  // Expand up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                break;\n            }\n            case 7: {  // Expand down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.d += delta;\n                break;\n            }\n        }\n        \n        // Check constraints\n        bool valid = true;\n        \n        // Check if the rectangle still contains the desired point\n        if (!companies[i].rect.contains(companies[i].x, companies[i].y)) {\n            valid = false;\n        }\n        \n        // Check for overlaps\n        if (valid) {\n            for (int j = 0; j < n; ++j) {\n                if (i != j && companies[i].rect.overlaps(companies[j].rect)) {\n                    valid = false;\n                    break;\n                }\n            }\n        }\n        \n        if (valid) {\n            double new_satisfaction = companies[i].satisfaction();\n            double delta_score = new_satisfaction - old_satisfaction;\n            \n            // Accept or reject the move based on simulated annealing\n            if (delta_score > 0 || exp(delta_score / temperature) > (rng() % 1000) / 1000.0) {\n                current_score += delta_score;\n            } else {\n                companies[i].rect = old_rect;\n            }\n        } else {\n            companies[i].rect = old_rect;\n        }\n    }\n    \n    // Extract the final rectangles\n    vector<Rectangle> result;\n    for (int i = 0; i < n; ++i) {\n        result.push_back(companies[i].rect);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<pair<int, int>> points(n);\n    vector<int> rs(n);\n    \n    for (int i = 0; i < n; ++i) {\n        cin >> points[i].first >> points[i].second >> rs[i];\n    }\n    \n    vector<Rectangle> solution = solve(n, points, rs);\n    \n    for (const auto& rect : solution) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Tile {\n    int id;\n    vector<pair<int, int>> squares;\n    int total_value;\n    set<int> adjacent_tiles;\n    bool is_1x1;\n    pair<int, int> other_square;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tiles(50, vector<int>(50));\n    vector<vector<int>> points(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tiles[i][j];\n        }\n    }\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> points[i][j];\n        }\n    }\n    \n    // Build tile information\n    map<int, Tile> tile_map;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int tile_id = tiles[i][j];\n            if (tile_map.find(tile_id) == tile_map.end()) {\n                tile_map[tile_id] = {tile_id, {}, 0, {}, true, {-1, -1}};\n            }\n            tile_map[tile_id].squares.emplace_back(i, j);\n            tile_map[tile_id].total_value += points[i][j];\n        }\n    }\n    \n    // Determine tile types and other square\n    for (auto& [id, tile] : tile_map) {\n        if (tile.squares.size() == 2) {\n            tile.is_1x1 = false;\n            if (tile.squares[0].first == tile.squares[1].first) {\n                // 1x2 tile\n                if (tile.squares[0].second < tile.squares[1].second) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            } else {\n                // 2x1 tile\n                if (tile.squares[0].first < tile.squares[1].first) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            }\n        }\n    }\n    \n    // Build adjacency information\n    for (auto& [id, tile] : tile_map) {\n        for (auto& [i, j] : tile.squares) {\n            vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n            for (auto& [di, dj] : directions) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int neighbor_tile_id = tiles[ni][nj];\n                    if (neighbor_tile_id != id) {\n                        tile.adjacent_tiles.insert(neighbor_tile_id);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Start tile\n    int start_tile_id = tiles[si][sj];\n    set<int> visited_tiles;\n    visited_tiles.insert(start_tile_id);\n    int current_i = si, current_j = sj;\n    string path;\n    \n    // If starting tile is 1x2 or 2x1, move to the other square\n    if (!tile_map[start_tile_id].is_1x1) {\n        auto [oi, oj] = tile_map[start_tile_id].other_square;\n        if (oi < current_i) {\n            path += 'U';\n            current_i = oi;\n        } else if (oi > current_i) {\n            path += 'D';\n            current_i = oi;\n        } else if (oj < current_j) {\n            path += 'L';\n            current_j = oj;\n        } else if (oj > current_j) {\n            path += 'R';\n            current_j = oj;\n        }\n    }\n    \n    // Greedy walk with probabilistic selection\n    random_device rd;\n    mt19937 gen(rd());\n    \n    while (true) {\n        vector<pair<int, pair<char, pair<int, int>>>> candidates;\n        \n        vector<pair<char, pair<int, int>>> directions = {\n            {'U', {-1, 0}}, {'D', {1, 0}}, {'L', {0, -1}}, {'R', {0, 1}}\n        };\n        \n        for (auto& [dir, delta] : directions) {\n            int ni = current_i + delta.first;\n            int nj = current_j + delta.second;\n            \n            if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                int next_tile_id = tiles[ni][nj];\n                \n                if (visited_tiles.find(next_tile_id) == visited_tiles.end()) {\n                    int score = tile_map[next_tile_id].total_value;\n                    \n                    // Consider connectivity\n                    int adjacent_unvisited = 0;\n                    for (int adj_id : tile_map[next_tile_id].adjacent_tiles) {\n                        if (visited_tiles.find(adj_id) == visited_tiles.end()) {\n                            adjacent_unvisited++;\n                        }\n                    }\n                    \n                    score += adjacent_unvisited * 10;  // Weight for connectivity\n                    candidates.emplace_back(score, make_pair(dir, make_pair(ni, nj)));\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Probabilistic selection\n        vector<double> probabilities;\n        for (int i = 0; i < candidates.size(); ++i) {\n            probabilities.push_back(pow(0.8, i));\n        }\n        \n        double sum_probs = accumulate(probabilities.begin(), probabilities.end(), 0.0);\n        for (double& prob : probabilities) {\n            prob /= sum_probs;\n        }\n        \n        uniform_real_distribution<> dis(0.0, 1.0);\n        double r = dis(gen);\n        double cumulative = 0.0;\n        int selected_idx = 0;\n        \n        for (int i = 0; i < probabilities.size(); ++i) {\n            cumulative += probabilities[i];\n            if (r <= cumulative) {\n                selected_idx = i;\n                break;\n            }\n        }\n        \n        auto& [score, move_info] = candidates[selected_idx];\n        auto& [dir, next_pos] = move_info;\n        auto& [ni, nj] = next_pos;\n        \n        int next_tile_id = tiles[ni][nj];\n        \n        path += dir;\n        visited_tiles.insert(next_tile_id);\n        current_i = ni;\n        current_j = nj;\n        \n        // If tile is 1x2 or 2x1, move to the other square\n        if (!tile_map[next_tile_id].is_1x1) {\n            auto [oi, oj] = tile_map[next_tile_id].other_square;\n            if (oi != ni || oj != nj) {\n                if (oi < ni) {\n                    path += 'U';\n                    current_i = oi;\n                } else if (oi > ni) {\n                    path += 'D';\n                    current_i = oi;\n                } else if (oj < nj) {\n                    path += 'L';\n                    current_j = oj;\n                } else if (oj > nj) {\n                    path += 'R';\n                    current_j = oj;\n                }\n            }\n        }\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <functional>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\nint main() {\n    vector<vector<double>> hor_est(N, vector<double>(N-1, 5000.0));\n    vector<vector<double>> ver_est(N-1, vector<double>(N, 5000.0));\n\n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        vector<vector<double>> dist(N, vector<double>(N, 1e18));\n        vector<vector<tuple<int, int, char>>> parent(N, vector<tuple<int, int, char>>(N, make_tuple(-1, -1, ' ')));\n        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (i == ti && j == tj) {\n                break;\n            }\n            if (d > dist[i][j]) {\n                continue;\n            }\n\n            if (i > 0) {\n                double w = ver_est[i-1][j];\n                if (d + w < dist[i-1][j]) {\n                    dist[i-1][j] = d + w;\n                    parent[i-1][j] = make_tuple(i, j, 'U');\n                    pq.push({dist[i-1][j], i-1, j});\n                }\n            }\n            if (i < N-1) {\n                double w = ver_est[i][j];\n                if (d + w < dist[i+1][j]) {\n                    dist[i+1][j] = d + w;\n                    parent[i+1][j] = make_tuple(i, j, 'D');\n                    pq.push({dist[i+1][j], i+1, j});\n                }\n            }\n            if (j > 0) {\n                double w = hor_est[i][j-1];\n                if (d + w < dist[i][j-1]) {\n                    dist[i][j-1] = d + w;\n                    parent[i][j-1] = make_tuple(i, j, 'L');\n                    pq.push({dist[i][j-1], i, j-1});\n                }\n            }\n            if (j < N-1) {\n                double w = hor_est[i][j];\n                if (d + w < dist[i][j+1]) {\n                    dist[i][j+1] = d + w;\n                    parent[i][j+1] = make_tuple(i, j, 'R');\n                    pq.push({dist[i][j+1], i, j+1});\n                }\n            }\n        }\n\n        string path_str = \"\";\n        int i = ti, j = tj;\n        while (i != si || j != sj) {\n            auto [pi, pj, dir] = parent[i][j];\n            path_str += dir;\n            i = pi;\n            j = pj;\n        }\n        reverse(path_str.begin(), path_str.end());\n\n        cout << path_str << endl;\n        cout.flush();\n\n        int y;\n        cin >> y;\n\n        double L_est = 0.0;\n        vector<double*> edges_in_path;\n        i = si; j = sj;\n        for (char c : path_str) {\n            if (c == 'U') {\n                L_est += ver_est[i-1][j];\n                edges_in_path.push_back(&ver_est[i-1][j]);\n                i--;\n            } else if (c == 'D') {\n                L_est += ver_est[i][j];\n                edges_in_path.push_back(&ver_est[i][j]);\n                i++;\n            } else if (c == 'L') {\n                L_est += hor_est[i][j-1];\n                edges_in_path.push_back(&hor_est[i][j-1]);\n                j--;\n            } else if (c == 'R') {\n                L_est += hor_est[i][j];\n                edges_in_path.push_back(&hor_est[i][j]);\n                j++;\n            }\n        }\n\n        int m = edges_in_path.size();\n        double error = y - L_est;\n        for (double* ptr : edges_in_path) {\n            *ptr += 0.1 * error / m;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <array>\n#include <cassert>\n\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int FIXED_N = 20;\nconstexpr char EMPTY = '.';\nconstexpr array<char, 8> CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Problem {\n    int N;\n    int M;\n    vector<string> strings;\n    vector<vector<array<int, 8>>> char_freq;\n    vector<int> string_importance;\n    \n    Problem(int N, int M, const vector<string>& strings) : N(N), M(M), strings(strings) {\n        assert(N == FIXED_N);\n        char_freq.resize(N);\n        for (int i = 0; i < N; i++) {\n            char_freq[i].resize(N);\n            for (int j = 0; j < N; j++) {\n                char_freq[i][j].fill(0);\n            }\n        }\n        \n        string_importance.resize(M);\n        for (int i = 0; i < M; i++) {\n            string_importance[i] = strings[i].size();\n        }\n        \n        for (int idx = 0; idx < M; idx++) {\n            const auto& s = strings[idx];\n            int k = s.size();\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int p = 0; p < min(k, N); p++) {\n                        int c = s[p] - 'A';\n                        char_freq[i][(j + p) % N][c] += string_importance[idx];\n                        char_freq[(i + p) % N][j][c] += string_importance[idx];\n                    }\n                }\n            }\n        }\n    }\n};\n\nstruct Solution {\n    const Problem* problem;\n    vector<string> matrix;\n    vector<bool> satisfied;\n    int score;\n    int satisfied_count;\n    int empty_count;\n    \n    Solution(const Problem& problem) : problem(&problem), matrix(problem.N, string(problem.N, EMPTY)), \n                                      satisfied(problem.M, false), score(0), satisfied_count(0), \n                                      empty_count(problem.N * problem.N) {}\n    \n    Solution(const Solution& other) : problem(other.problem), matrix(other.matrix), \n                                      satisfied(other.satisfied), score(other.score), \n                                      satisfied_count(other.satisfied_count), \n                                      empty_count(other.empty_count) {}\n    \n    Solution& operator=(const Solution& other) {\n        if (this != &other) {\n            problem = other.problem;\n            matrix = other.matrix;\n            satisfied = other.satisfied;\n            score = other.score;\n            satisfied_count = other.satisfied_count;\n            empty_count = other.empty_count;\n        }\n        return *this;\n    }\n    \n    bool can_place_string(const string& s, int i, int j, bool horizontal) {\n        int k = s.size();\n        \n        if (horizontal) {\n            for (int p = 0; p < k; p++) {\n                int col = (j + p) % problem->N;\n                if (matrix[i][col] != EMPTY && matrix[i][col] != s[p]) {\n                    return false;\n                }\n            }\n        } else {\n            for (int p = 0; p < k; p++) {\n                int row = (i + p) % problem->N;\n                if (matrix[row][j] != EMPTY && matrix[row][j] != s[p]) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    void place_string(const string& s, int i, int j, bool horizontal) {\n        int k = s.size();\n        \n        if (horizontal) {\n            for (int p = 0; p < k; p++) {\n                int col = (j + p) % problem->N;\n                matrix[i][col] = s[p];\n            }\n        } else {\n            for (int p = 0; p < k; p++) {\n                int row = (i + p) % problem->N;\n                matrix[row][j] = s[p];\n            }\n        }\n    }\n    \n    void fill_based_on_freq() {\n        for (int i = 0; i < problem->N; i++) {\n            for (int j = 0; j < problem->N; j++) {\n                if (matrix[i][j] == EMPTY) {\n                    int max_freq = -1;\n                    char best_char = EMPTY;\n                    for (int c = 0; c < 8; c++) {\n                        if (problem->char_freq[i][j][c] > max_freq) {\n                            max_freq = problem->char_freq[i][j][c];\n                            best_char = 'A' + c;\n                        }\n                    }\n                    if (best_char != EMPTY) {\n                        matrix[i][j] = best_char;\n                    }\n                }\n            }\n        }\n        empty_count = 0;\n    }\n    \n    bool is_subsequence(const string& s) const {\n        int k = s.size();\n        \n        for (int i = 0; i < problem->N; i++) {\n            for (int j = 0; j < problem->N; j++) {\n                bool match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[i][(j + p) % problem->N] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n                \n                match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[(i + p) % problem->N][j] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    int calculate_score() {\n        satisfied_count = 0;\n        for (int i = 0; i < problem->M; i++) {\n            satisfied[i] = is_subsequence(problem->strings[i]);\n            if (satisfied[i]) {\n                satisfied_count++;\n            }\n        }\n        \n        if (satisfied_count < problem->M) {\n            score = static_cast<int>(round(1e8 * static_cast<double>(satisfied_count) / problem->M));\n        } else {\n            score = static_cast<int>(round(1e8 * (2.0 * problem->N * problem->N) / (2.0 * problem->N * problem->N - empty_count)));\n        }\n        \n        return score;\n    }\n    \n    void local_search(int iterations) {\n        uniform_int_distribution<int> pos_dist(0, problem->N-1);\n        uniform_int_distribution<int> char_dist(0, 7);\n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        int current_score = calculate_score();\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Save current state\n            char old_char = EMPTY;\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            \n            if (matrix[i][j] == EMPTY) continue;\n            \n            old_char = matrix[i][j];\n            matrix[i][j] = CHARS[char_dist(rng)];\n            \n            int new_score = calculate_score();\n            \n            if (new_score > current_score) {\n                current_score = new_score;\n            } else {\n                // Revert change\n                matrix[i][j] = old_char;\n            }\n        }\n    }\n    \n    void print() const {\n        for (const auto& row : matrix) {\n            cout << row << endl;\n        }\n    }\n};\n\nSolution solve(const Problem& problem) {\n    Solution solution(problem);\n    \n    // Sort strings by importance (length) descending\n    vector<int> sorted_indices(problem.M);\n    for (int i = 0; i < problem.M; i++) {\n        sorted_indices[i] = i;\n    }\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return problem.string_importance[a] > problem.string_importance[b];\n    });\n    \n    // Try to place the most important strings first\n    uniform_int_distribution<int> pos_dist(0, problem.N-1);\n    uniform_real_distribution<double> real_dist(0.0, 1.0);\n    \n    for (int idx : sorted_indices) {\n        const string& s = problem.strings[idx];\n        int k = s.size();\n        \n        bool placed = false;\n        \n        // Try 10 random positions\n        for (int attempt = 0; attempt < 10; attempt++) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            bool horizontal = real_dist(rng) < 0.5;\n            \n            if (solution.can_place_string(s, i, j, horizontal)) {\n                solution.place_string(s, i, j, horizontal);\n                placed = true;\n                break;\n            }\n        }\n    }\n    \n    // Fill remaining cells based on frequency\n    solution.fill_based_on_freq();\n    \n    // Perform a very limited local search\n    solution.local_search(100);\n    \n    return solution;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    assert(N == FIXED_N);\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Problem problem(N, M, strings);\n    Solution solution = solve(problem);\n    solution.print();\n    \n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <list>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <unordered_map>\n#include <unordered_set>\n#include <string>\n#include <utility>\n#include <array>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    Point(int i_=0, int j_=0) : i(i_), j(j_) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n};\n\nstruct Segment {\n    bool is_horizontal;\n    int fixed_index;\n    int start, end;\n    Segment(bool h, int idx, int s, int e) : is_horizontal(h), fixed_index(idx), start(s), end(e) {}\n    bool operator==(const Segment& other) const {\n        return is_horizontal == other.is_horizontal && fixed_index == other.fixed_index && start == other.start && end == other.end;\n    }\n    bool operator<(const Segment& other) const {\n        if (is_horizontal != other.is_horizontal) return is_horizontal < other.is_horizontal;\n        if (fixed_index != other.fixed_index) return fixed_index < other.fixed_index;\n        if (start != other.start) return start < other.start;\n        return end < other.end;\n    }\n};\n\nvector<Point> dial_shortest_path(const vector<vector<int>>& grid_cost, int N, Point start, Point end) {\n    int max_cost = 9 * N * N;\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n    vector<list<Point>> buckets(max_cost + 1);\n\n    dist[start.i][start.j] = 0;\n    buckets[0].push_back(start);\n\n    for (int idx = 0; idx <= max_cost; idx++) {\n        while (!buckets[idx].empty()) {\n            Point p = buckets[idx].front();\n            buckets[idx].pop_front();\n            if (dist[p.i][p.j] < idx) continue;\n            if (p == end) break;\n            for (auto [di, dj] : {array<int,2>{-1,0}, {1,0}, {0,-1}, {0,1}}) {\n                int ni = p.i + di;\n                int nj = p.j + dj;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid_cost[ni][nj] == -1) continue;\n                int new_cost = dist[p.i][p.j] + grid_cost[ni][nj];\n                if (new_cost < dist[ni][nj]) {\n                    dist[ni][nj] = new_cost;\n                    parent[ni][nj] = p;\n                    if (new_cost <= max_cost) {\n                        buckets[new_cost].push_front(Point(ni, nj));\n                    }\n                }\n            }\n        }\n    }\n\n    vector<Point> path;\n    if (dist[end.i][end.j] == INF) {\n        return path;\n    }\n    Point cur = end;\n    while (cur != start) {\n        path.push_back(cur);\n        cur = parent[cur.i][cur.j];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<int> bipartite_matching(const vector<vector<int>>& graph, int nH, int nV) {\n    vector<int> matchH(nH, -1);\n    vector<int> matchV(nV, -1);\n    vector<bool> visited;\n\n    function<bool(int)> dfs = [&](int u) {\n        visited[u] = true;\n        for (int v : graph[u]) {\n            if (matchV[v] == -1 || (!visited[matchV[v]] && dfs(matchV[v]))) {\n                matchH[u] = v;\n                matchV[v] = u;\n                return true;\n            }\n        }\n        return false;\n    };\n\n    for (int u = 0; u < nH; u++) {\n        visited.assign(nH, false);\n        dfs(u);\n    }\n\n    vector<int> matching(nH, -1);\n    for (int u = 0; u < nH; u++) {\n        if (matchH[u] != -1) {\n            matching[u] = matchH[u];\n        }\n    }\n    return matching;\n}\n\nvector<Segment> konig_vertex_cover(const vector<vector<int>>& graph, const vector<int>& matching, int nH, int nV) {\n    vector<vector<int>> residual_graph(nH + nV);\n    for (int u = 0; u < nH; u++) {\n        for (int v : graph[u]) {\n            if (matching[u] == v) {\n                residual_graph[nH + v].push_back(u);\n            } else {\n                residual_graph[u].push_back(nH + v);\n            }\n        }\n    }\n\n    vector<bool> marked(nH + nV, false);\n    queue<int> q;\n    for (int u = 0; u < nH; u++) {\n        if (matching[u] == -1) {\n            marked[u] = true;\n            q.push(u);\n        }\n    }\n\n    while (!q.empty()) {\n        int node = q.front();\n        q.pop();\n        for (int neighbor : residual_graph[node]) {\n            if (!marked[neighbor]) {\n                marked[neighbor] = true;\n                q.push(neighbor);\n            }\n        }\n    }\n\n    vector<Segment> vertex_cover;\n    for (int u = 0; u < nH; u++) {\n        if (!marked[u]) {\n            vertex_cover.push_back(Segment(true, u, 0, 0));\n        }\n    }\n    for (int v = 0; v < nV; v++) {\n        if (marked[nH + v]) {\n            vertex_cover.push_back(Segment(false, v, 0, 0));\n        }\n    }\n    return vertex_cover;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid_str[i];\n    }\n\n    vector<vector<int>> grid_cost(N, vector<int>(N, -1));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                grid_cost[i][j] = grid_str[i][j] - '0';\n            }\n        }\n    }\n\n    vector<Segment> h_segments, v_segments;\n    vector<vector<Segment*>> h_segment_ptr(N, vector<Segment*>(N, nullptr));\n    vector<vector<Segment*>> v_segment_ptr(N, vector<Segment*>(N, nullptr));\n\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid_str[i][j] == '#') {\n                j++;\n                continue;\n            }\n            int start = j;\n            while (j < N && grid_str[i][j] != '#') {\n                j++;\n            }\n            int end = j - 1;\n            h_segments.emplace_back(true, i, start, end);\n            Segment* seg = &h_segments.back();\n            for (int k = start; k <= end; k++) {\n                h_segment_ptr[i][k] = seg;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid_str[i][j] == '#') {\n                i++;\n                continue;\n            }\n            int start = i;\n            while (i < N && grid_str[i][j] != '#') {\n                i++;\n            }\n            int end = i - 1;\n            v_segments.emplace_back(false, j, start, end);\n            Segment* seg = &v_segments.back();\n            for (int k = start; k <= end; k++) {\n                v_segment_ptr[k][j] = seg;\n            }\n        }\n    }\n\n    unordered_map<Segment*, int> h_segment_to_id;\n    unordered_map<Segment*, int> v_segment_to_id;\n    for (int i = 0; i < h_segments.size(); i++) {\n        h_segment_to_id[&h_segments[i]] = i;\n    }\n    for (int i = 0; i < v_segments.size(); i++) {\n        v_segment_to_id[&v_segments[i]] = i;\n    }\n\n    vector<vector<int>> bipartite_graph(h_segments.size());\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                Segment* h_seg = h_segment_ptr[i][j];\n                Segment* v_seg = v_segment_ptr[i][j];\n                int h_id = h_segment_to_id[h_seg];\n                int v_id = v_segment_to_id[v_seg];\n                bipartite_graph[h_id].push_back(v_id);\n            }\n        }\n    }\n\n    vector<int> matching = bipartite_matching(bipartite_graph, h_segments.size(), v_segments.size());\n    vector<Segment> vertex_cover_segments = konig_vertex_cover(bipartite_graph, matching, h_segments.size(), v_segments.size());\n\n    Segment* h_start_seg = h_segment_ptr[si][sj];\n    Segment* v_start_seg = v_segment_ptr[si][sj];\n    vector<Segment> segments_to_cover;\n    for (const Segment& seg : vertex_cover_segments) {\n        if (seg.is_horizontal) {\n            if (&h_segments[seg.fixed_index] != h_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        } else {\n            if (&v_segments[seg.fixed_index] != v_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        }\n    }\n\n    vector<Point> candidate_points;\n    for (const Segment& seg : segments_to_cover) {\n        if (seg.is_horizontal) {\n            candidate_points.emplace_back(seg.fixed_index, seg.start);\n        } else {\n            candidate_points.emplace_back(seg.start, seg.fixed_index);\n        }\n    }\n\n    vector<Point> P;\n    P.emplace_back(si, sj);\n    P.insert(P.end(), candidate_points.begin(), candidate_points.end());\n    int total_points = P.size();\n\n    vector<vector<int>> dist_matrix(total_points, vector<int>(total_points, INF));\n    vector<vector<vector<Point>>> paths(total_points, vector<vector<Point>>(total_points));\n\n    for (int i = 0; i < total_points; i++) {\n        vector<Point> path_to_end = dial_shortest_path(grid_cost, N, P[i], P[i]);\n        for (int j = 0; j < total_points; j++) {\n            if (i == j) {\n                dist_matrix[i][j] = 0;\n                paths[i][j] = {P[i]};\n                continue;\n            }\n            vector<Point> path_ij = dial_shortest_path(grid_cost, N, P[i], P[j]);\n            if (path_ij.empty()) {\n                dist_matrix[i][j] = INF;\n                paths[i][j] = {};\n            } else {\n                int total_cost = 0;\n                Point cur = P[i];\n                for (const Point& p : path_ij) {\n                    total_cost += grid_cost[p.i][p.j];\n                }\n                dist_matrix[i][j] = total_cost;\n                paths[i][j] = path_ij;\n            }\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited(total_points, false);\n    visited[0] = true;\n    tour.push_back(0);\n    int current = 0;\n    for (int step = 1; step < total_points; step++) {\n        int best_next = -1;\n        int best_dist = INF;\n        for (int j = 0; j < total_points; j++) {\n            if (!visited[j] && dist_matrix[current][j] < best_dist) {\n                best_dist = dist_matrix[current][j];\n                best_next = j;\n            }\n        }\n        if (best_next == -1) break;\n        visited[best_next] = true;\n        tour.push_back(best_next);\n        current = best_next;\n    }\n    tour.push_back(0);\n\n    vector<Point> full_route;\n    full_route.push_back(P[0]);\n    for (int idx = 0; idx < tour.size() - 1; idx++) {\n        int i = tour[idx];\n        int j = tour[idx+1];\n        if (i == j) continue;\n        vector<Point>& path_segment = paths[i][j];\n        full_route.insert(full_route.end(), path_segment.begin(), path_segment.end());\n    }\n\n    string moves;\n    for (int i = 0; i < full_route.size() - 1; i++) {\n        Point a = full_route[i];\n        Point b = full_route[i+1];\n        if (b.i < a.i) moves += 'U';\n        else if (b.i > a.i) moves += 'D';\n        else if (b.j < a.j) moves += 'L';\n        else if (b.j > a.j) moves += 'R';\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n#include <cstring>\n#include <sys/select.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(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    vector<vector<int>> prerequisites(N);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        prerequisites[v].push_back(u);\n    }\n\n    vector<int> task_status(N, -1);\n    vector<int> member_status(M, -1);\n    vector<int> start_day(N, 0);\n\n    vector<vector<int>> S(M, vector<int>(K, 0));\n\n    int current_day = 1;\n\n    while (true) {\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        vector<int> tokens;\n        char* cstr = new char[line.length() + 1];\n        strcpy(cstr, line.c_str());\n        char* p = strtok(cstr, \" \");\n        while (p != nullptr) {\n            tokens.push_back(atoi(p));\n            p = strtok(nullptr, \" \");\n        }\n        delete[] cstr;\n\n        int n = tokens[0];\n        vector<int> completed_members;\n        for (int i = 1; i <= n; ++i) {\n            completed_members.push_back(tokens[i]);\n        }\n\n        for (int idx = 0; idx < n; ++idx) {\n            int j0 = completed_members[idx];\n            int j = j0 - 1;\n            if (member_status[j] == -1) {\n                continue;\n            }\n            int task_i = member_status[j];\n            task_status[task_i] = 1;\n            member_status[j] = -1;\n\n            int t_taken = current_day - start_day[task_i];\n\n            if (t_taken == 1) {\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        S[j][k] = d[task_i][k];\n                    }\n                }\n            } else {\n                int current_w = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        current_w += d[task_i][k] - S[j][k];\n                    }\n                }\n\n                if (current_w > t_taken + 3) {\n                    int reduction_needed = current_w - (t_taken + 3);\n                    vector<pair<int, int>> deficits;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task_i][k] > S[j][k]) {\n                            int deficit_k = d[task_i][k] - S[j][k];\n                            deficits.emplace_back(deficit_k, k);\n                        }\n                    }\n                    sort(deficits.begin(), deficits.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                        return a.first > b.first;\n                    });\n                    for (auto& def : deficits) {\n                        if (reduction_needed <= 0) break;\n                        int deficit_k = def.first;\n                        int k = def.second;\n                        int increase = min(deficit_k, reduction_needed);\n                        S[j][k] += increase;\n                        reduction_needed -= increase;\n                    }\n                }\n            }\n        }\n\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] != -1) continue;\n            bool available = true;\n            for (int pre : prerequisites[i]) {\n                if (task_status[pre] != 1) {\n                    available = false;\n                    break;\n                }\n            }\n            if (available) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> free_team_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_status[j] == -1) {\n                free_team_members.push_back(j);\n            }\n        }\n\n        vector<pair<int, int>> assignments;\n        if (!available_tasks.empty() && !free_team_members.empty()) {\n            vector<pair<int, int>> task_list;\n            for (int i : available_tasks) {\n                int min_exp = -1;\n                for (int j : free_team_members) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (min_exp == -1 || exp_time < min_exp) {\n                        min_exp = exp_time;\n                    }\n                }\n                task_list.emplace_back(min_exp, i);\n            }\n\n            sort(task_list.begin(), task_list.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                return a.first > b.first;\n            });\n\n            set<int> free_set(free_team_members.begin(), free_team_members.end());\n            for (auto& p : task_list) {\n                if (free_set.empty()) break;\n                int i = p.second;\n                int best_j = -1;\n                int best_exp = -1;\n                for (int j : free_set) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (best_j == -1 || exp_time < best_exp) {\n                        best_j = j;\n                        best_exp = exp_time;\n                    }\n                }\n                assignments.emplace_back(best_j, i);\n                free_set.erase(best_j);\n            }\n        }\n\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        for (auto& p : assignments) {\n            int j = p.first;\n            int i = p.second;\n            task_status[i] = 0;\n            member_status[j] = i;\n            start_day[i] = current_day;\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <set>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Order {\n    int id;\n    int a, b;  // restaurant\n    int c, d;  // destination\n};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    \n    int manhattan_distance(const Point& other) const {\n        return abs(x - other.x) + abs(y - other.y);\n    }\n};\n\nvector<Order> orders;\nvector<int> selected_orders;\nvector<Point> route;\n\nmt19937 rng;\n\nint calculate_total_distance(const vector<Point>& route) {\n    int total = 0;\n    for (size_t i = 0; i < route.size() - 1; i++) {\n        total += route[i].manhattan_distance(route[i + 1]);\n    }\n    return total;\n}\n\nbool is_valid_route(const vector<int>& selected, const vector<Point>& route) {\n    vector<pair<int, int>> positions(1001, {-1, -1});\n    \n    for (size_t i = 0; i < route.size(); i++) {\n        for (int order_id : selected) {\n            const auto& order = orders[order_id];\n            if (route[i].x == order.a && route[i].y == order.b) {\n                if (positions[order_id].first == -1) {\n                    positions[order_id].first = i;\n                }\n            } else if (route[i].x == order.c && route[i].y == order.d) {\n                if (positions[order_id].second == -1) {\n                    positions[order_id].second = i;\n                }\n            }\n        }\n    }\n    \n    for (int order_id : selected) {\n        if (positions[order_id].first == -1 || positions[order_id].second == -1) {\n            return false;\n        }\n        if (positions[order_id].first >= positions[order_id].second) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nvector<Point> construct_greedy_route(const vector<int>& selected) {\n    vector<Point> route = {Point(400, 400)};\n    set<int> remaining_orders(selected.begin(), selected.end());\n    \n    while (!remaining_orders.empty()) {\n        int best_order = -1;\n        int best_pos = -1;\n        int best_increase = 1e9;\n        \n        for (int order_id : remaining_orders) {\n            const auto& order = orders[order_id];\n            \n            // Try inserting restaurant and destination in all possible positions\n            for (size_t i = 0; i <= route.size(); i++) {\n                for (size_t j = i + 1; j <= route.size(); j++) {\n                    vector<Point> temp_route = route;\n                    temp_route.insert(temp_route.begin() + i, Point(order.a, order.b));\n                    temp_route.insert(temp_route.begin() + j, Point(order.c, order.d));\n                    \n                    int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n                    \n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_order = order_id;\n                        best_pos = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_order == -1) break;\n        \n        const auto& best_order_data = orders[best_order];\n        size_t insert_dest_pos = best_pos + 1;\n        \n        // Find best position for destination\n        for (size_t j = best_pos + 1; j <= route.size(); j++) {\n            vector<Point> temp_route = route;\n            temp_route.insert(temp_route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n            temp_route.insert(temp_route.begin() + j, Point(best_order_data.c, best_order_data.d));\n            \n            int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n            \n            if (increase < best_increase) {\n                best_increase = increase;\n                insert_dest_pos = j;\n            }\n        }\n        \n        route.insert(route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n        route.insert(route.begin() + insert_dest_pos, Point(best_order_data.c, best_order_data.d));\n        remaining_orders.erase(best_order);\n    }\n    \n    route.push_back(Point(400, 400));\n    \n    assert(is_valid_route(selected, route));\n    return route;\n}\n\nvector<int> select_initial_orders() {\n    // Calculate center of mass for all orders\n    double center_x = 0, center_y = 0;\n    for (const auto& order : orders) {\n        center_x += (order.a + order.c) / 2.0;\n        center_y += (order.b + order.d) / 2.0;\n    }\n    center_x /= orders.size();\n    center_y /= orders.size();\n    \n    // Calculate distances from center for each order\n    vector<pair<double, int>> order_distances;\n    for (size_t i = 0; i < orders.size(); i++) {\n        const auto& order = orders[i];\n        double mid_x = (order.a + order.c) / 2.0;\n        double mid_y = (order.b + order.d) / 2.0;\n        double dist = abs(mid_x - center_x) + abs(mid_y - center_y);\n        order_distances.emplace_back(dist, i);\n    }\n    \n    // Sort by distance and select the closest 50\n    sort(order_distances.begin(), order_distances.end());\n    vector<int> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(order_distances[i].second);\n    }\n    \n    return selected;\n}\n\nvector<Point> simulated_annealing(const vector<int>& initial_selected, const vector<Point>& initial_route) {\n    vector<int> current_selected = initial_selected;\n    vector<Point> current_route = initial_route;\n    int current_distance = calculate_total_distance(current_route);\n    \n    vector<int> best_selected = current_selected;\n    vector<Point> best_route = current_route;\n    int best_distance = current_distance;\n    \n    const double initial_temp = 1000.0;\n    const double final_temp = 1.0;\n    const int iterations = 100000;\n    \n    double temp = initial_temp;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        temp = initial_temp * pow(final_temp / initial_temp, (double)iter / iterations);\n        \n        // Choose a random operation\n        int operation = uniform_int_distribution<int>(0, 2)(rng);\n        \n        if (operation == 0) {\n            // Swap two points in the route\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            int j = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            \n            if (i == j) continue;\n            \n            vector<Point> new_route = current_route;\n            swap(new_route[i], new_route[j]);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else if (operation == 1) {\n            // Reverse a segment\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 3)(rng);\n            int j = uniform_int_distribution<int>(i + 1, current_route.size() - 2)(rng);\n            \n            vector<Point> new_route = current_route;\n            reverse(new_route.begin() + i, new_route.begin() + j + 1);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else {\n            // Swap an order in the selected set with one not in the set\n            vector<int> unselected;\n            for (size_t i = 0; i < orders.size(); i++) {\n                if (find(current_selected.begin(), current_selected.end(), i) == current_selected.end()) {\n                    unselected.push_back(i);\n                }\n            }\n            \n            if (unselected.empty()) continue;\n            \n            int idx_to_remove = uniform_int_distribution<int>(0, current_selected.size() - 1)(rng);\n            int idx_to_add = uniform_int_distribution<int>(0, unselected.size() - 1)(rng);\n            \n            vector<int> new_selected = current_selected;\n            new_selected[idx_to_remove] = unselected[idx_to_add];\n            sort(new_selected.begin(), new_selected.end());\n            \n            vector<Point> new_route = construct_greedy_route(new_selected);\n            int new_distance = calculate_total_distance(new_route);\n            int delta = new_distance - current_distance;\n            \n            if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_selected = new_selected;\n                current_route = new_route;\n                current_distance = new_distance;\n                \n                if (current_distance < best_distance) {\n                    best_selected = current_selected;\n                    best_route = current_route;\n                    best_distance = current_distance;\n                }\n            }\n        }\n    }\n    \n    return best_route;\n}\n\nvoid solve() {\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n    \n    // Initialize random number generator\n    rng = mt19937(high_resolution_clock::now().time_since_epoch().count());\n    \n    // Select initial orders\n    selected_orders = select_initial_orders();\n    \n    // Construct initial route\n    route = construct_greedy_route(selected_orders);\n    \n    // Optimize with simulated annealing\n    route = simulated_annealing(selected_orders, route);\n    \n    // Output the result\n    cout << selected_orders.size();\n    for (int order_id : selected_orders) {\n        cout << \" \" << order_id + 1;  // Convert to 1-based indexing\n    }\n    cout << endl;\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << endl;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\nusing namespace std;\n\nclass DSU {\nprivate:\n    vector<int> parent;\n    vector<int> rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n\n    void union_set(int x, int y) {\n        int rx = find(x);\n        int ry = find(y);\n        if (rx == ry) {\n            return;\n        }\n        if (rank[rx] < rank[ry]) {\n            parent[rx] = ry;\n        } else if (rank[rx] > rank[ry]) {\n            parent[ry] = rx;\n        } else {\n            parent[ry] = rx;\n            rank[rx]++;\n        }\n    }\n};\n\nstruct Edge {\n    int u, v;\n    double d;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N = 400;\n    int M = 1995;\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        edges[i].index = i;\n        int u = edges[i].u, v = edges[i].v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        edges[i].d = round(dist);\n    }\n\n    vector<int> tree_id(M, -1);\n    vector<Edge> remaining_edges = edges;\n    for (int t = 0; t < 5; t++) {\n        sort(remaining_edges.begin(), remaining_edges.end(), [](const Edge& a, const Edge& b) {\n            return a.d < b.d;\n        });\n\n        DSU dsu_temp(N);\n        vector<Edge> tree_edges;\n        vector<Edge> new_remaining;\n\n        for (Edge& e : remaining_edges) {\n            int u = e.u, v = e.v;\n            if (dsu_temp.find(u) != dsu_temp.find(v)) {\n                dsu_temp.union_set(u, v);\n                tree_edges.push_back(e);\n                tree_id[e.index] = t+1;\n            } else {\n                new_remaining.push_back(e);\n            }\n        }\n\n        remaining_edges = new_remaining;\n    }\n\n    DSU dsu_online(N);\n    vector<vector<int>> comp_edge_count(N, vector<int>(N, 0));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].u, v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n        if (a != b) {\n            comp_edge_count[a][b]++;\n            comp_edge_count[b][a]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n\n        if (a == b) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n\n        comp_edge_count[a][b]--;\n        comp_edge_count[b][a]--;\n\n        bool adopt = false;\n        if (comp_edge_count[a][b] == 0) {\n            adopt = true;\n        } else {\n            double progress = static_cast<double>(i) / M;\n            double base_threshold = 1.0;\n            double max_threshold = 3.0;\n            double factor = (6.0 - tree_id[i]) / 5.0;\n            double threshold = base_threshold + progress * (max_threshold - base_threshold) * factor;\n            if (l_i <= threshold * edges[i].d) {\n                adopt = true;\n            }\n        }\n\n        if (adopt) {\n            int root_a = a;\n            int root_b = b;\n            dsu_online.union_set(u, v);\n            int new_root = dsu_online.find(u);\n            int old_root = (new_root == root_a) ? root_b : root_a;\n\n            for (int c = 0; c < N; c++) {\n                int root_c = dsu_online.find(c);\n                if (root_c != c) continue;\n                if (root_c == new_root) continue;\n                if (comp_edge_count[old_root][root_c] > 0) {\n                    comp_edge_count[new_root][root_c] += comp_edge_count[old_root][root_c];\n                    comp_edge_count[root_c][new_root] += comp_edge_count[root_c][old_root];\n                    comp_edge_count[old_root][root_c] = 0;\n                    comp_edge_count[root_c][old_root] = 0;\n                }\n            }\n\n            cout << 1 << endl;\n            cout.flush();\n        } else {\n            cout << 0 << endl;\n            cout.flush();\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\n#include <cstring>\n#include <iomanip>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\n\nstruct Position {\n    int x, y;\n    Position(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Position& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nbool adjacent(const Position& a, const Position& b) {\n    return (abs(a.x - b.x) + abs(a.y - b.y) == 1);\n}\n\nbool is_buildable(int x, int y, const vector<Position>& pets, const vector<Position>& humans) {\n    for (const auto& pet : pets) {\n        if (pet.x == x && pet.y == y) {\n            return false;\n        }\n    }\n    for (const auto& human : humans) {\n        if (human.x == x && human.y == y) {\n            return false;\n        }\n    }\n\n    vector<pair<int,int>> adj = {{x-1,y}, {x+1,y}, {x,y-1}, {x,y+1}};\n    for (const auto& [ax, ay] : adj) {\n        if (ax < 1 || ax > 30 || ay < 1 || ay > 30) {\n            continue;\n        }\n        for (const auto& pet : pets) {\n            if (pet.x == ax && pet.y == ay) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nbool is_safe_to_move(int x, int y, bool grid[31][31], const set<Position>& building_set) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) {\n        return false;\n    }\n    if (!grid[x][y]) {\n        return false;\n    }\n    if (building_set.find(Position(x,y)) != building_set.end()) {\n        return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M;\n    cin >> N;\n    vector<Position> pets(N);\n    vector<int> pet_types(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n    }\n    cin >> M;\n    vector<Position> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n\n    bool grid[31][31];\n    for (int i = 1; i <= 30; i++) {\n        for (int j = 1; j <= 30; j++) {\n            grid[i][j] = true;\n        }\n    }\n\n    vector<Position> perimeter;\n    for (int y = 10; y <= 20; y++) {\n        perimeter.push_back(Position(10, y));\n    }\n    for (int x = 11; x <= 20; x++) {\n        perimeter.push_back(Position(x, 20));\n    }\n    for (int y = 19; y >= 10; y--) {\n        perimeter.push_back(Position(20, y));\n    }\n    for (int x = 19; x >= 11; x--) {\n        perimeter.push_back(Position(x, 10));\n    }\n\n    vector<queue<Position>> human_queues(M);\n    int segment_size = perimeter.size() / M;\n    int extra = perimeter.size() % M;\n    int index = 0;\n    for (int i = 0; i < M; i++) {\n        int size = segment_size + (i < extra ? 1 : 0);\n        for (int j = 0; j < size; j++) {\n            human_queues[i].push(perimeter[index++]);\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n\n        if (turn < 20) {\n            for (int i = 0; i < M; i++) {\n                int x = humans[i].x;\n                int y = humans[i].y;\n                if (x >= 10 && x <= 20 && y >= 10 && y <= 20) {\n                    actions[i] = '.';\n                } else {\n                    int dx = 15 - x;\n                    int dy = 15 - y;\n                    if (abs(dx) > abs(dy)) {\n                        actions[i] = (dx > 0) ? 'D' : 'U';\n                    } else {\n                        actions[i] = (dy > 0) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            set<Position> building_set;\n            vector<bool> will_build(M, false);\n\n            for (int i = 0; i < M; i++) {\n                if (human_queues[i].empty()) continue;\n                Position target = human_queues[i].front();\n                if (adjacent(humans[i], target) && is_buildable(target.x, target.y, pets, humans)) {\n                    building_set.insert(target);\n                    will_build[i] = true;\n                }\n            }\n\n            for (int i = 0; i < M; i++) {\n                if (will_build[i]) {\n                    Position target = human_queues[i].front();\n                    int dx = humans[i].x - target.x;\n                    int dy = humans[i].y - target.y;\n                    if (dx == -1) actions[i] = 'd';\n                    else if (dx == 1) actions[i] = 'u';\n                    else if (dy == -1) actions[i] = 'r';\n                    else if (dy == 1) actions[i] = 'l';\n                    human_queues[i].pop();\n                } else {\n                    if (human_queues[i].empty()) {\n                        actions[i] = '.';\n                    } else {\n                        Position target = human_queues[i].front();\n                        if (adjacent(humans[i], target)) {\n                            human_queues[i].pop();\n                            human_queues[i].push(target);\n                            actions[i] = '.';\n                        } else {\n                            vector<pair<int,int>> move_deltas = {{-1,0},{1,0},{0,-1},{0,1}};\n                            vector<char> move_dirs = {'U','D','L','R'};\n                            char best_move = '.';\n                            int best_dist = 1000000;\n                            for (int j = 0; j < 4; j++) {\n                                int nx = humans[i].x + move_deltas[j].first;\n                                int ny = humans[i].y + move_deltas[j].second;\n                                if (!is_safe_to_move(nx, ny, grid, building_set)) {\n                                    continue;\n                                }\n                                int d = abs(nx - target.x) + abs(ny - target.y);\n                                if (d < best_dist) {\n                                    best_dist = d;\n                                    best_move = move_dirs[j];\n                                }\n                            }\n                            actions[i] = best_move;\n                        }\n                    }\n                }\n            }\n\n            for (const auto& pos : building_set) {\n                grid[pos.x][pos.y] = false;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == '.') break;\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <climits>\n#include <random>\n#include <unordered_map>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    string path;\n    double priority;\n    \n    bool operator>(const State& other) const {\n        return priority > other.priority;\n    }\n};\n\nvector<string> h_global, v_global;\n\nstring bfs_shortest_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\", 0});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            return s.path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj], 0});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nstring astar_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> g_score(20, vector<int>(20, INT_MAX));\n    vector<vector<int>> f_score(20, vector<int>(20, INT_MAX));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    priority_queue<State, vector<State>, greater<State>> open_set;\n    \n    g_score[si][sj] = 0;\n    f_score[si][sj] = abs(si - ti) + abs(sj - tj);\n    open_set.push({si, sj, \"\", f_score[si][sj]});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!open_set.empty()) {\n        State current = open_set.top();\n        open_set.pop();\n        \n        if (current.i == ti && current.j == tj) {\n            return current.path;\n        }\n        \n        if (current.priority > f_score[current.i][current.j]) {\n            continue;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = current.i + di[d];\n            int nj = current.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (current.i > 0) can_move = (v[current.i-1][current.j] == '0');\n            } else if (d == 1) { // D\n                if (current.i < 19) can_move = (v[current.i][current.j] == '0');\n            } else if (d == 2) { // L\n                if (current.j > 0) can_move = (h[current.i][current.j-1] == '0');\n            } else { // R\n                if (current.j < 19) can_move = (h[current.i][current.j] == '0');\n            }\n            \n            if (!can_move) continue;\n            \n            int tentative_g_score = g_score[current.i][current.j] + 1;\n            \n            if (tentative_g_score < g_score[ni][nj]) {\n                paths[ni][nj] = current.path + dc[d];\n                g_score[ni][nj] = tentative_g_score;\n                f_score[ni][nj] = tentative_g_score + abs(ni - ti) + abs(nj - tj);\n                open_set.push({ni, nj, paths[ni][nj], f_score[ni][nj]});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nstring randomized_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\", 0});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    mt19937 rng(random_device{}());\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            return s.path;\n        }\n        \n        vector<int> dirs = {0, 1, 2, 3};\n        shuffle(dirs.begin(), dirs.end(), rng);\n        \n        for (int d : dirs) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj], 0});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nint count_adjacent_walls(int i, int j, const vector<string>& h, const vector<string>& v) {\n    int walls = 0;\n    if (i == 0 || v[i-1][j] == '1') walls++;\n    if (i == 19 || v[i][j] == '1') walls++;\n    if (j == 0 || h[i][j-1] == '1') walls++;\n    if (j == 19 || h[i][j] == '1') walls++;\n    return walls;\n}\n\ndouble monte_carlo_score(const string& path, const vector<int>& redundancies, int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v, double p, int trials = 1000) {\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \n    double total_score = 0.0;\n    mt19937 rng(random_device{}());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    \n    for (int trial = 0; trial < trials; trial++) {\n        int ci = si, cj = sj;\n        int steps = 0;\n        bool reached = false;\n        int move_idx = 0;\n        int step_in_move = 0;\n        \n        while (steps < 200 && !reached) {\n            if (ci == ti && cj == tj) {\n                reached = true;\n                break;\n            }\n            \n            if (move_idx >= path.size()) {\n                break;\n            }\n            \n            char c = path[move_idx];\n            if (dist(rng) < p) {\n                // Forget, stay in place\n                step_in_move++;\n            } else {\n                // Try to move\n                int ni = ci, nj = cj;\n                bool can_move = false;\n                \n                if (c == 'U') {\n                    if (ci > 0 && v[ci-1][cj] == '0') {\n                        ni = ci - 1;\n                        can_move = true;\n                    }\n                } else if (c == 'D') {\n                    if (ci < 19 && v[ci][cj] == '0') {\n                        ni = ci + 1;\n                        can_move = true;\n                    }\n                } else if (c == 'L') {\n                    if (cj > 0 && h[ci][cj-1] == '0') {\n                        nj = cj - 1;\n                        can_move = true;\n                    }\n                } else if (c == 'R') {\n                    if (cj < 19 && h[ci][cj] == '0') {\n                        nj = cj + 1;\n                        can_move = true;\n                    }\n                }\n                \n                if (can_move) {\n                    ci = ni;\n                    cj = nj;\n                }\n                step_in_move++;\n            }\n            \n            if (step_in_move >= redundancies[move_idx]) {\n                move_idx++;\n                step_in_move = 0;\n            }\n            \n            steps++;\n        }\n        \n        if (reached) {\n            total_score += (401 - steps);\n        }\n    }\n    \n    return total_score / trials;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    h_global = h;\n    v_global = v;\n    \n    vector<string> candidate_paths;\n    \n    string shortest = bfs_shortest_path(si, sj, ti, tj, h, v);\n    if (!shortest.empty()) candidate_paths.push_back(shortest);\n    \n    string astar = astar_path(si, sj, ti, tj, h, v);\n    if (!astar.empty() && astar != shortest) candidate_paths.push_back(astar);\n    \n    for (int i = 0; i < 3; i++) {\n        string rand_path = randomized_path(si, sj, ti, tj, h, v);\n        if (!rand_path.empty() && find(candidate_paths.begin(), candidate_paths.end(), rand_path) == candidate_paths.end()) {\n            candidate_paths.push_back(rand_path);\n        }\n    }\n    \n    if (candidate_paths.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    string best_path = \"\";\n    double best_score = -1;\n    vector<int> best_redundancies;\n    \n    for (const string& path : candidate_paths) {\n        vector<int> redundancies;\n        int total_length = 0;\n        int ci = si, cj = sj;\n        \n        for (char c : path) {\n            int walls = count_adjacent_walls(ci, cj, h, v);\n            int r = 1;\n            while (r <= 10) {\n                double prob = 1.0 - pow(p, r);\n                if (prob >= 0.95) {\n                    break;\n                }\n                r++;\n            }\n            r += walls / 2;\n            if (r > 10) r = 10;\n            redundancies.push_back(r);\n            total_length += r;\n            \n            if (c == 'U' && ci > 0 && v[ci-1][cj] == '0') ci--;\n            else if (c == 'D' && ci < 19 && v[ci][cj] == '0') ci++;\n            else if (c == 'L' && cj > 0 && h[ci][cj-1] == '0') cj--;\n            else if (c == 'R' && cj < 19 && h[ci][cj] == '0') cj++;\n        }\n        \n        if (total_length > 200) {\n            double scale = 200.0 / total_length;\n            vector<int> scaled_redundancies;\n            int scaled_length = 0;\n            for (int r : redundancies) {\n                int new_r = max(1, static_cast<int>(r * scale));\n                scaled_redundancies.push_back(new_r);\n                scaled_length += new_r;\n            }\n            redundancies = scaled_redundancies;\n        }\n        \n        double score = monte_carlo_score(path, redundancies, si, sj, ti, tj, h, v, p);\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n            best_redundancies = redundancies;\n        }\n    }\n    \n    string robust_path;\n    for (int i = 0; i < best_path.size(); i++) {\n        robust_path += string(best_redundancies[i], best_path[i]);\n    }\n    \n    cout << robust_path << endl;\n    \n    return 0;\n}","ahc010":"","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <unordered_set>\n#include <tuple>\n#include <cmath>\n#include <climits>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nconst int dx[] = {0, 0, -1, 1};\nconst int dy[] = {-1, 1, 0, 0};\nconst char dir_char[] = {'L', 'R', 'U', 'D'};\n\nstruct State {\n    vector<vector<int>> board;\n    int empty_x, empty_y;\n    int last_move;\n    int connections;\n    int max_component;\n    string moves;\n};\n\nbool are_connected(int tile1, int tile2, int direction) {\n    if (direction == 0) return (tile1 & 1) && (tile2 & 4);\n    if (direction == 1) return (tile1 & 4) && (tile2 & 1);\n    if (direction == 2) return (tile1 & 2) && (tile2 & 8);\n    if (direction == 3) return (tile1 & 8) && (tile2 & 2);\n    return false;\n}\n\nint count_connections_full(const vector<vector<int>>& board, int N) {\n    int connections = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            if (i < N - 1 && board[i+1][j] != 0) {\n                if (are_connected(tile, board[i+1][j], 3)) {\n                    connections++;\n                }\n            }\n            if (j < N - 1 && board[i][j+1] != 0) {\n                if (are_connected(tile, board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint compute_components(vector<vector<int>>& board, int N) {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_comp = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int comp_size = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                comp_size++;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d];\n                    int ny = y + dy[d];\n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && board[nx][ny] != 0) {\n                        if (are_connected(board[x][y], board[nx][ny], d)) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            max_comp = max(max_comp, comp_size);\n        }\n    }\n    return max_comp;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(0));\n\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int empty_x = -1, empty_y = -1;\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            if (c == '0') {\n                initial_board[i][j] = 0;\n                empty_x = i;\n                empty_y = j;\n            } else {\n                if (c >= '0' && c <= '9') {\n                    initial_board[i][j] = c - '0';\n                } else {\n                    initial_board[i][j] = 10 + (c - 'a');\n                }\n            }\n        }\n    }\n\n    vector<State> best_states;\n    int num_iterations = 2;\n    double gamma = 1.0;\n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        State current;\n        current.board = initial_board;\n        current.empty_x = empty_x;\n        current.empty_y = empty_y;\n        current.last_move = -1;\n        current.connections = count_connections_full(current.board, N);\n        current.max_component = compute_components(current.board, N);\n        current.moves = \"\";\n\n        for (int step = 0; step < T; ++step) {\n            if (step % 10 == 0) {\n                current.max_component = compute_components(current.board, N);\n                if (current.max_component == N * N - 1) {\n                    break;\n                }\n            }\n\n            int best_delta = -1000000;\n            int best_move = -1;\n            int best_new_connections = -1;\n\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == (current.last_move ^ 1)) continue;\n\n                int nx = current.empty_x + dx[dir];\n                int ny = current.empty_y + dy[dir];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n\n                int new_connections = current.connections;\n                int tile = current.board[nx][ny];\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = nx + dx[d];\n                    int y = ny + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections--;\n                        }\n                    }\n                }\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = current.empty_x + dx[d];\n                    int y = current.empty_y + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (x == nx && y == ny) continue;\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections++;\n                        }\n                    }\n                }\n\n                double delta = new_connections - current.connections;\n                delta += gamma * (current.max_component * 0.01);\n                delta += (rand() % 100) * 0.001;\n\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_move = dir;\n                    best_new_connections = new_connections;\n                }\n            }\n\n            if (best_move == -1) break;\n\n            int nx = current.empty_x + dx[best_move];\n            int ny = current.empty_y + dy[best_move];\n            swap(current.board[current.empty_x][current.empty_y], current.board[nx][ny]);\n            current.empty_x = nx;\n            current.empty_y = ny;\n            current.connections = best_new_connections;\n            current.moves += dir_char[best_move];\n            current.last_move = best_move;\n        }\n\n        current.max_component = compute_components(current.board, N);\n        best_states.push_back(current);\n    }\n\n    sort(best_states.begin(), best_states.end(), [](const State& a, const State& b) {\n        if (a.max_component != b.max_component) {\n            return a.max_component > b.max_component;\n        }\n        return a.moves.size() < b.moves.size();\n    });\n\n    cout << best_states[0].moves << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <set>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nusing Point = pair<long long, long long>;\nusing Line = pair<Point, Point>;\n\nconst long long RADIUS = 10000;\nconst long long RADIUS_SQ = 100000000;\n\nstruct Solution {\n    vector<Line> lines;\n    double score;\n};\n\nlong long cross(const Point& O, const Point& A, const Point& B) {\n    return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);\n}\n\nlong long side(const Line& line, const Point& P) {\n    const Point& A = line.first;\n    const Point& B = line.second;\n    return cross(A, B, P);\n}\n\nbool is_inside_circle(const Point& p) {\n    return p.first * p.first + p.second * p.second < RADIUS_SQ;\n}\n\ndouble calculate_score(const vector<int>& a, const vector<int>& b) {\n    int total_distributed = 0;\n    int total_attendees = 0;\n    \n    for (int d = 1; d <= 10; d++) {\n        total_distributed += min(a[d-1], b[d-1]);\n        total_attendees += a[d-1];\n    }\n    \n    return 1000000.0 * total_distributed / total_attendees;\n}\n\nvector<int> count_strawberries(const vector<Point>& strawberries, const vector<Line>& lines) {\n    if (lines.empty()) {\n        return {static_cast<int>(strawberries.size())};\n    }\n    \n    unordered_map<string, int> region_counts;\n    \n    for (const auto& strawberry : strawberries) {\n        string signature;\n        bool on_line = false;\n        \n        for (const auto& line : lines) {\n            long long s = side(line, strawberry);\n            if (s == 0) {\n                on_line = true;\n                break;\n            }\n            signature += (s > 0) ? '1' : '0';\n        }\n        \n        if (!on_line) {\n            region_counts[signature]++;\n        }\n    }\n    \n    vector<int> distribution(10, 0);\n    for (const auto& [_, count] : region_counts) {\n        if (count >= 1 && count <= 10) {\n            distribution[count-1]++;\n        }\n    }\n    \n    return distribution;\n}\n\nvector<Line> generate_candidate_lines(const vector<Point>& strawberries, mt19937& rng, int num_candidates = 20) {\n    vector<Line> candidates;\n    int n = strawberries.size();\n    \n    // Random lines through two strawberries\n    for (int i = 0; i < num_candidates / 2 && i < n * n / 2; i++) {\n        int idx1 = rng() % n;\n        int idx2 = rng() % n;\n        if (idx1 != idx2) {\n            candidates.push_back({strawberries[idx1], strawberries[idx2]});\n        }\n    }\n    \n    // Random lines in random directions\n    uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n    for (int i = 0; i < num_candidates / 2; i++) {\n        Point p1 = {coord_dist(rng), coord_dist(rng)};\n        Point p2 = {coord_dist(rng), coord_dist(rng)};\n        candidates.push_back({p1, p2});\n    }\n    \n    return candidates;\n}\n\nSolution solve(int N, int K, const vector<int>& a, const vector<Point>& strawberries) {\n    mt19937 rng(12345);\n    \n    Solution best_solution;\n    best_solution.lines = {};\n    vector<int> initial_dist = count_strawberries(strawberries, {});\n    best_solution.score = calculate_score(a, initial_dist);\n    \n    vector<Line> current_lines;\n    double current_score = best_solution.score;\n    \n    int no_improve_count = 0;\n    int max_no_improve = 5; // Stop after 5 consecutive non-improving iterations\n    \n    for (int iter = 0; iter < min(K, 50); iter++) { // Limit to 50 iterations\n        vector<Line> candidates = generate_candidate_lines(strawberries, rng);\n        \n        Line best_line;\n        double best_score = current_score;\n        bool improved = false;\n        \n        for (const auto& line : candidates) {\n            vector<Line> new_lines = current_lines;\n            new_lines.push_back(line);\n            \n            vector<int> distribution = count_strawberries(strawberries, new_lines);\n            double score = calculate_score(a, distribution);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = line;\n                improved = true;\n            }\n        }\n        \n        if (improved) {\n            current_lines.push_back(best_line);\n            current_score = best_score;\n            no_improve_count = 0;\n            \n            if (current_score > best_solution.score) {\n                best_solution.lines = current_lines;\n                best_solution.score = current_score;\n            }\n        } else {\n            no_improve_count++;\n            if (no_improve_count >= max_no_improve) {\n                break;\n            }\n            // Add a random line anyway to continue exploring\n            uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n            Point p1 = {coord_dist(rng), coord_dist(rng)};\n            Point p2 = {coord_dist(rng), coord_dist(rng)};\n            current_lines.push_back({p1, p2});\n        }\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(10);\n    for (int i = 0; i < 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].first >> strawberries[i].second;\n    }\n    \n    Solution solution = solve(N, K, a, strawberries);\n    \n    cout << solution.lines.size() << \"\\n\";\n    for (const auto& line : solution.lines) {\n        cout << line.first.first << \" \" << line.first.second << \" \"\n             << line.second.first << \" \" << line.second.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    int c = (N - 1) / 2;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> col_dots(N);\n    vector<set<int>> row_dots(N);\n    set<tuple<int, int, int, int>> segments;\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    while (true) {\n        vector<pair<int, int>> non_dot_points;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    non_dot_points.emplace_back(x, y);\n                }\n            }\n        }\n\n        if (non_dot_points.empty()) {\n            break;\n        }\n\n        sort(non_dot_points.begin(), non_dot_points.end(), \n            [c](const pair<int, int>& a, const pair<int, int>& b) {\n                int wa = (a.first - c) * (a.first - c) + (a.second - c) * (a.second - c) + 1;\n                int wb = (b.first - c) * (b.first - c) + (b.second - c) * (b.second - c) + 1;\n                return wa > wb;\n            });\n\n        tuple<int, int, int, int, int, int, int, int> best_op;\n        vector<tuple<int, int, int, int>> best_segments_list;\n        int best_weight = -1;\n        bool found = false;\n\n        for (auto [x, y] : non_dot_points) {\n            int weight = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n            bool found_axis = false;\n            for (int x2 = 0; x2 < N; x2++) {\n                if (x2 == x) continue;\n                if (!grid[x2][y]) continue;\n\n                if (col_dots[x].size() <= col_dots[x2].size()) {\n                    for (int y2 : col_dots[x]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x2].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                } else {\n                    for (int y2 : col_dots[x2]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                }\n            }\n\n            bool found_diamond = false;\n            for (int role = 0; role < 4; role++) {\n                int max_a;\n                if (role == 0) {\n                    max_a = min({(N - 1 - x) / 2, (N - 1 - y), y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x + a;\n                        int cy = y;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + 2 * a - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + i;\n                            int x2 = x + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a + i;\n                            int y1 = y + a - i;\n                            int x2 = x + a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + 2 * a - i;\n                            int y1 = y - i;\n                            int x2 = x + 2 * a - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a + i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 1) {\n                    max_a = min({x, N - 1 - x, y / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y - a;\n                        int Ax = cx - a, Ay = cy;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - 2 * a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y - i;\n                            int x2 = x + i + 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - 2 * a + i;\n                            int x2 = x - i - 1;\n                            int y2 = y - 2 * a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y - a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Dx, Dy, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 2) {\n                    max_a = min({x / 2, y, N - 1 - y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x - a;\n                        int cy = y;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - 2 * a + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - i;\n                            int x2 = x - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a - i;\n                            int y1 = y - a + i;\n                            int x2 = x - a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - 2 * a + i;\n                            int y1 = y + i;\n                            int x2 = x - 2 * a + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a - i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Ax, Ay, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 3) {\n                    max_a = min({x, N - 1 - x, (N - 1 - y) / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y + a;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + 2 * a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y + i;\n                            int x2 = x - i - 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + 2 * a - i;\n                            int x2 = x + i + 1;\n                            int y2 = y + 2 * a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y + a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                }\n            }\n        }\n\n        if (!found) {\n            break;\n        }\n\n        auto [x, y, x1, y1, x2, y2, x3, y3] = best_op;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n        for (auto& seg : best_segments_list) {\n            segments.insert(seg);\n        }\n        operations.push_back(best_op);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        auto [x, y, x1, y1, x2, y2, x3, y3] = op;\n        cout << x << \" \" << y << \" \" << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \" \" << x3 << \" \" << y3 << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> cells;\n    int rows, cols;\n    \n    Grid(int r = 10, int c = 10) : rows(r), cols(c), cells(r, vector<int>(c, 0)) {}\n    \n    bool is_valid(int r, int c) const {\n        return r >= 0 && r < rows && c >= 0 && c < cols;\n    }\n    \n    int get_empty_count() const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) count++;\n            }\n        }\n        return count;\n    }\n    \n    pair<int, int> get_nth_empty(int n) const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) {\n                    count++;\n                    if (count == n) return {r, c};\n                }\n            }\n        }\n        return {-1, -1}; // Should not happen\n    }\n    \n    void tilt(char direction) {\n        if (direction == 'F') { // Forward (up)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = 0;\n                for (int r = 0; r < rows; ++r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'B') { // Backward (down)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = rows - 1;\n                for (int r = rows - 1; r >= 0; --r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        } else if (direction == 'L') { // Left\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = 0;\n                for (int c = 0; c < cols; ++c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'R') { // Right\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = cols - 1;\n                for (int c = cols - 1; c >= 0; --c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    void place(int r, int c, int flavor) {\n        cells[r][c] = flavor;\n    }\n    \n    double calculate_score() const {\n        vector<bool> visited(rows * cols, false);\n        vector<int> component_sizes;\n        \n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0 && !visited[r * cols + c]) {\n                    int flavor = cells[r][c];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    visited[r * cols + c] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int dr = -1; dr <= 1; ++dr) {\n                            for (int dc = -1; dc <= 1; ++dc) {\n                                if (abs(dr) + abs(dc) != 1) continue;\n                                int nr = cr + dr;\n                                int nc = cc + dc;\n                                if (is_valid(nr, nc) && cells[nr][nc] == flavor && \n                                    !visited[nr * cols + nc]) {\n                                    visited[nr * cols + nc] = true;\n                                    q.push({nr, nc});\n                                }\n                            }\n                        }\n                    }\n                    \n                    component_sizes.push_back(size);\n                }\n            }\n        }\n        \n        double sum_squares = 0;\n        for (int size : component_sizes) {\n            sum_squares += size * size;\n        }\n        \n        array<int, 4> flavor_counts = {0, 0, 0, 0};\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0) {\n                    flavor_counts[cells[r][c]]++;\n                }\n            }\n        }\n        \n        double denominator = 0;\n        for (int i = 1; i <= 3; ++i) {\n            denominator += flavor_counts[i] * flavor_counts[i];\n        }\n        \n        return sum_squares / denominator;\n    }\n    \n    pair<int, int> get_tilted_position(int r, int c, char direction) const {\n        if (direction == 'F') { // Forward (up)\n            while (r > 0 && cells[r - 1][c] == 0) {\n                r--;\n            }\n        } else if (direction == 'B') { // Backward (down)\n            while (r < rows - 1 && cells[r + 1][c] == 0) {\n                r++;\n            }\n        } else if (direction == 'L') { // Left\n            while (c > 0 && cells[r][c - 1] == 0) {\n                c--;\n            }\n        } else if (direction == 'R') { // Right\n            while (c < cols - 1 && cells[r][c + 1] == 0) {\n                c++;\n            }\n        }\n        return {r, c};\n    }\n    \n    int count_same_flavor_neighbors(int r, int c, int flavor) const {\n        int count = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n    \n    bool would_break_cluster(int r, int c, int flavor, char direction) const {\n        // Check if tilting would disconnect this candy from its current cluster\n        int neighbors = count_same_flavor_neighbors(r, c, flavor);\n        if (neighbors <= 1) return false; // Can't break a cluster if already isolated or only one neighbor\n        \n        // Simulate the tilt and check if it disconnects the candy\n        auto [new_r, new_c] = get_tilted_position(r, c, direction);\n        if (new_r == r && new_c == c) return false; // No movement\n        \n        // After movement, check if it still has neighbors\n        int new_neighbors = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = new_r + dr;\n                int nc = new_c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    // Check if this neighbor would also move to a position adjacent to the candy\n                    auto [neighbor_new_r, neighbor_new_c] = get_tilted_position(nr, nc, direction);\n                    if (abs(neighbor_new_r - new_r) + abs(neighbor_new_c - new_c) == 1) {\n                        new_neighbors++;\n                    }\n                }\n            }\n        }\n        \n        return new_neighbors == 0;\n    }\n    \n    int count_flavor_in_area(int r, int c, int flavor, int radius) const {\n        int count = 0;\n        for (int dr = -radius; dr <= radius; ++dr) {\n            for (int dc = -radius; dc <= radius; ++dc) {\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nclass CandyClustering {\nprivate:\n    Grid grid;\n    vector<int> flavors;\n    array<int, 4> flavor_counts = {0, 0, 0, 0};\n    vector<pair<int, int>> flavor_region_centers; // Fixed centers based on regions\n    vector<pair<int, int>> flavor_centers; // Dynamic centers of mass\n    vector<vector<int>> flavor_regions; // Which region each cell belongs to\n    \npublic:\n    CandyClustering(const vector<int>& f) : flavors(f) {\n        // Count flavors\n        for (int f : flavors) {\n            flavor_counts[f]++;\n        }\n        \n        // Initialize regions and centers\n        initialize_flavor_regions();\n        initialize_flavor_centers();\n    }\n    \n    void initialize_flavor_regions() {\n        flavor_regions.assign(grid.rows, vector<int>(grid.cols, 0));\n        \n        // Sort flavors by count (descending)\n        vector<pair<int, int>> sorted_flavors;\n        for (int i = 1; i <= 3; ++i) {\n            sorted_flavors.emplace_back(flavor_counts[i], i);\n        }\n        sort(sorted_flavors.rbegin(), sorted_flavors.rend());\n        \n        // Assign regions proportional to flavor counts\n        int total = grid.rows * grid.cols;\n        int assigned = 0;\n        \n        for (auto [count, flavor] : sorted_flavors) {\n            if (count == 0) continue;\n            \n            // Calculate how many cells this flavor should get\n            int cells_needed = round(static_cast<double>(count) / 100 * total);\n            \n            // Assign contiguous blocks\n            int rows_needed = (cells_needed + grid.cols - 1) / grid.cols;\n            \n            // Start from the top-left and assign rows\n            for (int r = assigned / grid.cols; r < grid.rows && rows_needed > 0; ++r) {\n                for (int c = 0; c < grid.cols; ++c) {\n                    if (flavor_regions[r][c] == 0) {\n                        flavor_regions[r][c] = flavor;\n                        cells_needed--;\n                        if (cells_needed <= 0) break;\n                    }\n                }\n                if (cells_needed <= 0) break;\n                rows_needed--;\n            }\n            \n            assigned += count;\n        }\n    }\n    \n    void initialize_flavor_centers() {\n        flavor_region_centers.resize(4);\n        flavor_centers.resize(4);\n        \n        // Calculate the center of each flavor's region\n        array<vector<pair<int, int>>, 4> region_positions;\n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (flavor_regions[r][c] != 0) {\n                    region_positions[flavor_regions[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!region_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : region_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_region_centers[f] = {sum_r / region_positions[f].size(), \n                                          sum_c / region_positions[f].size()};\n                flavor_centers[f] = flavor_region_centers[f];\n            }\n        }\n    }\n    \n    char decide_direction(int step, int pos) {\n        auto [r, c] = grid.get_nth_empty(pos);\n        int flavor = flavors[step - 1];\n        grid.place(r, c, flavor);\n        \n        if (step == 100) return ' ';\n        \n        // Update centers more frequently\n        if (step % 5 == 0) {\n            update_flavor_centers();\n        }\n        \n        char best_dir = 'F';\n        double best_score = -1e9;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid temp_grid = grid;\n            temp_grid.tilt(dir);\n            \n            double score = calculate_direction_score(temp_grid, flavor, r, c, dir, step);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        grid.tilt(best_dir);\n        return best_dir;\n    }\n    \n    void update_flavor_centers() {\n        array<vector<pair<int, int>>, 4> flavor_positions;\n        \n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (grid.cells[r][c] != 0) {\n                    flavor_positions[grid.cells[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!flavor_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : flavor_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_centers[f] = {sum_r / flavor_positions[f].size(), \n                                     sum_c / flavor_positions[f].size()};\n            }\n        }\n    }\n    \n    double calculate_direction_score(const Grid& g, int flavor, int r, int c, char dir, int step) {\n        double score = 0;\n        \n        // Get new position after tilting\n        auto [new_r, new_c] = g.get_tilted_position(r, c, dir);\n        \n        // Distance to dynamic center (center of mass)\n        auto center = flavor_centers[flavor];\n        double distance_before = sqrt(pow(r - center.first, 2) + pow(c - center.second, 2));\n        double distance_after = sqrt(pow(new_r - center.first, 2) + pow(new_c - center.second, 2));\n        score += (distance_before - distance_after) * 15;\n        \n        // Distance to fixed region center\n        auto region_center = flavor_region_centers[flavor];\n        double region_distance_before = sqrt(pow(r - region_center.first, 2) + pow(c - region_center.second, 2));\n        double region_distance_after = sqrt(pow(new_r - region_center.first, 2) + pow(new_c - region_center.second, 2));\n        score += (region_distance_before - region_distance_after) * 5;\n        \n        // Same-flavor neighbors\n        int same_flavor_neighbors = g.count_same_flavor_neighbors(new_r, new_c, flavor);\n        score += same_flavor_neighbors * 100;\n        \n        // Density of same flavor in the area\n        int density = g.count_flavor_in_area(new_r, new_c, flavor, 2);\n        score += density * 10;\n        \n        // Penalty for isolation\n        if (same_flavor_neighbors == 0) {\n            score -= 30;\n        }\n        \n        // Penalty for breaking clusters\n        if (grid.would_break_cluster(r, c, flavor, dir)) {\n            score -= 50;\n        }\n        \n        // Stage-specific scoring\n        if (step < 30) {\n            // Early stage: prioritize moving to region\n            score += (region_distance_before - region_distance_after) * 10;\n        } else if (step < 70) {\n            // Middle stage: balance between region and clustering\n            score += (distance_before - distance_after) * 10;\n        } else {\n            // Late stage: prioritize clustering and overall score\n            double current_score = grid.calculate_score();\n            double new_score = g.calculate_score();\n            score += (new_score - current_score) * 5000;\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n    \n    CandyClustering solver(flavors);\n    \n    for (int t = 1; t <= 100; ++t) {\n        int pos;\n        cin >> pos;\n        \n        char direction = solver.decide_direction(t, pos);\n        \n        if (t < 100) {\n            cout << direction << endl;\n            cout.flush();\n        }\n    }\n    \n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n#include <utility>\n#include <iomanip>\n\nusing namespace std;\n\nvector<pair<int, int>> generate_clique_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int c = 2; c <= N; ++c) {\n        pairs.push_back({c, 0});\n    }\n    return pairs;\n}\n\nvector<pair<int, int>> generate_bipartite_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int a = 1; a <= N/2; ++a) {\n        for (int b = a; b <= N - a; ++b) {\n            pairs.push_back({a, b});\n        }\n    }\n    return pairs;\n}\n\nvector<double> get_expected_clique_degrees(int c, int N, double eps) {\n    double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    for (int i = 0; i < N - c; ++i) {\n        deg[i] = exp_iso;\n    }\n    for (int i = N - c; i < N; ++i) {\n        deg[i] = exp_clique;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_bipartite_degrees(int a, int b, int N, double eps) {\n    double exp_a = b * (1 - 2 * eps) + eps * (N - 1);\n    double exp_b = a * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    int idx = 0;\n    for (int i = 0; i < N - a - b; ++i) {\n        deg[idx++] = exp_iso;\n    }\n    for (int i = 0; i < b; ++i) {\n        deg[idx++] = exp_b;\n    }\n    for (int i = 0; i < a; ++i) {\n        deg[idx++] = exp_a;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_star_degrees(int N, double eps) {\n    double exp_center = (N - 1) * (1 - eps);\n    double exp_leaf = 1 + (N - 2) * eps;\n    vector<double> deg(N);\n    deg[0] = exp_center;\n    for (int i = 1; i < N; ++i) {\n        deg[i] = exp_leaf;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    int N = 4;\n    while (true) {\n        int num_cliques = max(0, N - 1);\n        int num_bipartite = (N / 2) * ((N + 1) / 2);\n        int num_graphs = num_cliques + num_bipartite;\n        if (num_graphs >= M) {\n            break;\n        }\n        N++;\n        if (N > 100) {\n            N = 100;\n            break;\n        }\n    }\n\n    vector<pair<int, int>> clique_pairs = generate_clique_pairs(N);\n    vector<pair<int, int>> bipartite_pairs = generate_bipartite_pairs(N);\n\n    vector<pair<int, int>> candidate_pairs;\n    candidate_pairs.insert(candidate_pairs.end(), clique_pairs.begin(), clique_pairs.end());\n    candidate_pairs.insert(candidate_pairs.end(), bipartite_pairs.begin(), bipartite_pairs.end());\n\n    vector<vector<double>> candidate_expected;\n    for (auto& p : candidate_pairs) {\n        if (p.second == 0) {\n            candidate_expected.push_back(get_expected_clique_degrees(p.first, N, eps));\n        } else {\n            candidate_expected.push_back(get_expected_bipartite_degrees(p.first, p.second, N, eps));\n        }\n    }\n\n    vector<int> selected_indices;\n    if (M > 0) {\n        selected_indices.push_back(0);\n    }\n\n    for (int i = 1; i < M; ++i) {\n        double max_min_dist_sq = -1.0;\n        int best_index = -1;\n\n        for (int idx = 0; idx < candidate_expected.size(); ++idx) {\n            if (find(selected_indices.begin(), selected_indices.end(), idx) != selected_indices.end()) {\n                continue;\n            }\n\n            double min_dist_sq = numeric_limits<double>::max();\n            for (int sel : selected_indices) {\n                double dist_sq = 0.0;\n                for (int j = 0; j < N; ++j) {\n                    double diff = candidate_expected[idx][j] - candidate_expected[sel][j];\n                    dist_sq += diff * diff;\n                }\n                if (dist_sq < min_dist_sq) {\n                    min_dist_sq = dist_sq;\n                }\n            }\n\n            if (min_dist_sq > max_min_dist_sq) {\n                max_min_dist_sq = min_dist_sq;\n                best_index = idx;\n            }\n        }\n\n        if (best_index != -1) {\n            selected_indices.push_back(best_index);\n        }\n    }\n\n    cout << N << endl;\n    for (int idx : selected_indices) {\n        auto p = candidate_pairs[idx];\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        if (p.second == 0) {\n            int c = p.first;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if (i < c && j < c) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        } else {\n            int a = p.first;\n            int b = p.second;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i < a && j >= a && j < a + b) || (j < a && i >= a && i < a + b)) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    vector<vector<double>> selected_expected;\n    for (int idx : selected_indices) {\n        selected_expected.push_back(candidate_expected[idx]);\n    }\n\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n\n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[idx] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                idx++;\n            }\n        }\n\n        sort(deg.begin(), deg.end());\n\n        int best_index = -1;\n        double best_dist_sq = numeric_limits<double>::max();\n\n        for (int t = 0; t < M; ++t) {\n            double dist_sq = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = deg[i] - selected_expected[t][i];\n                dist_sq += diff * diff;\n            }\n            if (dist_sq < best_dist_sq) {\n                best_dist_sq = dist_sq;\n                best_index = t;\n            }\n        }\n\n        cout << best_index << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n#include <unordered_map>\n#include <numeric>\n#include <stack>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int index;\n};\n\nusing ll = long long;\n\nll compute_alt(int u, int v, const Edge& e, const vector<vector<pair<int, int>>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, LLONG_MAX);\n    dist[u] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n    pq.push({0, u});\n\n    while (!pq.empty()) {\n        auto [d, node] = pq.top();\n        pq.pop();\n        if (d != dist[node]) continue;\n        if (node == v) return d;\n        for (auto [neighbor, weight] : adj[node]) {\n            if ((node == e.u && neighbor == e.v) || (node == e.v && neighbor == e.u)) {\n                continue;\n            }\n            ll new_dist = d + weight;\n            if (new_dist < dist[neighbor]) {\n                dist[neighbor] = new_dist;\n                pq.push({new_dist, neighbor});\n            }\n        }\n    }\n    return dist[v];\n}\n\nvector<double> compute_betweenness(const vector<vector<pair<int, int>>>& adj, int N) {\n    vector<double> betweenness(N, 0.0);\n    vector<vector<int>> predecessors(N);\n    vector<ll> dist(N);\n    vector<int> count(N);\n    vector<double> dependency(N, 0.0);\n    \n    for (int s = 0; s < N; s++) {\n        // Initialize\n        fill(predecessors.begin(), predecessors.end(), vector<int>());\n        fill(dist.begin(), dist.end(), LLONG_MAX);\n        fill(count.begin(), count.end(), 0);\n        fill(dependency.begin(), dependency.end(), 0.0);\n        \n        stack<int> stk;\n        queue<int> q;\n        \n        dist[s] = 0;\n        count[s] = 1;\n        q.push(s);\n        \n        while (!q.empty()) {\n            int v = q.front();\n            q.pop();\n            stk.push(v);\n            \n            for (auto [w, weight] : adj[v]) {\n                if (dist[w] > dist[v] + weight) {\n                    dist[w] = dist[v] + weight;\n                    predecessors[w].clear();\n                    predecessors[w].push_back(v);\n                    count[w] = count[v];\n                    q.push(w);\n                } else if (dist[w] == dist[v] + weight) {\n                    predecessors[w].push_back(v);\n                    count[w] += count[v];\n                }\n            }\n        }\n        \n        while (!stk.empty()) {\n            int w = stk.top();\n            stk.pop();\n            for (int v : predecessors[w]) {\n                double partial = (double)count[v] / count[w] * (1.0 + dependency[w]);\n                dependency[v] += partial;\n            }\n            if (w != s) {\n                betweenness[w] += dependency[w];\n            }\n        }\n    }\n    \n    // Normalize betweenness for undirected graph\n    for (int i = 0; i < N; i++) {\n        betweenness[i] /= 2.0;\n    }\n    \n    return betweenness;\n}\n\ndouble estimate_frustration(const vector<vector<pair<int, int>>>& adj, \n                           const vector<Edge>& edges,\n                           const vector<int>& day_edges,\n                           int N, int sample_size = 50) {\n    if (day_edges.empty()) return 0.0;\n    \n    // Create graph without the edges in day_edges\n    vector<vector<pair<int, int>>> temp_adj = adj;\n    for (int e_idx : day_edges) {\n        const Edge& e = edges[e_idx];\n        // Remove edge from adjacency list\n        auto it1 = find_if(temp_adj[e.u].begin(), temp_adj[e.u].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.v; });\n        if (it1 != temp_adj[e.u].end()) temp_adj[e.u].erase(it1);\n        \n        auto it2 = find_if(temp_adj[e.v].begin(), temp_adj[e.v].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.u; });\n        if (it2 != temp_adj[e.v].end()) temp_adj[e.v].erase(it2);\n    }\n    \n    double total_increase = 0.0;\n    int samples = 0;\n    \n    // Sample vertices to estimate frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    for (int i = 0; i < sample_size; i++) {\n        int s = dist(rng);\n        vector<ll> dist_s(N, LLONG_MAX);\n        dist_s[s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist_s[node]) continue;\n            for (auto [neighbor, weight] : temp_adj[node]) {\n                ll new_dist = d + weight;\n                if (new_dist < dist_s[neighbor]) {\n                    dist_s[neighbor] = new_dist;\n                    pq.push({new_dist, neighbor});\n                }\n            }\n        }\n        \n        // For now, we'll use a simplified frustration calculation\n        // In a real implementation, we would compare with original distances\n        for (int j = 0; j < N; j++) {\n            if (s == j) continue;\n            if (dist_s[j] == LLONG_MAX) {\n                total_increase += 1000000000; // Disconnected penalty\n            } else {\n                total_increase += max(0LL, dist_s[j] - 1000); // Placeholder\n            }\n            samples++;\n        }\n    }\n    \n    return total_increase / max(1, samples);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].index = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Precompute original distances (simplified for performance)\n    vector<vector<ll>> original_dist(N, vector<ll>(N, 1000)); // Placeholder\n\n    // Compute vertex betweenness centrality\n    vector<double> vertex_betweenness = compute_betweenness(adj, N);\n\n    // Enhanced criticality calculation\n    vector<double> criticality(M, 0.0);\n    for (int idx = 0; idx < M; idx++) {\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        int w = e.w;\n        \n        // Distance increase component\n        ll alt_dist = compute_alt(u, v, e, adj);\n        if (alt_dist == LLONG_MAX) {\n            alt_dist = 1000000000;\n        }\n        ll increase = alt_dist - w;\n        if (increase < 0) increase = 0;\n        \n        // Betweenness component\n        double betweenness_component = vertex_betweenness[u] + vertex_betweenness[v];\n        \n        // Connectivity penalty\n        int degree_u = adj[u].size();\n        int degree_v = adj[v].size();\n        double connectivity_penalty = 1.0 / min(degree_u, degree_v);\n        \n        // Combined criticality\n        criticality[idx] = (double)increase * (1.0 + betweenness_component) + \n                          connectivity_penalty * 1000000.0;\n    }\n\n    // Initial assignment using enhanced criticality\n    vector<int> edge_indices(M);\n    for (int i = 0; i < M; i++) {\n        edge_indices[i] = i;\n    }\n\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return criticality[a] > criticality[b];\n    });\n\n    double max_crit = *max_element(criticality.begin(), criticality.end());\n\n    vector<int> assignment(M, -1);\n    vector<double> day_criticality(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<vector<int>> vertex_day_count(N, vector<int>(D, 0));\n\n    // Phase 1: Initial assignment\n    for (int i = 0; i < M; i++) {\n        int idx = edge_indices[i];\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        double min_cost = 1e20;\n        int best_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict_count = vertex_day_count[u][d] + vertex_day_count[v][d];\n            double norm_crit = (max_crit > 0) ? (criticality[idx] / max_crit) : 0.0;\n            double cost = conflict_count + 10.0 * norm_crit;\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_day = d;\n            }\n        }\n        assignment[idx] = best_day;\n        day_criticality[best_day] += criticality[idx];\n        day_count[best_day]++;\n        vertex_day_count[u][best_day]++;\n        vertex_day_count[v][best_day]++;\n    }\n\n    // Phase 2: Local search to balance frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int num_iterations = 5000;\n    \n    for (int iter = 0; iter < num_iterations; iter++) {\n        // Select a random day\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        \n        // Get edges in this day\n        vector<int> edges_in_d1;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) {\n                edges_in_d1.push_back(i);\n            }\n        }\n        if (edges_in_d1.empty()) continue;\n        \n        // Select a random edge from this day\n        uniform_int_distribution<int> dist_edge(0, (int)edges_in_d1.size()-1);\n        int e_idx = edges_in_d1[dist_edge(rng)];\n        \n        // Find candidate days to move to\n        vector<int> candidate_days;\n        for (int d2 = 0; d2 < D; d2++) {\n            if (d2 == d1) continue;\n            if (day_count[d2] >= K) continue;\n            candidate_days.push_back(d2);\n        }\n        if (candidate_days.empty()) continue;\n        \n        // Try each candidate day\n        double best_delta = 1e20;\n        int best_d2 = -1;\n        \n        for (int d2 : candidate_days) {\n            // Estimate frustration change\n            double delta = day_criticality[d1] + day_criticality[d2];\n            double new_d1 = day_criticality[d1] - criticality[e_idx];\n            double new_d2 = day_criticality[d2] + criticality[e_idx];\n            delta -= (new_d1 + new_d2);\n            \n            if (delta < best_delta) {\n                best_delta = delta;\n                best_d2 = d2;\n            }\n        }\n        \n        if (best_delta < 0) {\n            // Make the move\n            assignment[e_idx] = best_d2;\n            day_criticality[d1] -= criticality[e_idx];\n            day_criticality[best_d2] += criticality[e_idx];\n            day_count[d1]--;\n            day_count[best_d2]++;\n            vertex_day_count[edges[e_idx].u][d1]--;\n            vertex_day_count[edges[e_idx].v][d1]--;\n            vertex_day_count[edges[e_idx].u][best_d2]++;\n            vertex_day_count[edges[e_idx].v][best_d2]++;\n        }\n    }\n\n    // Phase 3: Simulated annealing for further optimization\n    double temperature = 1000.0;\n    double cooling_rate = 0.99;\n    int sa_iterations = 2000;\n    \n    double current_cost = 0.0;\n    for (int d = 0; d < D; d++) {\n        current_cost += day_criticality[d] * day_criticality[d];\n    }\n    \n    for (int iter = 0; iter < sa_iterations; iter++) {\n        temperature *= cooling_rate;\n        \n        // Select two random days\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        int d2 = dist_day(rng);\n        if (d1 == d2) continue;\n        \n        // Select random edges from each day\n        vector<int> edges_d1, edges_d2;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) edges_d1.push_back(i);\n            if (assignment[i] == d2) edges_d2.push_back(i);\n        }\n        \n        if (edges_d1.empty() || edges_d2.empty()) continue;\n        \n        uniform_int_distribution<int> dist_e1(0, (int)edges_d1.size()-1);\n        uniform_int_distribution<int> dist_e2(0, (int)edges_d2.size()-1);\n        int e1 = edges_d1[dist_e1(rng)];\n        int e2 = edges_d2[dist_e2(rng)];\n        \n        // Compute cost change for swapping\n        double old_cost = day_criticality[d1] * day_criticality[d1] + \n                         day_criticality[d2] * day_criticality[d2];\n        \n        double new_d1 = day_criticality[d1] - criticality[e1] + criticality[e2];\n        double new_d2 = day_criticality[d2] - criticality[e2] + criticality[e1];\n        double new_cost = new_d1 * new_d1 + new_d2 * new_d2;\n        \n        double delta = new_cost - old_cost;\n        \n        // Accept with probability based on temperature\n        if (delta < 0 || exp(-delta / temperature) > (double)rng() / rng.max()) {\n            // Make the swap\n            assignment[e1] = d2;\n            assignment[e2] = d1;\n            day_criticality[d1] = new_d1;\n            day_criticality[d2] = new_d2;\n            \n            // Update vertex counts\n            vertex_day_count[edges[e1].u][d1]--;\n            vertex_day_count[edges[e1].v][d1]--;\n            vertex_day_count[edges[e1].u][d2]++;\n            vertex_day_count[edges[e1].v][d2]++;\n            \n            vertex_day_count[edges[e2].u][d2]--;\n            vertex_day_count[edges[e2].v][d2]--;\n            vertex_day_count[edges[e2].u][d1]++;\n            vertex_day_count[edges[e2].v][d1]++;\n            \n            current_cost += delta;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] + 1;\n        if (i < M - 1) {\n            cout << \" \";\n        } else {\n            cout << endl;\n        }\n    }\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n#include <map>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[6] = {1, 0, 0, -1, 0, 0};\nconst int dy[6] = {0, 1, 0, 0, -1, 0};\nconst int dz[6] = {0, 0, 1, 0, 0, -1};\n\nusing Point = tuple<int, int, int>;\n\nvector<set<Point>> get_connected_components_from_set(const set<Point>& points) {\n    set<Point> visited;\n    vector<set<Point>> components;\n    for (const auto& p : points) {\n        if (visited.find(p) == visited.end()) {\n            set<Point> comp;\n            queue<Point> q;\n            q.push(p);\n            visited.insert(p);\n            while (!q.empty()) {\n                auto [x, y, z] = q.front(); q.pop();\n                comp.insert({x, y, z});\n                for (int dir = 0; dir < 6; dir++) {\n                    int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                    Point np = {nx, ny, nz};\n                    if (points.find(np) != points.end() && visited.find(np) == visited.end()) {\n                        visited.insert(np);\n                        q.push(np);\n                    }\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\nvector<set<Point>> get_connected_components_from_grid(const vector<vector<vector<bool>>>& grid, int D) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<set<Point>> components;\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (grid[z][x][y] && !visited[z][x][y]) {\n                    set<Point> comp;\n                    queue<Point> q;\n                    q.push({x, y, z});\n                    visited[z][x][y] = true;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.insert({cx, cy, cz});\n                        for (int dir = 0; dir < 6; dir++) {\n                            int nx = cx + dx[dir], ny = cy + dy[dir], nz = cz + dz[dir];\n                            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) \n                                continue;\n                            if (grid[nz][nx][ny] && !visited[nz][nx][ny]) {\n                                visited[nz][nx][ny] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n    return components;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> cand1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> cand2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> Common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (f1[z][x] == '1' && r1[z][y] == '1') {\n                    cand1[z][x][y] = true;\n                }\n                if (f2[z][x] == '1' && r2[z][y] == '1') {\n                    cand2[z][x][y] = true;\n                }\n                if (cand1[z][x][y] && cand2[z][x][y]) {\n                    Common[z][x][y] = true;\n                }\n            }\n        }\n    }\n\n    auto process_object = [&](const vector<string>& f, const vector<string>& r, \n                              const vector<vector<vector<bool>>>& cand, \n                              const vector<vector<vector<bool>>>& common) {\n        set<Point> additional_set;\n        vector<vector<bool>> covered_front(D, vector<bool>(D, false));\n        vector<vector<bool>> covered_right(D, vector<bool>(D, false));\n\n        // Mark requirements covered by common cells\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (common[z][x][y]) {\n                        covered_front[z][x] = true;\n                        covered_right[z][y] = true;\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered front requirements\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (f[z][x] == '1' && !covered_front[z][x]) {\n                    bool found = false;\n                    for (int y = 0; y < D; y++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int y = 0; y < D; y++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered right requirements\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (r[z][y] == '1' && !covered_right[z][y]) {\n                    bool found = false;\n                    for (int x = 0; x < D; x++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int x = 0; x < D; x++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return additional_set;\n    };\n\n    set<Point> A1_set = process_object(f1, r1, cand1, Common);\n    set<Point> B1_set = process_object(f2, r2, cand2, Common);\n\n    auto common_components = get_connected_components_from_grid(Common, D);\n    auto a1_components = get_connected_components_from_set(A1_set);\n    auto b1_components = get_connected_components_from_set(B1_set);\n\n    int n = common_components.size() + a1_components.size() + b1_components.size();\n    vector<int> arr1(D*D*D, 0);\n    vector<int> arr2(D*D*D, 0);\n\n    int block_id = 1;\n    for (const auto& comp : common_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : a1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : b1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    cout << n << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr1[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr2[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <queue>\n#include <unordered_set>\n#include <chrono>\n#include <iomanip>\n#include <limits>\n\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    ll x, y;\n    \n    Point() : x(0), y(0) {}\n    Point(ll x, ll y) : x(x), y(y) {}\n    \n    ll dist2(const Point& other) const {\n        ll dx = x - other.x;\n        ll dy = y - other.y;\n        return dx * dx + dy * dy;\n    }\n    \n    double dist(const Point& other) const {\n        return sqrt(dist2(other));\n    }\n};\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int idx;\n    \n    Edge(int u, int v, ll w, int idx) : u(u), v(v), w(w), idx(idx) {}\n    \n    bool operator<(const Edge& other) const {\n        return w < other.w;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    ll cost;\n    int covered;\n    \n    Solution(int N, int M) : P(N, 0), B(M, 0), cost(0), covered(0) {}\n};\n\nclass TVNetworkOptimizer {\nprivate:\n    int N, M, K;\n    vector<Point> stations;\n    vector<Point> residents;\n    vector<Edge> edges;\n    vector<vector<pair<int, ll>>> adj; // adjacency list\n    \n    // Random number generation\n    mt19937 rng;\n    \n    // Best solution found\n    Solution best_solution;\n    \n    // Distance matrices\n    vector<vector<double>> station_to_resident_dist;\n    vector<vector<double>> station_to_station_dist;\n    \npublic:\n    TVNetworkOptimizer() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void read_input() {\n        cin >> N >> M >> K;\n        \n        stations.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> stations[i].x >> stations[i].y;\n        }\n        \n        edges.reserve(M);\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v;\n            ll w;\n            cin >> u >> v >> w;\n            u--; v--;\n            edges.emplace_back(u, v, w, i);\n            adj[u].emplace_back(v, w);\n            adj[v].emplace_back(u, w);\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].x >> residents[i].y;\n        }\n        \n        // Precompute distances\n        compute_distances();\n    }\n    \n    void compute_distances() {\n        station_to_resident_dist.resize(N, vector<double>(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                station_to_resident_dist[i][j] = stations[i].dist(residents[j]);\n            }\n        }\n        \n        station_to_station_dist.resize(N, vector<double>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                station_to_station_dist[i][j] = stations[i].dist(stations[j]);\n            }\n        }\n    }\n    \n    // Build initial MST solution\n    Solution build_mst_solution() {\n        Solution sol(N, M);\n        \n        // Prim's algorithm for MST\n        vector<bool> in_mst(N, false);\n        vector<ll> min_edge(N, numeric_limits<ll>::max());\n        vector<int> parent(N, -1);\n        \n        min_edge[0] = 0;\n        \n        for (int i = 0; i < N; i++) {\n            int u = -1;\n            for (int v = 0; v < N; v++) {\n                if (!in_mst[v] && (u == -1 || min_edge[v] < min_edge[u])) {\n                    u = v;\n                }\n            }\n            \n            if (min_edge[u] == numeric_limits<ll>::max()) break;\n            \n            in_mst[u] = true;\n            \n            if (parent[u] != -1) {\n                // Find the edge between u and parent[u]\n                for (const auto& edge : edges) {\n                    if ((edge.u == u && edge.v == parent[u]) || \n                        (edge.u == parent[u] && edge.v == u)) {\n                        sol.B[edge.idx] = 1;\n                        sol.cost += edge.w;\n                        break;\n                    }\n                }\n            }\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!in_mst[v] && w < min_edge[v]) {\n                    min_edge[v] = w;\n                    parent[v] = u;\n                }\n            }\n        }\n        \n        // Assign powers to cover residents\n        assign_powers(sol);\n        \n        return sol;\n    }\n    \n    // Assign powers to vertices to cover residents\n    void assign_powers(Solution& sol) {\n        vector<bool> covered(K, false);\n        sol.covered = 0;\n        \n        // First, find which vertices are reachable from vertex 1\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find the closest reachable station\n        vector<vector<int>> assignments(N);\n        for (int k = 0; k < K; k++) {\n            double min_dist = numeric_limits<double>::max();\n            int best_station = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (reachable[i] && station_to_resident_dist[i][k] < min_dist) {\n                    min_dist = station_to_resident_dist[i][k];\n                    best_station = i;\n                }\n            }\n            \n            if (best_station != -1) {\n                assignments[best_station].push_back(k);\n            }\n        }\n        \n        // Calculate power for each station\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            if (!assignments[i].empty()) {\n                double max_dist = 0;\n                for (int k : assignments[i]) {\n                    max_dist = max(max_dist, station_to_resident_dist[i][k]);\n                }\n                sol.P[i] = min(5000, static_cast<int>(ceil(max_dist)));\n                power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n                \n                for (int k : assignments[i]) {\n                    if (!covered[k]) {\n                        covered[k] = true;\n                        sol.covered++;\n                    }\n                }\n            } else {\n                sol.P[i] = 0;\n            }\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    // Find vertices reachable from vertex 1\n    vector<bool> find_reachable(const vector<int>& B) {\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!reachable[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                reachable[v] = true;\n                                q.push(v);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return reachable;\n    }\n    \n    // Calculate total edge cost\n    ll get_edge_cost(const vector<int>& B) {\n        ll cost = 0;\n        for (int i = 0; i < M; i++) {\n            if (B[i]) {\n                cost += edges[i].w;\n            }\n        }\n        return cost;\n    }\n    \n    // Try to improve solution by adding/removing edges\n    Solution local_search(const Solution& initial_sol) {\n        Solution best_sol = initial_sol;\n        Solution current_sol = initial_sol;\n        \n        uniform_int_distribution<int> edge_dist(0, M-1);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        double temperature = 1000.0;\n        double cooling_rate = 0.995;\n        int iterations = 10000;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Try random edge operation\n            int edge_idx = edge_dist(rng);\n            Solution new_sol = current_sol;\n            \n            if (new_sol.B[edge_idx] == 1) {\n                // Try removing edge\n                new_sol.B[edge_idx] = 0;\n                if (is_connected(new_sol.B)) {\n                    assign_powers(new_sol);\n                } else {\n                    new_sol.B[edge_idx] = 1; // Revert if disconnected\n                }\n            } else {\n                // Try adding edge\n                new_sol.B[edge_idx] = 1;\n                assign_powers(new_sol);\n            }\n            \n            // Accept or reject based on simulated annealing\n            if (accept_solution(current_sol, new_sol, temperature)) {\n                current_sol = new_sol;\n                if (current_sol.covered == K && \n                    (best_sol.covered < K || current_sol.cost < best_sol.cost)) {\n                    best_sol = current_sol;\n                }\n            }\n            \n            temperature *= cooling_rate;\n        }\n        \n        return best_sol;\n    }\n    \n    // Check if the graph with selected edges is connected\n    bool is_connected(const vector<int>& B) {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!visited[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                visited[v] = true;\n                                q.push(v);\n                                count++;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return count == N;\n    }\n    \n    // Simulated annealing acceptance criterion\n    bool accept_solution(const Solution& current, const Solution& new_sol, double temperature) {\n        if (new_sol.covered > current.covered) return true;\n        if (new_sol.covered < current.covered) return false;\n        \n        if (new_sol.cost < current.cost) return true;\n        \n        if (temperature < 1e-6) return false;\n        \n        double delta = new_sol.cost - current.cost;\n        double prob = exp(-delta / temperature);\n        \n        uniform_real_distribution<double> dist(0.0, 1.0);\n        return dist(rng) < prob;\n    }\n    \n    // Optimize power assignments given fixed network\n    void optimize_powers(Solution& sol) {\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find all stations that can cover it\n        vector<vector<int>> covering_stations(K);\n        for (int k = 0; k < K; k++) {\n            for (int i = 0; i < N; i++) {\n                if (reachable[i]) {\n                    double dist = station_to_resident_dist[i][k];\n                    if (dist <= 5000) {\n                        covering_stations[k].push_back(i);\n                    }\n                }\n            }\n        }\n        \n        // Greedily assign residents to minimize total power cost\n        vector<bool> covered(K, false);\n        vector<int> assignments(K, -1);\n        sol.covered = 0;\n        \n        // Sort residents by number of covering stations (ascending)\n        vector<int> resident_order(K);\n        for (int k = 0; k < K; k++) resident_order[k] = k;\n        sort(resident_order.begin(), resident_order.end(), \n             [&](int a, int b) { \n                 return covering_stations[a].size() < covering_stations[b].size(); \n             });\n        \n        for (int k : resident_order) {\n            if (covered[k]) continue;\n            \n            // Find best station for this resident\n            int best_station = -1;\n            double best_cost = numeric_limits<double>::max();\n            \n            for (int station : covering_stations[k]) {\n                double dist = station_to_resident_dist[station][k];\n                double additional_cost = dist * dist;\n                \n                // Check how many additional residents this station would cover\n                int additional_cover = 0;\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && station_to_resident_dist[station][other] <= dist) {\n                        additional_cover++;\n                    }\n                }\n                \n                double cost_per_resident = additional_cost / max(1, additional_cover);\n                \n                if (cost_per_resident < best_cost) {\n                    best_cost = cost_per_resident;\n                    best_station = station;\n                }\n            }\n            \n            if (best_station != -1) {\n                double required_power = station_to_resident_dist[best_station][k];\n                \n                // Assign this resident and others that can be covered\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && \n                        station_to_resident_dist[best_station][other] <= required_power) {\n                        covered[other] = true;\n                        assignments[other] = best_station;\n                        sol.covered++;\n                    }\n                }\n            }\n        }\n        \n        // Set powers based on assignments\n        vector<double> max_power(N, 0.0);\n        for (int k = 0; k < K; k++) {\n            if (assignments[k] != -1) {\n                max_power[assignments[k]] = max(max_power[assignments[k]], \n                                               station_to_resident_dist[assignments[k]][k]);\n            }\n        }\n        \n        // Calculate power cost\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            sol.P[i] = min(5000, static_cast<int>(ceil(max_power[i])));\n            power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    void solve() {\n        // Build initial MST solution\n        Solution sol = build_mst_solution();\n        \n        // Optimize power assignments\n        optimize_powers(sol);\n        best_solution = sol;\n        \n        // Run local search with simulated annealing\n        for (int trial = 0; trial < 5; trial++) {\n            Solution improved = local_search(best_solution);\n            optimize_powers(improved);\n            \n            if (improved.covered == K && \n                (best_solution.covered < K || improved.cost < best_solution.cost)) {\n                best_solution = improved;\n            }\n        }\n        \n        // Final power optimization\n        optimize_powers(best_solution);\n        \n        // Output solution\n        output_solution(best_solution);\n    }\n    \n    void output_solution(const Solution& sol) {\n        for (int i = 0; i < N; i++) {\n            cout << sol.P[i];\n            if (i < N - 1) cout << \" \";\n        }\n        cout << endl;\n        \n        for (int i = 0; i < M; i++) {\n            cout << sol.B[i];\n            if (i < M - 1) cout << \" \";\n        }\n        cout << endl;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TVNetworkOptimizer optimizer;\n    optimizer.read_input();\n    optimizer.solve();\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n\nusing namespace std;\n\nvector<vector<int>> pyramid;\nvector<tuple<int, int, int, int>> operations;\n\n// Check if two positions are adjacent\nbool is_adjacent(int x1, int y1, int x2, int y2) {\n    return (x1 == x2 - 1 && y1 == y2 - 1) ||\n           (x1 == x2 - 1 && y1 == y2) ||\n           (x1 == x2 && y1 == y2 - 1) ||\n           (x1 == x2 && y1 == y2 + 1) ||\n           (x1 == x2 + 1 && y1 == y2) ||\n           (x1 == x2 + 1 && y1 == y2 + 1);\n}\n\n// Count the number of violations\nint count_violations() {\n    int violations = 0;\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) violations++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) violations++;\n        }\n    }\n    return violations;\n}\n\n// Swap two balls and record the operation\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    if (!is_adjacent(x1, y1, x2, y2)) {\n        cerr << \"Error: Attempting to swap non-adjacent balls\" << endl;\n        return;\n    }\n    operations.emplace_back(x1, y1, x2, y2);\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n}\n\n// Top-down pass: ensure each ball is smaller than those below it\nvoid top_down_pass() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            int left_child = pyramid[x+1][y];\n            int right_child = pyramid[x+1][y+1];\n            \n            if (current > left_child || current > right_child) {\n                // Find the smaller child\n                if (left_child < right_child) {\n                    // Swap with left child\n                    swap_balls(x, y, x+1, y);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                } else {\n                    // Swap with right child\n                    swap_balls(x, y, x+1, y+1);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y+1;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Bubble up larger numbers towards the bottom\nvoid bubble_up() {\n    for (int x = 28; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check if current is larger than its parent\n            if (x > 0) {\n                int parent_y = -1;\n                if (y <= x-1 && pyramid[x-1][y] < current) {\n                    parent_y = y;\n                } else if (y > 0 && pyramid[x-1][y-1] < current) {\n                    parent_y = y-1;\n                }\n                \n                if (parent_y != -1) {\n                    // Swap with parent\n                    swap_balls(x, y, x-1, parent_y);\n                }\n            }\n        }\n    }\n}\n\n// Local refinement: fix specific violations\nvoid local_refinement() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check violation with left child\n            if (current > pyramid[x+1][y]) {\n                // Try to find a better position for current\n                bool found = false;\n                \n                // Check adjacent positions\n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    // Just swap with the child\n                    swap_balls(x, y, x+1, y);\n                }\n            }\n            \n            // Check violation with right child\n            if (current > pyramid[x+1][y+1]) {\n                // Similar logic as above\n                bool found = false;\n                \n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    swap_balls(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    pyramid.resize(30);\n    for (int x = 0; x < 30; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Apply our algorithm\n    int max_operations = 10000;\n    \n    // Initial top-down pass\n    top_down_pass();\n    \n    // Iterative improvement\n    while (operations.size() < max_operations) {\n        int violations_before = count_violations();\n        if (violations_before == 0) break;\n        \n        // Try different strategies\n        if (operations.size() % 3 == 0) {\n            bubble_up();\n        } else if (operations.size() % 3 == 1) {\n            top_down_pass();\n        } else {\n            local_refinement();\n        }\n        \n        // Check if we're making progress\n        int violations_after = count_violations();\n        if (violations_after >= violations_before) {\n            // Not making progress, try a different approach\n            break;\n        }\n    }\n    \n    // Final pass to fix remaining violations\n    if (operations.size() < max_operations) {\n        local_refinement();\n    }\n    \n    // Output the result\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <iomanip>\n\nusing namespace std;\n\nconst int D = 9;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nint grid[D][D];\nint base_distance[D][D];\n\nvoid bfs_base() {\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_distance[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_distance[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (base_distance[nx][ny] == -1 && grid[nx][ny] != -1) {\n                    base_distance[nx][ny] = base_distance[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nstruct BFSResult {\n    bool visited[D][D];\n    int dist[D][D];\n};\n\nBFSResult bfs_current() {\n    BFSResult res;\n    memset(res.visited, false, sizeof(res.visited));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            res.dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    res.visited[0][4] = true;\n    res.dist[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (!res.visited[nx][ny]) {\n                    if (grid[nx][ny] == 0 || grid[nx][ny] == -2) {\n                        res.visited[nx][ny] = true;\n                        res.dist[nx][ny] = res.dist[x][y] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n    }\n    return res;\n}\n\nbool check_reachability_after_placing(int i, int j, int t_d) {\n    grid[i][j] = t_d;\n    BFSResult res = bfs_current();\n    vector<pair<int, int>> container_cells;\n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            if (grid[x][y] >= 0) {\n                container_cells.push_back({x, y});\n            }\n        }\n    }\n    bool all_reachable = true;\n    for (auto [x, y] : container_cells) {\n        bool reachable = false;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (res.visited[nx][ny]) {\n                    reachable = true;\n                    break;\n                }\n            }\n        }\n        if (!reachable) {\n            all_reachable = false;\n            break;\n        }\n    }\n    grid[i][j] = 0;\n    return all_reachable;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    cin >> N;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            grid[i][j] = 0;\n        }\n    }\n    grid[0][4] = -2;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    bfs_base();\n\n    int min_base = INT_MAX, max_base = INT_MIN;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == 4) continue;\n            if (grid[i][j] == -1) continue;\n            if (base_distance[i][j] == -1) continue;\n            if (base_distance[i][j] < min_base) min_base = base_distance[i][j];\n            if (base_distance[i][j] > max_base) max_base = base_distance[i][j];\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    if (M > 0) {\n        for (int d = 0; d < M; d++) {\n            int t_d;\n            cin >> t_d;\n\n            double desired;\n            if (M == 1) {\n                desired = min_base;\n            } else {\n                desired = (double)(t_d) / (M - 1) * (max_base - min_base) + min_base;\n            }\n\n            BFSResult res1 = bfs_current();\n            vector<pair<int, int>> candidate_cells;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] == 0 && res1.visited[i][j]) {\n                        candidate_cells.push_back({i, j});\n                    }\n                }\n            }\n\n            vector<pair<int, int>> valid_candidates;\n            vector<double> costs;\n            vector<int> current_dists;\n\n            for (auto [i, j] : candidate_cells) {\n                if (check_reachability_after_placing(i, j, t_d)) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            if (valid_candidates.empty()) {\n                for (auto [i, j] : candidate_cells) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            int best_index = 0;\n            for (int idx = 1; idx < valid_candidates.size(); idx++) {\n                if (costs[idx] < costs[best_index]) {\n                    best_index = idx;\n                } else if (costs[idx] == costs[best_index]) {\n                    if (current_dists[idx] < current_dists[best_index]) {\n                        best_index = idx;\n                    } else if (current_dists[idx] == current_dists[best_index]) {\n                        if (base_distance[valid_candidates[idx].first][valid_candidates[idx].second] < \n                            base_distance[valid_candidates[best_index].first][valid_candidates[best_index].second]) {\n                            best_index = idx;\n                        }\n                    }\n                }\n            }\n\n            auto [i, j] = valid_candidates[best_index];\n            grid[i][j] = t_d;\n            cout << i << \" \" << j << endl;\n            cout.flush();\n        }\n    }\n\n    if (M > 0) {\n        vector<pair<int, int>> transport_order;\n        for (int step = 0; step < M; step++) {\n            BFSResult res = bfs_current();\n            vector<pair<int, int>> reachable_containers;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] >= 0) {\n                        for (int d = 0; d < 4; d++) {\n                            int ni = i + dx[d], nj = j + dy[d];\n                            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                                if (res.visited[ni][nj]) {\n                                    reachable_containers.push_back({i, j});\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int min_number = INT_MAX;\n            pair<int, int> min_cell = {-1, -1};\n            for (auto [i, j] : reachable_containers) {\n                if (grid[i][j] < min_number) {\n                    min_number = grid[i][j];\n                    min_cell = {i, j};\n                }\n            }\n\n            grid[min_cell.first][min_cell.second] = 0;\n            transport_order.push_back(min_cell);\n        }\n\n        for (auto [i, j] : transport_order) {\n            cout << i << \" \" << j << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nconst int dx[4] = {1, 0, -1, 0};\nconst int dy[4] = {0, 1, 0, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<vector<bool>> adj(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 = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    adj[c1][0] = true;\n                    adj[0][c1] = true;\n                } else {\n                    int c2 = grid[ni][nj];\n                    if (c1 != c2) {\n                        adj[c1][c2] = true;\n                        adj[c2][c1] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> new_grid(n, vector<int>(n, -1));\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<tuple<int, int, int>> q;\n\n    vector<int> A;\n    for (int c = 1; c <= m; c++) {\n        if (adj[c][0]) {\n            A.push_back(c);\n        }\n    }\n\n    vector<vector<int>> H(A.size());\n    for (int i = 0; i < A.size(); i++) {\n        for (int j = i+1; j < A.size(); j++) {\n            if (adj[A[i]][A[j]]) {\n                H[i].push_back(j);\n                H[j].push_back(i);\n            }\n        }\n    }\n\n    vector<int> order;\n    vector<bool> done(H.size(), false);\n    if (!H.empty()) {\n        queue<int> qq;\n        qq.push(0);\n        done[0] = true;\n        while (!qq.empty()) {\n            int u = qq.front(); qq.pop();\n            order.push_back(u);\n            for (int v : H[u]) {\n                if (!done[v]) {\n                    done[v] = true;\n                    qq.push(v);\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> boundary;\n    for (int j = 0; j < n; j++) {\n        boundary.emplace_back(0, j);\n    }\n    for (int i = 1; i < n; i++) {\n        boundary.emplace_back(i, n-1);\n    }\n    for (int j = n-2; j >= 0; j--) {\n        boundary.emplace_back(n-1, j);\n    }\n    for (int i = n-2; i >= 1; i--) {\n        boundary.emplace_back(i, 0);\n    }\n\n    vector<int> boundary_assignment;\n    if (!order.empty()) {\n        boundary_assignment.push_back(A[order[0]]);\n        for (int i = 1; i < order.size(); i++) {\n            int u = order[i-1];\n            int v = order[i];\n            bool adj_in_H = false;\n            for (int w : H[u]) {\n                if (w == v) {\n                    adj_in_H = true;\n                    break;\n                }\n            }\n            if (!adj_in_H) {\n                boundary_assignment.push_back(0);\n            }\n            boundary_assignment.push_back(A[v]);\n        }\n        int u = order.back();\n        int v = order[0];\n        bool adj_in_H = false;\n        for (int w : H[u]) {\n            if (w == v) {\n                adj_in_H = true;\n                break;\n            }\n        }\n        if (!adj_in_H) {\n            boundary_assignment.push_back(0);\n        }\n    }\n\n    for (int idx = 0; idx < boundary.size(); idx++) {\n        int color = (idx < boundary_assignment.size()) ? boundary_assignment[idx] : 0;\n        int i = boundary[idx].first;\n        int j = boundary[idx].second;\n        new_grid[i][j] = color;\n        visited[i][j] = true;\n        if (color != 0) {\n            q.push({i, j, color});\n        }\n    }\n\n    while (!q.empty()) {\n        auto [i, j, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n            if (visited[ni][nj]) continue;\n            bool can_assign = true;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + dx[dd];\n                int nnj = nj + dy[dd];\n                if (nni < 0 || nni >= n || nnj < 0 || nnj >= n) continue;\n                if (new_grid[nni][nnj] == -1) continue;\n                int d_color = new_grid[nni][nnj];\n                if (d_color == 0) continue;\n                if (d_color == c) continue;\n                if (!adj[c][d_color]) {\n                    can_assign = false;\n                    break;\n                }\n            }\n            if (can_assign) {\n                new_grid[ni][nj] = c;\n                visited[ni][nj] = true;\n                q.push({ni, nj, c});\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (new_grid[i][j] == -1) {\n                new_grid[i][j] = 0;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << new_grid[i][j] << (j < n-1 ? ' ' : '\\n');\n        }\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\n\n// Random number generator with proper seeding\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to output a query and get the result\nchar query(int nL, int nR, const vector<int>& L, const vector<int>& R) {\n    cout << nL << \" \" << nR;\n    for (int i : L) cout << \" \" << i;\n    for (int i : R) cout << \" \" << i;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\n// Function to partition items into D sets based on estimated weights\nvector<int> partition_items(int N, int D, const vector<double>& estimated_weights) {\n    // Create pairs of (item_index, estimated_weight)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.emplace_back(estimated_weights[i], i);\n    }\n    \n    // Sort items by estimated weight in descending order\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize D sets\n    vector<double> set_weights(D, 0.0);\n    vector<int> assignment(N, -1);\n    \n    // Greedy assignment: assign each item to the set with the smallest current total weight\n    for (const auto& [weight, idx] : items) {\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        assignment[idx] = min_set;\n        set_weights[min_set] += weight;\n    }\n    \n    // Improvement phase 1: Try to balance by swapping items between sets\n    for (int iter = 0; iter < 100; iter++) {\n        // Calculate the current variance\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        double variance = 0.0;\n        for (double w : set_weights) {\n            variance += (w - mean) * (w - mean);\n        }\n        variance /= D;\n        \n        // Try to find a swap that reduces the variance\n        bool improved = false;\n        \n        // Try swaps between sets\n        for (int trial = 0; trial < 50; trial++) {\n            int i = rng() % N;\n            int j = rng() % N;\n            while (i == j) {\n                j = rng() % N;\n            }\n            \n            if (assignment[i] != assignment[j]) {\n                // Calculate the new variance if we swap items i and j\n                int set_i = assignment[i];\n                int set_j = assignment[j];\n                \n                double new_weight_i = set_weights[set_i] - estimated_weights[i] + estimated_weights[j];\n                double new_weight_j = set_weights[set_j] - estimated_weights[j] + estimated_weights[i];\n                \n                double new_variance = variance;\n                new_variance -= (set_weights[set_i] - mean) * (set_weights[set_i] - mean) / D;\n                new_variance -= (set_weights[set_j] - mean) * (set_weights[set_j] - mean) / D;\n                new_variance += (new_weight_i - mean) * (new_weight_i - mean) / D;\n                new_variance += (new_weight_j - mean) * (new_weight_j - mean) / D;\n                \n                if (new_variance < variance) {\n                    // Swap the items\n                    assignment[i] = set_j;\n                    assignment[j] = set_i;\n                    set_weights[set_i] = new_weight_i;\n                    set_weights[set_j] = new_weight_j;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Improvement phase 2: Try to move items to balance sets\n    for (int iter = 0; iter < 50; iter++) {\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        \n        // Find the set with the highest weight and the set with the lowest weight\n        int max_set = max_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        \n        if (set_weights[max_set] - set_weights[min_set] < 1e-6) break;\n        \n        // Find an item in the max_set that can be moved to min_set to reduce difference\n        bool moved = false;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == max_set) {\n                double new_max = set_weights[max_set] - estimated_weights[i];\n                double new_min = set_weights[min_set] + estimated_weights[i];\n                \n                double current_diff = set_weights[max_set] - set_weights[min_set];\n                double new_diff = abs(new_max - new_min);\n                \n                if (new_diff < current_diff) {\n                    // Move the item\n                    assignment[i] = min_set;\n                    set_weights[max_set] = new_max;\n                    set_weights[min_set] = new_min;\n                    moved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!moved) break;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Initialize estimated weights\n    vector<double> estimated_weights(N, 1.0);\n    \n    // Keep track of how many times each item has been compared\n    vector<int> compare_count(N, 0);\n    \n    // Use queries to estimate relative weights\n    for (int q = 0; q < Q; q++) {\n        if (q < Q / 2) {\n            // First half: Compare individual items using tournament method\n            // Find two items with the lowest comparison counts\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            int i = -1, j = -1;\n            for (int idx : indices) {\n                if (i == -1) {\n                    i = idx;\n                } else if (j == -1) {\n                    j = idx;\n                    break;\n                }\n            }\n            \n            char result = query(1, 1, {i}, {j});\n            compare_count[i]++;\n            compare_count[j]++;\n            \n            // Update estimates based on result\n            double adjustment = 0.15;\n            if (result == '>') {\n                estimated_weights[i] *= (1.0 + adjustment);\n                estimated_weights[j] *= (1.0 - adjustment);\n            } else if (result == '<') {\n                estimated_weights[i] *= (1.0 - adjustment);\n                estimated_weights[j] *= (1.0 + adjustment);\n            }\n        } else {\n            // Second half: Compare groups of items to refine estimates\n            // Sort items by estimated weight\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return estimated_weights[a] < estimated_weights[b];\n            });\n            \n            // Create two groups of similar weight items\n            int group_size = 2 + rng() % min(4, N / 5);\n            int start = rng() % (N - 2 * group_size);\n            \n            vector<int> group1, group2;\n            for (int k = 0; k < group_size; k++) {\n                group1.push_back(indices[start + k]);\n                group2.push_back(indices[start + group_size + k]);\n            }\n            \n            char result = query(group_size, group_size, group1, group2);\n            \n            // Update estimates based on result\n            double adjustment = 0.08;\n            if (result == '>') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n            } else if (result == '<') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n            }\n            \n            for (int k : group1) compare_count[k]++;\n            for (int k : group2) compare_count[k]++;\n        }\n    }\n    \n    // Normalize estimated weights to a reasonable scale\n    double min_weight = *min_element(estimated_weights.begin(), estimated_weights.end());\n    for (int i = 0; i < N; i++) {\n        estimated_weights[i] /= min_weight;\n    }\n    \n    // Partition items into D sets\n    vector<int> assignment = partition_items(N, D, estimated_weights);\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> position(n + 1);  // position[v] = stack_index\n    \n    // Read input and initialize data structures\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            position[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int next_box = 1;\n    \n    while (next_box <= n) {\n        // Check if next_box is at the top of any stack\n        bool found_at_top = false;\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_box) {\n                // Carry out operation\n                stacks[i].pop_back();\n                operations.emplace_back(next_box, 0);\n                next_box++;\n                found_at_top = true;\n                break;\n            }\n        }\n        \n        if (found_at_top) continue;\n        \n        // Find the stack containing next_box\n        int stack_idx = -1;\n        int pos_in_stack = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                if (stacks[i][j] == next_box) {\n                    stack_idx = i;\n                    pos_in_stack = j;\n                    break;\n                }\n            }\n            if (stack_idx != -1) break;\n        }\n        \n        // The box immediately above next_box\n        int box_above = stacks[stack_idx][pos_in_stack + 1];\n        \n        // Choose destination stack\n        int best_dest = -1;\n        \n        // Prefer empty stacks\n        for (int i = 0; i < m; i++) {\n            if (i != stack_idx && stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n        }\n        \n        // If no empty stack, prefer stacks with larger bottom elements\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx && !stacks[i].empty() && stacks[i][0] > next_box) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Otherwise, choose any non-source stack\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Move boxes above next_box (including box_above) to destination\n        vector<int> moved_boxes;\n        for (int i = pos_in_stack + 1; i < stacks[stack_idx].size(); i++) {\n            moved_boxes.push_back(stacks[stack_idx][i]);\n            position[stacks[stack_idx][i]] = best_dest;\n        }\n        \n        // Update source stack\n        stacks[stack_idx].resize(pos_in_stack + 1);\n        \n        // Update destination stack\n        stacks[best_dest].insert(stacks[best_dest].end(), \n                                 moved_boxes.begin(), moved_boxes.end());\n        \n        // Record operation\n        operations.emplace_back(box_above, best_dest + 1);\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <utility>\n#include <unordered_set>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    Point operator+(const Point& other) const {\n        return Point(i + other.i, j + other.j);\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<Point> {\n        size_t operator()(const Point& p) const {\n            return static_cast<size_t>(p.i) * 1000 + p.j;\n        }\n    };\n}\n\nclass Solution {\npublic:\n    int N;\n    vector<string> h, v;\n    vector<vector<int>> d;\n    vector<vector<bool>> visited;\n    vector<Point> path;\n    string route;\n    \n    // Directions: R, D, L, U\n    const vector<Point> directions = {Point(0, 1), Point(1, 0), Point(0, -1), Point(-1, 0)};\n    const string dir_chars = \"RDLU\";\n    \n    Solution(int n, const vector<string>& h, const vector<string>& v, const vector<vector<int>>& d)\n        : N(n), h(h), v(v), d(d), visited(n, vector<bool>(n, false)) {\n        // Initialize path with starting point\n        path.emplace_back(0, 0);\n    }\n    \n    bool can_move(const Point& from, const Point& to) const {\n        if (to.i < 0 || to.i >= N || to.j < 0 || to.j >= N) return false;\n        \n        // Check horizontal wall\n        if (from.i == to.i) {\n            int j = min(from.j, to.j);\n            if (v[from.i][j] == '1') return false;\n        }\n        // Check vertical wall\n        else if (from.j == to.j) {\n            int i = min(from.i, to.i);\n            if (h[i][from.j] == '1') return false;\n        }\n        return true;\n    }\n    \n    void dfs(Point p) {\n        visited[p.i][p.j] = true;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            Point next = p + directions[dir];\n            if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                !visited[next.i][next.j] && can_move(p, next)) {\n                path.push_back(next);\n                route += dir_chars[dir];\n                dfs(next);\n                path.push_back(p);\n                route += dir_chars[(dir + 2) % 4];\n            }\n        }\n    }\n    \n    vector<Point> bfs(const Point& start, const Point& end) {\n        vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n        vector<vector<bool>> bfs_visited(N, vector<bool>(N, false));\n        queue<Point> q;\n        \n        q.push(start);\n        bfs_visited[start.i][start.j] = true;\n        \n        while (!q.empty()) {\n            Point current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Point> result;\n                Point p = end;\n                while (p != start) {\n                    result.push_back(p);\n                    p = parent[p.i][p.j];\n                }\n                result.push_back(start);\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (const Point& dir : directions) {\n                Point next = current + dir;\n                if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                    !bfs_visited[next.i][next.j] && can_move(current, next)) {\n                    bfs_visited[next.i][next.j] = true;\n                    parent[next.i][next.j] = current;\n                    q.push(next);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    string get_route_string(const vector<Point>& path) {\n        string result;\n        for (size_t i = 1; i < path.size(); i++) {\n            Point from = path[i-1];\n            Point to = path[i];\n            for (int dir = 0; dir < 4; dir++) {\n                if (from + directions[dir] == to) {\n                    result += dir_chars[dir];\n                    break;\n                }\n            }\n        }\n        return result;\n    }\n    \n    void optimize_route() {\n        // Find cells with high dirt susceptibility\n        vector<pair<int, Point>> high_dirt_cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                high_dirt_cells.emplace_back(d[i][j], Point(i, j));\n            }\n        }\n        sort(high_dirt_cells.rbegin(), high_dirt_cells.rend());\n        \n        // Try to create shortcuts to high dirt cells\n        for (int iter = 0; iter < 100; iter++) {\n            if (route.length() > 90000) break; // Don't exceed the limit\n            \n            // Select a random high dirt cell\n            int idx = rng() % min(10, (int)high_dirt_cells.size());\n            Point target = high_dirt_cells[idx].second;\n            \n            // Find random positions in the current path\n            int pos1 = rng() % (path.size() - 1);\n            int pos2 = rng() % (path.size() - 1);\n            if (pos1 > pos2) swap(pos1, pos2);\n            \n            // Try to create a shortcut from pos1 to target and back to pos2\n            vector<Point> path1 = bfs(path[pos1], target);\n            vector<Point> path2 = bfs(target, path[pos2]);\n            \n            if (!path1.empty() && !path2.empty() && \n                path1.size() + path2.size() < pos2 - pos1) {\n                // Create new path\n                vector<Point> new_path;\n                for (int i = 0; i <= pos1; i++) {\n                    new_path.push_back(path[i]);\n                }\n                for (size_t i = 1; i < path1.size(); i++) {\n                    new_path.push_back(path1[i]);\n                }\n                for (size_t i = 1; i < path2.size(); i++) {\n                    new_path.push_back(path2[i]);\n                }\n                for (size_t i = pos2 + 1; i < path.size(); i++) {\n                    new_path.push_back(path[i]);\n                }\n                \n                // Update path and route\n                path = new_path;\n                route = get_route_string(path);\n            }\n        }\n        \n        // Ensure we return to (0,0)\n        if (path.back() != Point(0, 0)) {\n            vector<Point> return_path = bfs(path.back(), Point(0, 0));\n            for (size_t i = 1; i < return_path.size(); i++) {\n                path.push_back(return_path[i]);\n            }\n            route = get_route_string(path);\n        }\n        \n        // Ensure length constraint\n        if (route.length() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    \n    string solve() {\n        // Generate initial route using DFS\n        dfs(Point(0, 0));\n        \n        // Optimize the route\n        optimize_route();\n        \n        return route;\n    }\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> d(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    Solution solution(N, h, v, d);\n    string route = solution.solve();\n    cout << route << endl;\n    \n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct TargetInfo {\n    string target;\n    int prefix_len;\n    TargetInfo(string t, int pl) : target(t), prefix_len(pl) {}\n    bool operator<(const TargetInfo& other) const {\n        return prefix_len < other.prefix_len; // Longer prefixes first\n    }\n};\n\nint main() {\n    srand(time(0));\n\n    int N, M;\n    cin >> N >> M;\n    int s_i, s_j;\n    cin >> s_i >> s_j;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<string> targets(M);\n    set<string> uncovered_targets;\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n        uncovered_targets.insert(targets[i]);\n    }\n\n    map<string, int> prefix_count;\n    map<string, map<char, int>> next_char_count;\n    priority_queue<TargetInfo> target_queue;\n\n    for (const string& t : targets) {\n        for (int len = 1; len <= 4; len++) {\n            string p = t.substr(0, len);\n            prefix_count[p]++;\n        }\n        for (int len = 0; len < 5; len++) {\n            string p = t.substr(0, len);\n            if (len < 5) {\n                char next_char = t[len];\n                next_char_count[p][next_char]++;\n            }\n        }\n        target_queue.push(TargetInfo(t, 0));\n    }\n\n    int current_i = s_i, current_j = s_j;\n    string current_last4 = string(1, grid[s_i][s_j]);\n    vector<pair<int, int>> path;\n    path.emplace_back(s_i, s_j);\n\n    int steps_since_cover = 0;\n    int total_covered = 0;\n\n    for (int step = 1; step < 5000; step++) {\n        double best_score = -1e18;\n        pair<int, int> best_move = {-1, -1};\n        string best_new_last4;\n        string best_completed_target = \"\";\n\n        // Dynamic bonus based on progress\n        double completion_bonus = 1000000.0 * (1.0 + (double)total_covered / M);\n\n        // Check if we need to explore randomly\n        if (steps_since_cover > 50) {\n            int random_i = rand() % N;\n            int random_j = rand() % N;\n            best_move = {random_i, random_j};\n            steps_since_cover = 0; // Reset counter\n        } else {\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    char c = grid[i][j];\n                    int cost_move = abs(current_i - i) + abs(current_j - j) + 1;\n\n                    string new_last4;\n                    if (current_last4.size() == 4) {\n                        new_last4 = current_last4.substr(1) + c;\n                    } else {\n                        new_last4 = current_last4 + c;\n                    }\n\n                    double score = -cost_move;\n\n                    // Type 1: Complete a target\n                    if (current_last4.size() == 4) {\n                        string candidate = current_last4 + c;\n                        if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                            score += completion_bonus;\n                        }\n                    }\n\n                    // Type 2: Extend existing prefix\n                    if (next_char_count.find(current_last4) != next_char_count.end()) {\n                        const auto& char_count = next_char_count.at(current_last4);\n                        auto it = char_count.find(c);\n                        if (it != char_count.end()) {\n                            // Higher bonus for longer prefixes\n                            score += 10000.0 * it->second * (current_last4.size() + 1);\n                        }\n                    }\n\n                    // Type 3: Create new prefix\n                    if (prefix_count.find(new_last4) != prefix_count.end()) {\n                        score += 1000.0 * prefix_count.at(new_last4);\n                    }\n\n                    // Small random component for exploration\n                    score += (rand() % 1000) * 0.1;\n\n                    if (score > best_score) {\n                        best_score = score;\n                        best_move = {i, j};\n                        best_new_last4 = new_last4;\n                        if (current_last4.size() == 4) {\n                            string candidate = current_last4 + c;\n                            if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                                best_completed_target = candidate;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Make the move\n        path.push_back(best_move);\n        current_i = best_move.first;\n        current_j = best_move.second;\n        current_last4 = best_new_last4;\n\n        // Update if we completed a target\n        if (!best_completed_target.empty()) {\n            uncovered_targets.erase(best_completed_target);\n            total_covered++;\n            steps_since_cover = 0;\n\n            // Update data structures\n            for (int len = 1; len <= 4; len++) {\n                string p = best_completed_target.substr(0, len);\n                prefix_count[p]--;\n            }\n            for (int len = 0; len < 5; len++) {\n                string p = best_completed_target.substr(0, len);\n                if (len < 5) {\n                    char next_char = best_completed_target[len];\n                    next_char_count[p][next_char]--;\n                }\n            }\n        } else {\n            steps_since_cover++;\n        }\n\n        if (uncovered_targets.empty()) {\n            break;\n        }\n    }\n\n    for (const auto& p : path) {\n        cout << p.first << \" \" << p.second << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        return tie(i, j) < tie(other.i, other.j);\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct OilField {\n    vector<Point> cells;\n    int size;\n};\n\nstruct GridInfo {\n    int N, M;\n    double epsilon;\n    vector<OilField> oil_fields;\n    vector<vector<int>> drilled_values;\n    vector<vector<double>> estimated_values;\n    set<Point> oil_squares;\n    \n    GridInfo(int N, int M, double epsilon) : N(N), M(M), epsilon(epsilon) {\n        drilled_values.assign(N, vector<int>(N, -1));\n        estimated_values.assign(N, vector<double>(N, 0.0));\n    }\n};\n\nvoid read_input(GridInfo& grid) {\n    cin >> grid.N >> grid.M >> grid.epsilon;\n    grid.oil_fields.resize(grid.M);\n    \n    for (int k = 0; k < grid.M; ++k) {\n        int d;\n        cin >> d;\n        grid.oil_fields[k].size = d;\n        grid.oil_fields[k].cells.resize(d);\n        for (int i = 0; i < d; ++i) {\n            cin >> grid.oil_fields[k].cells[i].i >> grid.oil_fields[k].cells[i].j;\n        }\n    }\n}\n\nint drill(GridInfo& grid, int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    grid.drilled_values[i][j] = value;\n    grid.estimated_values[i][j] = value;\n    if (value > 0) {\n        grid.oil_squares.insert(Point(i, j));\n    }\n    return value;\n}\n\nint divine(GridInfo& grid, const vector<Point>& squares) {\n    cout << \"q \" << squares.size();\n    for (const auto& p : squares) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    return value;\n}\n\nbool submit_answer(GridInfo& grid, const set<Point>& answer) {\n    cout << \"a \" << answer.size();\n    for (const auto& p : answer) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nvector<Point> get_region_points(int i1, int j1, int i2, int j2, int N) {\n    vector<Point> points;\n    for (int i = i1; i <= i2; ++i) {\n        for (int j = j1; j <= j2; ++j) {\n            if (i >= 0 && i < N && j >= 0 && j < N) {\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    return points;\n}\n\nvoid explore_grid(GridInfo& grid, int max_operations) {\n    int operations_used = 0;\n    \n    if (operations_used < max_operations) {\n        auto all_points = get_region_points(0, 0, grid.N-1, grid.N-1, grid.N);\n        if (all_points.size() >= 2) {\n            int total_oil_estimate = divine(grid, all_points);\n            operations_used++;\n            \n            double avg_oil = static_cast<double>(total_oil_estimate) / (grid.N * grid.N);\n            for (int i = 0; i < grid.N; ++i) {\n                for (int j = 0; j < grid.N; ++j) {\n                    grid.estimated_values[i][j] = avg_oil;\n                }\n            }\n        }\n    }\n    \n    queue<tuple<int, int, int, int>> regions;\n    regions.push({0, 0, grid.N-1, grid.N-1});\n    \n    while (!regions.empty() && operations_used < max_operations) {\n        auto [i1, j1, i2, j2] = regions.front();\n        regions.pop();\n        \n        auto points = get_region_points(i1, j1, i2, j2, grid.N);\n        if (points.size() < 2) continue;\n        \n        int oil_estimate = divine(grid, points);\n        operations_used++;\n        \n        if (oil_estimate > 0) {\n            int mid_i = (i1 + i2) / 2;\n            int mid_j = (j1 + j2) / 2;\n            \n            if (i2 - i1 > 1 || j2 - j1 > 1) {\n                regions.push({i1, j1, mid_i, mid_j});\n                regions.push({i1, mid_j + 1, mid_i, j2});\n                regions.push({mid_i + 1, j1, i2, mid_j});\n                regions.push({mid_i + 1, mid_j + 1, i2, j2});\n            } else {\n                for (const auto& p : points) {\n                    if (operations_used < max_operations) {\n                        drill(grid, p.i, p.j);\n                        operations_used++;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (operations_used < max_operations) {\n        vector<pair<double, Point>> candidates;\n        for (int i = 0; i < grid.N; ++i) {\n            for (int j = 0; j < grid.N; ++j) {\n                if (grid.drilled_values[i][j] == -1) {\n                    candidates.emplace_back(grid.estimated_values[i][j], Point(i, j));\n                }\n            }\n        }\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        for (const auto& [_, p] : candidates) {\n            if (operations_used >= max_operations) break;\n            drill(grid, p.i, p.j);\n            operations_used++;\n        }\n    }\n}\n\nvoid infer_oil_fields(GridInfo& grid) {\n    for (const auto& field : grid.oil_fields) {\n        vector<pair<int, Point>> possible_positions;\n        \n        for (int di = 0; di <= grid.N - field.cells.back().i; ++di) {\n            for (int dj = 0; dj <= grid.N - field.cells.back().j; ++dj) {\n                int score = 0;\n                for (const auto& cell : field.cells) {\n                    int i = di + cell.i;\n                    int j = dj + cell.j;\n                    if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                        if (grid.drilled_values[i][j] > 0) {\n                            score += grid.drilled_values[i][j];\n                        } else if (grid.drilled_values[i][j] == 0) {\n                            score = -1;\n                            break;\n                        }\n                    }\n                }\n                if (score > 0) {\n                    possible_positions.emplace_back(score, Point(di, dj));\n                }\n            }\n        }\n        \n        sort(possible_positions.rbegin(), possible_positions.rend());\n        \n        for (int idx = 0; idx < min(3, (int)possible_positions.size()); ++idx) {\n            const auto& [_, pos] = possible_positions[idx];\n            double weight = idx == 0 ? 1.0 : 0.5;\n            \n            for (const auto& cell : field.cells) {\n                int i = pos.i + cell.i;\n                int j = pos.j + cell.j;\n                if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                    if (grid.drilled_values[i][j] == -1) {\n                        grid.estimated_values[i][j] += weight;\n                    }\n                }\n            }\n        }\n    }\n}\n\nset<Point> determine_answer(GridInfo& grid) {\n    set<Point> answer;\n    \n    answer.insert(grid.oil_squares.begin(), grid.oil_squares.end());\n    \n    for (int i = 0; i < grid.N; ++i) {\n        for (int j = 0; j < grid.N; ++j) {\n            if (grid.drilled_values[i][j] == -1 && grid.estimated_values[i][j] > 0.5) {\n                answer.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return answer;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double epsilon;\n    cin >> N >> M >> epsilon;\n    \n    GridInfo grid(N, M, epsilon);\n    read_input(grid);\n    \n    int max_operations = 2 * N * N;\n    \n    explore_grid(grid, max_operations / 2);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations * 3 / 4);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations);\n    \n    set<Point> answer = determine_answer(grid);\n    \n    bool correct = submit_answer(grid, answer);\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <cassert>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    \n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int i0, int j0, int i1, int j1) : i0(i0), j0(j0), i1(i1), j1(j1) {}\n    \n    int area() const {\n        return (i1 - i0) * (j1 - j0);\n    }\n    \n    bool operator==(const Rectangle& other) const {\n        return i0 == other.i0 && j0 == other.j0 && i1 == other.i1 && j1 == other.j1;\n    }\n};\n\nstruct DayLayout {\n    vector<Rectangle> rectangles;\n    vector<vector<int>> horizontal_partitions;  // H_{d,i,j}\n    vector<vector<int>> vertical_partitions;    // V_{d,i,j}\n    \n    DayLayout(int W) {\n        horizontal_partitions.resize(W-1, vector<int>(W, 0));\n        vertical_partitions.resize(W, vector<int>(W-1, 0));\n    }\n    \n    void update_partitions(int W) {\n        // Reset partitions\n        for (auto& row : horizontal_partitions) fill(row.begin(), row.end(), 0);\n        for (auto& row : vertical_partitions) fill(row.begin(), row.end(), 0);\n        \n        // Set partitions based on rectangles\n        for (const auto& rect : rectangles) {\n            // Horizontal partitions (top and bottom edges)\n            if (rect.i0 > 0) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i0-1][j] = 1;\n                }\n            }\n            if (rect.i1 < W) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i1-1][j] = 1;\n                }\n            }\n            \n            // Vertical partitions (left and right edges)\n            if (rect.j0 > 0) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j0-1] = 1;\n                }\n            }\n            if (rect.j1 < W) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j1-1] = 1;\n                }\n            }\n        }\n    }\n};\n\nclass EventHallOptimizer {\nprivate:\n    int W, D, N;\n    vector<vector<int>> desired_areas;\n    vector<DayLayout> layouts;\n    mt19937 rng;\n    \npublic:\n    EventHallOptimizer(int W, int D, int N, const vector<vector<int>>& areas)\n        : W(W), D(D), N(N), desired_areas(areas) {\n        // Initialize random number generator\n        rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n        \n        layouts.reserve(D);\n        for (int d = 0; d < D; ++d) {\n            layouts.emplace_back(W);\n        }\n    }\n    \n    void solve() {\n        // Generate initial layout for day 0\n        generate_initial_layout(0);\n        layouts[0].update_partitions(W);\n        \n        // Generate layouts for subsequent days\n        for (int d = 1; d < D; ++d) {\n            // Start with previous day's layout as base\n            layouts[d] = layouts[d-1];\n            \n            // Optimize layout for day d\n            optimize_layout(d);\n            layouts[d].update_partitions(W);\n        }\n    }\n    \n    void generate_initial_layout(int day) {\n        vector<pair<int, int>> area_indices;\n        for (int k = 0; k < N; ++k) {\n            area_indices.emplace_back(desired_areas[day][k], k);\n        }\n        sort(area_indices.begin(), area_indices.end(), greater<pair<int, int>>());\n        \n        vector<Rectangle> rects(N);\n        vector<bool> used(N, false);\n        \n        // Use a space-filling curve approach\n        int current_i = 0, current_j = 0;\n        \n        for (const auto& [area, idx] : area_indices) {\n            // Find best fitting rectangle\n            Rectangle best_rect;\n            int best_score = -1;\n            \n            // Try different starting positions and sizes\n            for (int start_i = current_i; start_i < W - 1; ++start_i) {\n                for (int start_j = (start_i == current_i ? current_j : 0); start_j < W - 1; ++start_j) {\n                    // Try different aspect ratios\n                    for (int aspect = 1; aspect <= 4; ++aspect) {\n                        int height = sqrt(area * aspect);\n                        int width = area / height;\n                        if (width * height < area) width++;\n                        \n                        // Ensure rectangle fits\n                        if (start_i + height > W || start_j + width > W) continue;\n                        \n                        Rectangle rect(start_i, start_j, start_i + height, start_j + width);\n                        \n                        // Check for overlaps\n                        bool overlap = false;\n                        for (int k = 0; k < N; ++k) {\n                            if (used[k] && rectangles_overlap(rect, rects[k])) {\n                                overlap = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!overlap) {\n                            int score = rect.area();\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (best_score == -1) {\n                // Fallback: place at current position with minimum size\n                int side = ceil(sqrt(area));\n                best_rect = Rectangle(current_i, current_j, \n                                    min(current_i + side, W), \n                                    min(current_j + side, W));\n            }\n            \n            rects[idx] = best_rect;\n            used[idx] = true;\n            \n            // Update current position\n            current_j = best_rect.j1;\n            if (current_j >= W - 1) {\n                current_j = 0;\n                current_i = best_rect.i1;\n            }\n        }\n        \n        layouts[day].rectangles = rects;\n    }\n    \n    void optimize_layout(int day) {\n        const double initial_temp = 1000.0;\n        const double cooling_rate = 0.95;\n        const int iterations = 1000;\n        \n        double temp = initial_temp;\n        vector<Rectangle> current_rects = layouts[day].rectangles;\n        int current_cost = calculate_total_cost(day, current_rects);\n        \n        for (int iter = 0; iter < iterations; ++iter) {\n            // Generate neighbor solution\n            vector<Rectangle> neighbor_rects = current_rects;\n            apply_random_move(day, neighbor_rects);\n            \n            // Calculate cost\n            int neighbor_cost = calculate_total_cost(day, neighbor_rects);\n            \n            // Accept or reject\n            int delta = neighbor_cost - current_cost;\n            if (delta < 0 || exp(-delta / temp) > generate_random_double()) {\n                current_rects = neighbor_rects;\n                current_cost = neighbor_cost;\n            }\n            \n            // Cool down\n            temp *= cooling_rate;\n        }\n        \n        layouts[day].rectangles = current_rects;\n    }\n    \n    void apply_random_move(int day, vector<Rectangle>& rects) {\n        uniform_int_distribution<int> move_dist(0, 2);\n        int move_type = move_dist(rng);\n        \n        switch (move_type) {\n            case 0: // Resize rectangle\n                resize_random_rectangle(rects);\n                break;\n            case 1: // Move rectangle\n                move_random_rectangle(rects);\n                break;\n            case 2: // Swap two rectangles\n                swap_random_rectangles(rects);\n                break;\n        }\n        \n        // Ensure no overlaps\n        fix_overlaps(rects);\n    }\n    \n    void resize_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-10, 10);\n        int di0 = delta_dist(rng);\n        int dj0 = delta_dist(rng);\n        int di1 = delta_dist(rng);\n        int dj1 = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        rect.i0 = max(0, min(W-1, rect.i0 + di0));\n        rect.j0 = max(0, min(W-1, rect.j0 + dj0));\n        rect.i1 = max(rect.i0+1, min(W, rect.i1 + di1));\n        rect.j1 = max(rect.j0+1, min(W, rect.j1 + dj1));\n    }\n    \n    void move_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-5, 5);\n        int di = delta_dist(rng);\n        int dj = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        int height = rect.i1 - rect.i0;\n        int width = rect.j1 - rect.j0;\n        \n        rect.i0 = max(0, min(W - height, rect.i0 + di));\n        rect.j0 = max(0, min(W - width, rect.j0 + dj));\n        rect.i1 = rect.i0 + height;\n        rect.j1 = rect.j0 + width;\n    }\n    \n    void swap_random_rectangles(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx1 = rect_dist(rng);\n        int idx2 = rect_dist(rng);\n        \n        if (idx1 != idx2) {\n            swap(rects[idx1], rects[idx2]);\n        }\n    }\n    \n    void fix_overlaps(vector<Rectangle>& rects) {\n        // Simple overlap resolution: shrink overlapping rectangles\n        for (int i = 0; i < N; ++i) {\n            for (int j = i+1; j < N; ++j) {\n                if (rectangles_overlap(rects[i], rects[j])) {\n                    // Shrink the smaller rectangle\n                    if (rects[i].area() < rects[j].area()) {\n                        shrink_rectangle(rects[i], rects[j]);\n                    } else {\n                        shrink_rectangle(rects[j], rects[i]);\n                    }\n                }\n            }\n        }\n    }\n    \n    void shrink_rectangle(Rectangle& to_shrink, const Rectangle& other) {\n        // Find intersection and shrink accordingly\n        int left = max(to_shrink.j0, other.j0);\n        int right = min(to_shrink.j1, other.j1);\n        int top = max(to_shrink.i0, other.i0);\n        int bottom = min(to_shrink.i1, other.i1);\n        \n        if (left < right && top < bottom) {\n            // Calculate overlap sizes\n            int overlap_width = right - left;\n            int overlap_height = bottom - top;\n            \n            // Shrink in the direction with smaller overlap\n            if (overlap_width < overlap_height) {\n                if (other.j0 <= to_shrink.j0) {\n                    to_shrink.j0 = right;\n                } else {\n                    to_shrink.j1 = left;\n                }\n            } else {\n                if (other.i0 <= to_shrink.i0) {\n                    to_shrink.i0 = bottom;\n                } else {\n                    to_shrink.i1 = top;\n                }\n            }\n        }\n    }\n    \n    int calculate_total_cost(int day, const vector<Rectangle>& rects) {\n        int cost = 0;\n        \n        // Area penalty cost\n        for (int k = 0; k < N; ++k) {\n            int actual_area = rects[k].area();\n            if (actual_area < desired_areas[day][k]) {\n                cost += 100 * (desired_areas[day][k] - actual_area);\n            }\n        }\n        \n        // Partition change cost (except for day 0)\n        if (day > 0) {\n            // Create temporary layout to calculate partitions\n            DayLayout temp_layout(W);\n            temp_layout.rectangles = rects;\n            temp_layout.update_partitions(W);\n            \n            // Calculate partition differences\n            for (int i = 0; i < W-1; ++i) {\n                for (int j = 0; j < W; ++j) {\n                    if (layouts[day-1].horizontal_partitions[i][j] != temp_layout.horizontal_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n            \n            for (int i = 0; i < W; ++i) {\n                for (int j = 0; j < W-1; ++j) {\n                    if (layouts[day-1].vertical_partitions[i][j] != temp_layout.vertical_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n        }\n        \n        return cost;\n    }\n    \n    bool rectangles_overlap(const Rectangle& r1, const Rectangle& r2) {\n        return !(r1.i1 <= r2.i0 || r2.i1 <= r1.i0 || r1.j1 <= r2.j0 || r2.j1 <= r1.j0);\n    }\n    \n    double generate_random_double() {\n        return uniform_real_distribution<double>(0.0, 1.0)(rng);\n    }\n    \n    void output_solution() {\n        for (int d = 0; d < D; ++d) {\n            for (int k = 0; k < N; ++k) {\n                const auto& rect = layouts[d].rectangles[k];\n                cout << rect.i0 << \" \" << rect.j0 << \" \" << rect.i1 << \" \" << rect.j1 << \"\\n\";\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> desired_areas(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> desired_areas[d][k];\n        }\n    }\n    \n    EventHallOptimizer optimizer(W, D, N, desired_areas);\n    optimizer.solve();\n    optimizer.output_solution();\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<pair<int, pair<int, int>>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_improvement = -1;\n        int best_stamp = -1;\n        int best_p = -1;\n        int best_q = -1;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    int improvement = 0;\n                    \n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int v = board[p + i][q + j];\n                            int x = stamps[m][i][j];\n                            \n                            // Calculate the improvement\n                            int current_mod = v % MOD;\n                            int new_mod = (v + x) % MOD;\n                            int cell_improvement = new_mod - current_mod;\n                            if (cell_improvement < 0) cell_improvement += MOD;\n                            \n                            improvement += cell_improvement;\n                        }\n                    }\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_stamp = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_improvement <= 0) {\n            // No improvement, stop early\n            break;\n        }\n        \n        operations.push_back({best_stamp, {best_p, best_q}});\n        \n        // Apply the stamp\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_stamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << endl;\n    for (auto &op : operations) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <set>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 5;\n\nchar move_towards(int i0, int j0, int i1, int j1, int grid[N][N], int crane_pos[N][2], int crane_id, bool is_large, int crane_carrying[N]) {\n    vector<char> dirs = {'U', 'D', 'L', 'R'};\n    vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    int current_dist = abs(i0 - i1) + abs(j0 - j1);\n    vector<char> good_moves;\n    vector<char> ok_moves;\n\n    for (int idx = 0; idx < 4; idx++) {\n        int ni = i0 + moves[idx].first;\n        int nj = j0 + moves[idx].second;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n            continue;\n        }\n\n        if (crane_carrying[crane_id] != -1 && !is_large) {\n            if (grid[ni][nj] != -1) {\n                continue;\n            }\n        }\n\n        int new_dist = abs(ni - i1) + abs(nj - j1);\n        if (new_dist < current_dist) {\n            good_moves.push_back(dirs[idx]);\n        } else if (new_dist == current_dist) {\n            ok_moves.push_back(dirs[idx]);\n        }\n    }\n\n    if (!good_moves.empty()) {\n        return good_moves[0];\n    } else if (!ok_moves.empty()) {\n        return ok_moves[0];\n    } else {\n        return '.';\n    }\n}\n\nint main() {\n    int n_val;\n    cin >> n_val;\n    int A[N][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    int grid[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n\n    int crane_pos[N][2];\n    for (int i = 0; i < N; i++) {\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n    }\n\n    int crane_carrying[N];\n    for (int i = 0; i < N; i++) {\n        crane_carrying[i] = -1;\n    }\n\n    int next_container_index[N] = {0};\n    int next_dispatch[N];\n    for (int i = 0; i < N; i++) {\n        next_dispatch[i] = 5 * i;\n    }\n\n    bool bombed[N] = {false};\n    vector<string> crane_actions(N);\n\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) {\n            if (next_container_index[i] < N) {\n                bool crane_holding_at_gate = false;\n                for (int c = 0; c < N; c++) {\n                    if (!bombed[c] && crane_pos[c][0] == i && crane_pos[c][1] == 0 && crane_carrying[c] != -1) {\n                        crane_holding_at_gate = true;\n                        break;\n                    }\n                }\n                if (grid[i][0] == -1 && !crane_holding_at_gate) {\n                    grid[i][0] = A[i][next_container_index[i]];\n                    next_container_index[i]++;\n                }\n            }\n        }\n\n        vector<char> actions(N, '.');\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                actions[c] = '.';\n                continue;\n            }\n\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            int carrying = crane_carrying[c];\n\n            if (carrying != -1) {\n                int container_id = carrying;\n                int target_gate = container_id / N;\n\n                if (container_id == next_dispatch[target_gate]) {\n                    if (i0 == target_gate && j0 == N-1) {\n                        actions[c] = 'Q';\n                    } else {\n                        actions[c] = move_towards(i0, j0, target_gate, N-1, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (j0 >= 1 && j0 <= 3 && grid[i0][j0] == -1) {\n                        actions[c] = 'Q';\n                    } else {\n                        vector<pair<int, int>> candidates;\n                        for (int i = 0; i < N; i++) {\n                            for (int j = 1; j <= 3; j++) {\n                                if (grid[i][j] == -1) {\n                                    candidates.push_back({i, j});\n                                }\n                            }\n                        }\n                        if (!candidates.empty()) {\n                            auto best = candidates[0];\n                            int best_dist = abs(i0 - best.first) + abs(j0 - best.second);\n                            for (auto cand : candidates) {\n                                int dist = abs(i0 - cand.first) + abs(j0 - cand.second);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best = cand;\n                                }\n                            }\n                            actions[c] = move_towards(i0, j0, best.first, best.second, grid, crane_pos, c, (c==0), crane_carrying);\n                        } else {\n                            actions[c] = '.';\n                        }\n                    }\n                }\n            } else {\n                vector<tuple<int, int, int>> containers;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int cid = grid[i][j];\n                            if (cid / N == c) {\n                                containers.push_back(make_tuple(i, j, cid));\n                            }\n                        }\n                    }\n                }\n                if (!containers.empty()) {\n                    auto best = containers[0];\n                    int best_dist = abs(i0 - get<0>(best)) + abs(j0 - get<1>(best));\n                    for (auto cont : containers) {\n                        int dist = abs(i0 - get<0>(cont)) + abs(j0 - get<1>(cont));\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best = cont;\n                        }\n                    }\n                    int ti = get<0>(best), tj = get<1>(best);\n                    if (i0 == ti && j0 == tj) {\n                        actions[c] = 'P';\n                    } else {\n                        actions[c] = move_towards(i0, j0, ti, tj, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (i0 == c && j0 == 0) {\n                        actions[c] = '.';\n                    } else {\n                        actions[c] = move_towards(i0, j0, c, 0, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> next_pos(N);\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'U') {\n                next_pos[c] = {i0-1, j0};\n            } else if (act == 'D') {\n                next_pos[c] = {i0+1, j0};\n            } else if (act == 'L') {\n                next_pos[c] = {i0, j0-1};\n            } else if (act == 'R') {\n                next_pos[c] = {i0, j0+1};\n            } else {\n                next_pos[c] = {i0, j0};\n            }\n        }\n\n        set<int> involved;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == make_pair(crane_pos[j][0], crane_pos[j][1]) && \n                    next_pos[j] == make_pair(crane_pos[i][0], crane_pos[i][1])) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n\n        for (int c : involved) {\n            if (!bombed[c]) {\n                actions[c] = '.';\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'P') {\n                if (crane_carrying[c] == -1 && grid[i0][j0] != -1) {\n                    crane_carrying[c] = grid[i0][j0];\n                    grid[i0][j0] = -1;\n                }\n            } else if (act == 'Q') {\n                if (crane_carrying[c] != -1 && grid[i0][j0] == -1) {\n                    grid[i0][j0] = crane_carrying[c];\n                    crane_carrying[c] = -1;\n                }\n            } else if (act == 'B') {\n                if (crane_carrying[c] == -1) {\n                    bombed[c] = true;\n                }\n            } else if (act == 'U' || act == 'D' || act == 'L' || act == 'R') {\n                crane_pos[c][0] = next_pos[c].first;\n                crane_pos[c][1] = next_pos[c].second;\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container_id = grid[i][N-1];\n                grid[i][N-1] = -1;\n                next_dispatch[i] = container_id + 1;\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            crane_actions[c] += actions[c];\n        }\n\n        int total_dispatched = 0;\n        for (int i = 0; i < N; i++) {\n            total_dispatched += (next_dispatch[i] - 5*i);\n        }\n        if (total_dispatched == N*N) {\n            break;\n        }\n    }\n\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        if (crane_actions[i].size() > max_len) {\n            max_len = crane_actions[i].size();\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        while (crane_actions[i].size() < max_len) {\n            crane_actions[i] += '.';\n        }\n        cout << crane_actions[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <tuple>\n#include <string>\nusing namespace std;\n\nvector<string> get_manhattan_path(pair<int, int> start, pair<int, int> end) {\n    vector<string> path;\n    int x1 = start.first, y1 = start.second;\n    int x2 = end.first, y2 = end.second;\n    while (x1 < x2) {\n        path.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        path.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        path.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        path.push_back(\"L\");\n        y1--;\n    }\n    return path;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    long long base = 0;\n    vector<tuple<int, int, int>> sources;\n    vector<tuple<int, int, int>> sinks;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                sources.emplace_back(i, j, grid[i][j]);\n                base += grid[i][j];\n            } else if (grid[i][j] < 0) {\n                sinks.emplace_back(i, j, -grid[i][j]);\n                base += -grid[i][j];\n            }\n        }\n    }\n\n    long long total_soil = base / 2;\n\n    if (total_soil == 0) {\n        cout << endl;\n        return 0;\n    }\n\n    pair<int, int> best_hub;\n    long long best_cost = LLONG_MAX;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pair<int, int> hub = {i, j};\n\n            vector<tuple<int, int, int>> sorted_sources = sources;\n            sort(sorted_sources.begin(), sorted_sources.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            vector<tuple<int, int, int>> sorted_sinks = sinks;\n            sort(sorted_sinks.begin(), sorted_sinks.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            long long cost_transport = 0;\n            pair<int, int> current = {0, 0};\n            long long load = 0;\n\n            if (!sorted_sources.empty()) {\n                auto first = sorted_sources[0];\n                int d = abs(current.first - get<0>(first)) + abs(current.second - get<1>(first));\n                cost_transport += d * 100;\n                current = {get<0>(first), get<1>(first)};\n                load += get<2>(first);\n\n                for (int idx = 1; idx < sorted_sources.size(); idx++) {\n                    auto src = sorted_sources[idx];\n                    d = abs(current.first - get<0>(src)) + abs(current.second - get<1>(src));\n                    cost_transport += d * (100 + load);\n                    current = {get<0>(src), get<1>(src)};\n                    load += get<2>(src);\n                }\n\n                d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * (100 + load);\n            } else {\n                int d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * 100;\n            }\n\n            current = hub;\n            load = total_soil;\n\n            for (int idx = 0; idx < sorted_sinks.size(); idx++) {\n                auto sink = sorted_sinks[idx];\n                int d = abs(current.first - get<0>(sink)) + abs(current.second - get<1>(sink));\n                cost_transport += d * (100 + load);\n                current = {get<0>(sink), get<1>(sink)};\n                load -= get<2>(sink);\n            }\n\n            long long total_cost = base + cost_transport;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                best_hub = hub;\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> sorted_sources = sources;\n    sort(sorted_sources.begin(), sorted_sources.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<tuple<int, int, int>> sorted_sinks = sinks;\n    sort(sorted_sinks.begin(), sorted_sinks.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<string> operations;\n    pair<int, int> current_pos = {0, 0};\n\n    if (!sorted_sources.empty()) {\n        auto first = sorted_sources[0];\n        pair<int, int> first_pos = {get<0>(first), get<1>(first)};\n        vector<string> path = get_manhattan_path(current_pos, first_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"+\" + to_string(get<2>(first)));\n        current_pos = first_pos;\n\n        for (int idx = 1; idx < sorted_sources.size(); idx++) {\n            auto src = sorted_sources[idx];\n            pair<int, int> src_pos = {get<0>(src), get<1>(src)};\n            vector<string> path = get_manhattan_path(current_pos, src_pos);\n            operations.insert(operations.end(), path.begin(), path.end());\n            operations.push_back(\"+\" + to_string(get<2>(src)));\n            current_pos = src_pos;\n        }\n\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    } else {\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    }\n\n    for (auto sink : sorted_sinks) {\n        pair<int, int> sink_pos = {get<0>(sink), get<1>(sink)};\n        vector<string> path = get_manhattan_path(current_pos, sink_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"-\" + to_string(get<2>(sink)));\n        current_pos = sink_pos;\n    }\n\n    for (const string& op : operations) {\n        cout << op << endl;\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    // For each turn\n    for (int t = 0; t < T; t++) {\n        // Calculate scores for each seed\n        vector<pair<double, int>> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            // Calculate total value\n            int total_value = accumulate(X[i].begin(), X[i].end(), 0);\n            \n            // Find maximum value in any single criterion\n            int max_criterion = *max_element(X[i].begin(), X[i].end());\n            \n            // Calculate sum of top 5 criteria\n            vector<int> sorted_criteria = X[i];\n            sort(sorted_criteria.rbegin(), sorted_criteria.rend());\n            int top5_sum = accumulate(sorted_criteria.begin(), sorted_criteria.begin() + min(5, M), 0);\n            \n            // Combined score with weights\n            double score = 0.5 * total_value + 0.3 * max_criterion + 0.2 * top5_sum;\n            seed_scores[i] = {score, i};\n        }\n        \n        // Sort seeds by score in descending order\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Select top 36 seeds\n        vector<int> selected_seeds;\n        for (int i = 0; i < N * N; i++) {\n            selected_seeds.push_back(seed_scores[i].second);\n        }\n        \n        // Create grid arrangement\n        vector<vector<int>> A(N, vector<int>(N, 0));\n        \n        // Strategy: Place seeds with complementary strengths adjacent to each other\n        // Sort selected seeds by their strongest criterion\n        vector<pair<int, int>> seeds_by_max_criterion;\n        for (int seed : selected_seeds) {\n            int max_val = *max_element(X[seed].begin(), X[seed].end());\n            seeds_by_max_criterion.push_back({max_val, seed});\n        }\n        \n        // Sort by maximum criterion value\n        sort(seeds_by_max_criterion.rbegin(), seeds_by_max_criterion.rend());\n        \n        // Place in a checkerboard pattern, alternating high and medium seeds\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if ((i + j) % 2 == 0) {\n                    // Place a seed with high maximum criterion\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                } else {\n                    // Place a seed with balanced criteria\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                }\n            }\n        }\n        \n        // Output the arrangement\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds for next turn\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> X[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <climits>\n#include <queue>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s_grid(N);\n    vector<string> t_grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> s_grid[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t_grid[i];\n    }\n    \n    set<pair<int, int>> S;\n    set<pair<int, int>> T;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0') {\n                S.insert({i, j});\n            }\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0') {\n                T.insert({i, j});\n            }\n        }\n    }\n    \n    const vector<int> dx = {0, 1, 0, -1};\n    const vector<int> dy = {1, 0, -1, 0};\n    const vector<char> move_dir = {'R', 'D', 'L', 'U'};\n    \n    int V_prime = 2;\n    cout << V_prime << '\\n';\n    cout << \"0 1\\n\";\n    int rx0 = (N-1)/2;\n    int ry0 = (N-1)/2;\n    cout << rx0 << \" \" << ry0 << '\\n';\n    cout.flush();\n    \n    int rx = rx0;\n    int ry = ry0;\n    int dir = 0;\n    \n    auto manhattan_move = [&](int x1, int y1, int x2, int y2) {\n        vector<char> moves;\n        while (x1 < x2) {\n            moves.push_back('D');\n            x1++;\n        }\n        while (x1 > x2) {\n            moves.push_back('U');\n            x1--;\n        }\n        while (y1 < y2) {\n            moves.push_back('R');\n            y1++;\n        }\n        while (y1 > y2) {\n            moves.push_back('L');\n            y1--;\n        }\n        return moves;\n    };\n    \n    while (!S.empty()) {\n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq;\n        \n        for (const auto& pos : S) {\n            int i = pos.first, j = pos.second;\n            for (int d = 0; d < 4; d++) {\n                int x = i + dx[d];\n                int y = j + dy[d];\n                if (x >= 0 && x < N && y >= 0 && y < N) {\n                    int dist = abs(rx - x) + abs(ry - y);\n                    pq.push({dist, {pos, {x, y}}});\n                }\n            }\n        }\n        \n        auto best = pq.top();\n        pq.pop();\n        pair<int, int> best_pos = best.second.first;\n        pair<int, int> best_adj = best.second.second;\n        \n        int a = best_pos.first;\n        int b = best_pos.second;\n        int x = best_adj.first;\n        int y = best_adj.second;\n        \n        vector<char> path = manhattan_move(rx, ry, x, y);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        int desired_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (dx[d] == a - x && dy[d] == b - y) {\n                desired_dir = d;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string grab_command(2 * V_prime, '.');\n        grab_command[V_prime + 1] = 'P';\n        cout << grab_command << '\\n';\n        cout.flush();\n        S.erase({a, b});\n        \n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq_t;\n        \n        for (const auto& target : T) {\n            int i = target.first, j = target.second;\n            for (int d = 0; d < 4; d++) {\n                int x_target = i + dx[d];\n                int y_target = j + dy[d];\n                if (x_target >= 0 && x_target < N && y_target >= 0 && y_target < N) {\n                    int dist = abs(rx - x_target) + abs(ry - y_target);\n                    pq_t.push({dist, {target, {x_target, y_target}}});\n                }\n            }\n        }\n        \n        auto best_t = pq_t.top();\n        pq_t.pop();\n        pair<int, int> best_target = best_t.second.first;\n        pair<int, int> best_adj_target = best_t.second.second;\n        \n        int c = best_target.first;\n        int d = best_target.second;\n        int x_target = best_adj_target.first;\n        int y_target = best_adj_target.second;\n        \n        path = manhattan_move(rx, ry, x_target, y_target);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        desired_dir = -1;\n        for (int d_val = 0; d_val < 4; d_val++) {\n            if (dx[d_val] == c - x_target && dy[d_val] == d - y_target) {\n                desired_dir = d_val;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string release_command(2 * V_prime, '.');\n        release_command[V_prime + 1] = 'P';\n        cout << release_command << '\\n';\n        cout.flush();\n        T.erase({c, d});\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <chrono>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Point {\n    int x, y;\n    \n    bool operator<(const Point& other) const {\n        return tie(x, y) < tie(other.x, other.y);\n    }\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Polygon {\n    vector<Point> vertices;\n    \n    void add_vertex(const Point& p) {\n        vertices.push_back(p);\n    }\n    \n    double perimeter() const {\n        double perim = 0;\n        for (int i = 0; i < vertices.size(); ++i) {\n            int j = (i + 1) % vertices.size();\n            perim += abs(vertices[i].x - vertices[j].x) + abs(vertices[i].y - vertices[j].y);\n        }\n        return perim;\n    }\n    \n    bool contains(const Point& p) const {\n        int n = vertices.size();\n        bool inside = false;\n        \n        for (int i = 0, j = n - 1; i < n; j = i++) {\n            const Point& vi = vertices[i];\n            const Point& vj = vertices[j];\n            \n            if ((vi.y == vj.y) && (p.y == vi.y) && \n                (p.x >= min(vi.x, vj.x)) && (p.x <= max(vi.x, vj.x))) {\n                return true;\n            }\n            \n            if ((vi.x == vj.x) && (p.x == vi.x) && \n                (p.y >= min(vi.y, vj.y)) && (p.y <= max(vi.y, vj.y))) {\n                return true;\n            }\n            \n            if (((vi.y > p.y) != (vj.y > p.y)) &&\n                (p.x < (vj.x - vi.x) * (p.y - vi.y) / (vj.y - vi.y) + vi.x)) {\n                inside = !inside;\n            }\n        }\n        \n        return inside;\n    }\n    \n    bool is_simple() const {\n        int n = vertices.size();\n        if (n < 3) return false;\n        \n        for (int i = 0; i < n; ++i) {\n            int j = (i + 1) % n;\n            const Point& a = vertices[i];\n            const Point& b = vertices[j];\n            \n            for (int k = i + 1; k < n; ++k) {\n                int l = (k + 1) % n;\n                if (k == j || l == i || k == i) continue;\n                \n                const Point& c = vertices[k];\n                const Point& d = vertices[l];\n                \n                if (segments_intersect(a, b, c, d)) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \nprivate:\n    bool segments_intersect(const Point& a, const Point& b, const Point& c, const Point& d) const {\n        if (max(a.x, b.x) < min(c.x, d.x) || max(c.x, d.x) < min(a.x, b.x)) return false;\n        if (max(a.y, b.y) < min(c.y, d.y) || max(c.y, d.y) < min(a.y, b.y)) return false;\n        \n        long long cross1 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n        long long cross2 = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);\n        long long cross3 = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);\n        long long cross4 = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);\n        \n        if ((cross1 * cross2 < 0) && (cross3 * cross4 < 0)) return true;\n        \n        if (cross1 == 0 && on_segment(a, b, c)) return true;\n        if (cross2 == 0 && on_segment(a, b, d)) return true;\n        if (cross3 == 0 && on_segment(c, d, a)) return true;\n        if (cross4 == 0 && on_segment(c, d, b)) return true;\n        \n        return false;\n    }\n    \n    bool on_segment(const Point& a, const Point& b, const Point& c) const {\n        return c.x >= min(a.x, b.x) && c.x <= max(a.x, b.x) &&\n               c.y >= min(a.y, b.y) && c.y <= max(a.y, b.y);\n    }\n};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<Point> mackerels(N);\n    vector<Point> sardines(N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].x >> mackerels[i].y;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].x >> sardines[i].y;\n    }\n    \n    const int cluster_size = 50;\n    vector<vector<Point>> mackerel_clusters;\n    vector<bool> used(N, false);\n    \n    for (int i = 0; i < N; ++i) {\n        if (!used[i]) {\n            vector<Point> cluster;\n            cluster.push_back(mackerels[i]);\n            used[i] = true;\n            \n            for (int j = i + 1; j < N && cluster.size() < cluster_size; ++j) {\n                if (!used[j]) {\n                    int dx = mackerels[i].x - mackerels[j].x;\n                    int dy = mackerels[i].y - mackerels[j].y;\n                    if (dx * dx + dy * dy < 10000 * 10000) {\n                        cluster.push_back(mackerels[j]);\n                        used[j] = true;\n                    }\n                }\n            }\n            \n            if (cluster.size() >= 10) {\n                mackerel_clusters.push_back(cluster);\n            }\n        }\n    }\n    \n    sort(mackerel_clusters.begin(), mackerel_clusters.end(), \n         [](const vector<Point>& a, const vector<Point>& b) {\n             return a.size() > b.size();\n         });\n    \n    vector<tuple<int, int, int, int>> cluster_boxes;\n    for (const auto& cluster : mackerel_clusters) {\n        int min_x = 100000, max_x = 0;\n        int min_y = 100000, max_y = 0;\n        \n        for (const auto& p : cluster) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        cluster_boxes.emplace_back(min_x, min_y, max_x, max_y);\n    }\n    \n    Polygon best_polygon;\n    int best_score = 0;\n    \n    auto calculate_score = [](const Polygon& poly, const vector<Point>& macks, const vector<Point>& sards) {\n        int a = 0, b = 0;\n        for (const auto& p : macks) {\n            if (poly.contains(p)) {\n                a++;\n            }\n        }\n        for (const auto& p : sards) {\n            if (poly.contains(p)) {\n                b++;\n            }\n        }\n        return max(0, a - b + 1);\n    };\n    \n    for (size_t i = 0; i < min(mackerel_clusters.size(), size_t(10)); ++i) {\n        const auto& box = cluster_boxes[i];\n        int min_x = get<0>(box);\n        int min_y = get<1>(box);\n        int max_x = get<2>(box);\n        int max_y = get<3>(box);\n        \n        Polygon polygon;\n        polygon.add_vertex({min_x, min_y});\n        polygon.add_vertex({max_x, min_y});\n        polygon.add_vertex({max_x, max_y});\n        polygon.add_vertex({min_x, max_y});\n        \n        const int max_expansions = 10;\n        for (int expansion = 0; expansion < max_expansions; ++expansion) {\n            vector<Polygon> expansions;\n            \n            if (polygon.vertices[0].x > 0) {\n                Polygon left_poly = polygon;\n                left_poly.vertices[0].x = max(0, left_poly.vertices[0].x - 1000);\n                left_poly.vertices[3].x = left_poly.vertices[0].x;\n                if (left_poly.is_simple()) {\n                    expansions.push_back(left_poly);\n                }\n            }\n            \n            if (polygon.vertices[1].x < 100000) {\n                Polygon right_poly = polygon;\n                right_poly.vertices[1].x = min(100000, right_poly.vertices[1].x + 1000);\n                right_poly.vertices[2].x = right_poly.vertices[1].x;\n                if (right_poly.is_simple()) {\n                    expansions.push_back(right_poly);\n                }\n            }\n            \n            if (polygon.vertices[0].y > 0) {\n                Polygon down_poly = polygon;\n                down_poly.vertices[0].y = max(0, down_poly.vertices[0].y - 1000);\n                down_poly.vertices[1].y = down_poly.vertices[0].y;\n                if (down_poly.is_simple()) {\n                    expansions.push_back(down_poly);\n                }\n            }\n            \n            if (polygon.vertices[2].y < 100000) {\n                Polygon up_poly = polygon;\n                up_poly.vertices[2].y = min(100000, up_poly.vertices[2].y + 1000);\n                up_poly.vertices[3].y = up_poly.vertices[2].y;\n                if (up_poly.is_simple()) {\n                    expansions.push_back(up_poly);\n                }\n            }\n            \n            Polygon best_expansion = polygon;\n            int best_expansion_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& exp : expansions) {\n                if (exp.perimeter() <= 400000) {\n                    int score = calculate_score(exp, mackerels, sardines);\n                    if (score > best_expansion_score) {\n                        best_expansion = exp;\n                        best_expansion_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_expansion;\n        }\n        \n        vector<Point> inside_sardines;\n        for (const auto& p : sardines) {\n            if (polygon.contains(p)) {\n                inside_sardines.push_back(p);\n            }\n        }\n        \n        if (!inside_sardines.empty()) {\n            uniform_int_distribution<int> dist(0, inside_sardines.size() - 1);\n            Point target = inside_sardines[dist(rng)];\n            \n            vector<Polygon> adjusted_polygons;\n            \n            // Try shrinking from each direction\n            if (target.x < polygon.vertices[0].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].x = max(0, new_poly.vertices[0].x - 1000);\n                new_poly.vertices[3].x = new_poly.vertices[0].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.x > polygon.vertices[1].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[1].x = min(100000, new_poly.vertices[1].x + 1000);\n                new_poly.vertices[2].x = new_poly.vertices[1].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y < polygon.vertices[0].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].y = max(0, new_poly.vertices[0].y - 1000);\n                new_poly.vertices[1].y = new_poly.vertices[0].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y > polygon.vertices[2].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[2].y = min(100000, new_poly.vertices[2].y + 1000);\n                new_poly.vertices[3].y = new_poly.vertices[2].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            Polygon best_adjusted = polygon;\n            int best_adjusted_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& adj : adjusted_polygons) {\n                if (adj.perimeter() <= 400000) {\n                    int score = calculate_score(adj, mackerels, sardines);\n                    if (score > best_adjusted_score) {\n                        best_adjusted = adj;\n                        best_adjusted_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_adjusted;\n        }\n        \n        int score = calculate_score(polygon, mackerels, sardines);\n        if (score > best_score) {\n            best_score = score;\n            best_polygon = polygon;\n        }\n    }\n    \n    if (best_polygon.vertices.empty()) {\n        best_polygon.add_vertex({0, 0});\n        best_polygon.add_vertex({100000, 0});\n        best_polygon.add_vertex({100000, 100000});\n        best_polygon.add_vertex({0, 100000});\n    }\n    \n    cout << best_polygon.vertices.size() << \"\\n\";\n    for (const auto& p : best_polygon.vertices) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <cctype>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<tuple<double, double, double, double, int>> placed_rectangles;\n        double current_width = 0.0;\n        double current_height = 0.0;\n        double penalty = 0.0;\n        vector<tuple<int, int, char, int>> sequence;\n\n        for (int i = 0; i < N; i++) {\n            tuple<int, int, char, int, double, double, double, double> best_option;\n            double best_cost = 1e18;\n            bool found = false;\n\n            double cost_skip = current_width + current_height + penalty + (w_est[i] + h_est[i]);\n\n            for (int rotation : {0, 1}) {\n                double w_i = (rotation == 0) ? w_est[i] : h_est[i];\n                double h_i = (rotation == 0) ? h_est[i] : w_est[i];\n\n                for (char direction : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (const auto& rect : placed_rectangles) {\n                        refs.push_back(get<4>(rect));\n                    }\n\n                    for (int ref : refs) {\n                        double x0, y0;\n                        if (direction == 'U') {\n                            if (ref == -1) {\n                                x0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                x0 = get<0>(*it) + get<2>(*it);\n                            }\n                            y0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_x, x0) < min(r_x + r_w, x0 + w_i)) {\n                                    double candidate = r_y + r_h;\n                                    if (candidate > y0) {\n                                        y0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        } else {\n                            if (ref == -1) {\n                                y0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                y0 = get<1>(*it) + get<3>(*it);\n                            }\n                            x0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_y, y0) < min(r_y + r_h, y0 + h_i)) {\n                                    double candidate = r_x + r_w;\n                                    if (candidate > x0) {\n                                        x0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (found && best_cost < cost_skip) {\n                auto [i_opt, rot_opt, dir_opt, ref_opt, x0_opt, y0_opt, w_i_opt, h_i_opt] = best_option;\n                current_width = max(current_width, x0_opt + w_i_opt);\n                current_height = max(current_height, y0_opt + h_i_opt);\n                placed_rectangles.emplace_back(x0_opt, y0_opt, w_i_opt, h_i_opt, i_opt);\n                sequence.emplace_back(i_opt, rot_opt, dir_opt, ref_opt);\n            } else {\n                penalty += (w_est[i] + h_est[i]);\n            }\n        }\n\n        cout << sequence.size() << '\\n';\n        for (const auto& [i, rot, dir, ref] : sequence) {\n            cout << i << ' ' << rot << ' ' << dir << ' ' << ref << '\\n';\n        }\n        cout << flush;\n\n        if (turn < T - 1) {\n            int W_prime, H_prime;\n            cin >> W_prime >> H_prime;\n\n            double width_factor = 1.0;\n            if (current_width > 0) {\n                width_factor = static_cast<double>(W_prime) / current_width;\n            }\n            double height_factor = 1.0;\n            if (current_height > 0) {\n                height_factor = static_cast<double>(H_prime) / current_height;\n            }\n\n            double alpha = 0.2;\n            width_factor = 1.0 + alpha * (width_factor - 1.0);\n            height_factor = 1.0 + alpha * (height_factor - 1.0);\n\n            for (const auto& rect : placed_rectangles) {\n                int idx = get<4>(rect);\n                w_est[idx] *= width_factor;\n                h_est[idx] *= height_factor;\n                w_est[idx] = max(1.0, min(1e9, w_est[idx]));\n                h_est[idx] = max(1.0, min(1e9, h_est[idx]));\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <unordered_set>\n\nusing namespace std;\n\nstruct Vertex {\n    int id;\n    int x, y;\n    int beauty;\n    vector<int> neighbors;\n    int parent;\n    int height;\n    int root;\n};\n\nint H;  // Global height limit\nvector<vector<bool>> is_adjacent;  // Adjacency matrix for O(1) edge checks\n\n// Function to calculate attractiveness of a solution\nlong long calculate_attractiveness(const vector<Vertex>& vertices) {\n    long long attractiveness = 0;\n    for (const auto& v : vertices) {\n        attractiveness += (long long)(v.height + 1) * v.beauty;\n    }\n    return attractiveness;\n}\n\n// Function to update heights after changing a parent\nvoid update_heights(vector<Vertex>& vertices, int v) {\n    if (vertices[v].parent == -1) {\n        vertices[v].height = 0;\n        vertices[v].root = v;\n    } else {\n        vertices[v].height = vertices[vertices[v].parent].height + 1;\n        vertices[v].root = vertices[vertices[v].parent].root;\n    }\n    \n    // Recursively update children\n    for (int u : vertices[v].neighbors) {\n        if (vertices[u].parent == v) {\n            update_heights(vertices, u);\n        }\n    }\n}\n\n// Function to check if a parent assignment is valid (height <= H and edge exists)\nbool is_valid_parent(const vector<Vertex>& vertices, int v, int parent) {\n    if (parent == -1) return true;\n    if (vertices[parent].height >= H) return false;\n    return is_adjacent[v][parent];\n}\n\n// Function to check if u is a descendant of v\nbool is_descendant(const vector<Vertex>& vertices, int u, int v) {\n    int current = u;\n    while (current != -1) {\n        if (current == v) {\n            return true;\n        }\n        current = vertices[current].parent;\n    }\n    return false;\n}\n\n// Function to calculate Euclidean distance between two vertices\ndouble distance(const Vertex& a, const Vertex& b) {\n    double dx = a.x - b.x;\n    double dy = a.y - b.y;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Function to find the best parent for a vertex\nint find_best_parent(const vector<Vertex>& vertices, int v, const vector<bool>& is_root) {\n    int best_parent = -1;\n    long long best_gain = 0;\n    \n    // Consider neighbors that are roots or from different trees\n    for (int u : vertices[v].neighbors) {\n        if (is_root[u] || vertices[u].root != vertices[v].root) {\n            if (is_valid_parent(vertices, v, u)) {\n                // Calculate the gain in attractiveness if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                // Prefer parents that allow for deeper nesting in the future\n                if (new_height < H) {\n                    gain += vertices[v].beauty / 2;  // Bonus for potential future gains\n                }\n                \n                // Add a spatial component: prefer closer parents\n                double dist = distance(vertices[v], vertices[u]);\n                double spatial_factor = 1.0 / (1.0 + dist / 100.0);  // Normalize distance\n                gain = (long long)(gain * spatial_factor);\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n    }\n    \n    return best_parent;\n}\n\n// Function to perform local search\nvoid local_search(vector<Vertex>& vertices, const vector<vector<int>>& adj, int max_iterations) {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> vertex_dist(0, vertices.size() - 1);\n    \n    long long current_attractiveness = calculate_attractiveness(vertices);\n    vector<bool> is_root(vertices.size(), false);\n    for (const auto& v : vertices) {\n        if (v.parent == -1) {\n            is_root[v.id] = true;\n        }\n    }\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        int v = vertex_dist(gen);\n        \n        // Try to find a better parent for v\n        int current_parent = vertices[v].parent;\n        int best_parent = current_parent;\n        long long best_gain = 0;\n        \n        for (int u : adj[v]) {\n            if (u != current_parent && vertices[u].parent != v && \n                !is_descendant(vertices, u, v) &&  // Avoid creating cycles\n                is_valid_parent(vertices, v, u)) {\n                \n                // Calculate the gain if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n        \n        // If we found a better parent, update the solution\n        if (best_parent != current_parent && best_gain > 0) {\n            // Remove v from its current parent's children\n            if (current_parent != -1) {\n                // No need to explicitly remove, just update parent pointer\n            }\n            \n            // Add v to its new parent\n            vertices[v].parent = best_parent;\n            update_heights(vertices, v);\n            \n            // Update root status\n            if (current_parent == -1) {\n                is_root[v] = false;\n            }\n            if (best_parent == -1) {\n                is_root[v] = true;\n            }\n            \n            current_attractiveness += best_gain;\n        }\n        \n        // Occasionally try to make a vertex a root\n        if (iter % 100 == 0 && vertices[v].parent != -1) {\n            // Check if all children of v are actually adjacent to v\n            bool all_children_adjacent = true;\n            for (int u : adj[v]) {\n                if (vertices[u].parent == v && !is_adjacent[v][u]) {\n                    all_children_adjacent = false;\n                    break;\n                }\n            }\n            \n            if (all_children_adjacent) {\n                int old_parent = vertices[v].parent;\n                vertices[v].parent = -1;\n                update_heights(vertices, v);\n                \n                long long new_attractiveness = calculate_attractiveness(vertices);\n                if (new_attractiveness > current_attractiveness) {\n                    current_attractiveness = new_attractiveness;\n                    is_root[v] = true;\n                } else {\n                    // Revert the change\n                    vertices[v].parent = old_parent;\n                    update_heights(vertices, v);\n                }\n            }\n        }\n    }\n}\n\n// Function to validate the solution\nbool validate_solution(const vector<Vertex>& vertices, const vector<vector<int>>& adj) {\n    // Check that all parent-child relationships correspond to edges in the graph\n    for (const auto& v : vertices) {\n        if (v.parent != -1) {\n            if (!is_adjacent[v.id][v.parent]) {\n                return false;\n            }\n        }\n    }\n    \n    // Check that there are no cycles\n    for (const auto& v : vertices) {\n        unordered_set<int> visited;\n        int current = v.id;\n        while (current != -1) {\n            if (visited.count(current)) {\n                return false;  // Cycle detected\n            }\n            visited.insert(current);\n            current = vertices[current].parent;\n        }\n    }\n    \n    // Check height constraints\n    for (const auto& v : vertices) {\n        if (v.height > H) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M >> H;\n    \n    is_adjacent.assign(N, vector<bool>(N, false));\n    \n    vector<Vertex> vertices(N);\n    for (int i = 0; i < N; i++) {\n        vertices[i].id = i;\n        cin >> vertices[i].beauty;\n    }\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        vertices[u].neighbors.push_back(v);\n        vertices[v].neighbors.push_back(u);\n        is_adjacent[u][v] = true;\n        is_adjacent[v][u] = true;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].x >> vertices[i].y;\n    }\n    \n    // Initialize with each vertex as its own tree\n    for (auto& v : vertices) {\n        v.parent = -1;\n        v.height = 0;\n        v.root = v.id;\n    }\n    \n    // Sort vertices by beauty (higher beauty first) to prioritize them\n    vector<int> vertex_ids(N);\n    for (int i = 0; i < N; i++) {\n        vertex_ids[i] = i;\n    }\n    sort(vertex_ids.begin(), vertex_ids.end(), [&](int a, int b) {\n        return vertices[a].beauty > vertices[b].beauty;\n    });\n    \n    // Greedily assign parents\n    vector<bool> is_root(N, true);\n    for (int v : vertex_ids) {\n        // Only try to assign parents to vertices that can gain from having a parent\n        if (vertices[v].beauty > 20) {  // Lower threshold for more assignments\n            int best_parent = find_best_parent(vertices, v, is_root);\n            if (best_parent != -1) {\n                vertices[v].parent = best_parent;\n                is_root[v] = false;\n                update_heights(vertices, v);\n            }\n        }\n    }\n    \n    // Perform local search with more iterations\n    local_search(vertices, adj, 50000);  // Increased iterations for better results\n    \n    // Final validation\n    if (!validate_solution(vertices, adj)) {\n        // If validation fails, reset to a safe solution (each vertex as root)\n        for (auto& v : vertices) {\n            v.parent = -1;\n            v.height = 0;\n            v.root = v.id;\n        }\n    }\n    \n    // Output the solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertices[i].parent;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<pair<char, int>> moves;\n    int top = 0, bottom = N - 1;\n    int left = 0, right = N - 1;\n\n    while (top <= bottom && left <= right) {\n        // Process top row\n        for (int j = left; j <= right; j++) {\n            if (grid[top][j] == 'x') {\n                // Shift column j upward\n                for (int i = top; i < bottom; i++) {\n                    grid[i][j] = grid[i + 1][j];\n                }\n                grid[bottom][j] = '.';\n                moves.push_back({'U', j});\n            }\n        }\n        top++;\n\n        // Process bottom row\n        for (int j = left; j <= right; j++) {\n            if (grid[bottom][j] == 'x') {\n                // Shift column j downward\n                for (int i = bottom; i > top; i--) {\n                    grid[i][j] = grid[i - 1][j];\n                }\n                grid[top][j] = '.';\n                moves.push_back({'D', j});\n            }\n        }\n        bottom--;\n\n        // Process left column\n        for (int i = top; i <= bottom; i++) {\n            if (grid[i][left] == 'x') {\n                // Shift row i left\n                for (int j = left; j < right; j++) {\n                    grid[i][j] = grid[i][j + 1];\n                }\n                grid[i][right] = '.';\n                moves.push_back({'L', i});\n            }\n        }\n        left++;\n\n        // Process right column\n        for (int i = top; i <= bottom; i++) {\n            if (grid[i][right] == 'x') {\n                // Shift row i right\n                for (int j = right; j > left; j--) {\n                    grid[i][j] = grid[i][j - 1];\n                }\n                grid[i][left] = '.';\n                moves.push_back({'R', i});\n            }\n        }\n        right--;\n    }\n\n    for (auto move : moves) {\n        cout << move.first << \" \" << move.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    srand(0);\n    int N = 100;\n    int L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<long long, int>> candidates;\n        for (int j = 0; j < N; j++) {\n            if (j == i) continue;\n            candidates.push_back({T[j], j});\n        }\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, int>>());\n        if (candidates.size() >= 2) {\n            a[i] = candidates[0].second;\n            b[i] = candidates[1].second;\n        } else if (candidates.size() == 1) {\n            a[i] = candidates[0].second;\n            b[i] = i;\n        } else {\n            a[i] = i;\n            b[i] = i;\n        }\n    }\n\n    auto simulate = [&](const vector<int>& a_vec, const vector<int>& b_vec) {\n        vector<long long> count(N, 0);\n        int current = 0;\n        count[0] = 1;\n        for (int week = 1; week < L; week++) {\n            int next;\n            if (count[current] & 1) {\n                next = a_vec[current];\n            } else {\n                next = b_vec[current];\n            }\n            count[next]++;\n            current = next;\n        }\n        long long error = 0;\n        for (int i = 0; i < N; i++) {\n            error += abs(count[i] - T[i]);\n        }\n        return error;\n    };\n\n    long long best_error = simulate(a, b);\n    vector<int> best_a = a;\n    vector<int> best_b = b;\n\n    for (int iter = 0; iter < 100; iter++) {\n        int i = rand() % N;\n        int old_a = a[i];\n        int old_b = b[i];\n\n        a[i] = rand() % N;\n        b[i] = rand() % N;\n\n        long long new_error = simulate(a, b);\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n        } else {\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <iomanip>\n#include <sstream>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\n\nstruct City {\n    int id;\n    double cx, cy;  // estimated center coordinates\n    int lx, rx, ly, ry;  // given rectangle bounds\n    double uncertainty;  // size of the rectangle, representing uncertainty\n};\n\nstruct Edge {\n    int u, v;\n    int weight;  // estimated or actual weight\n    double estimated_dist;  // estimated distance based on center coordinates\n    \n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nstruct QueryResult {\n    vector<pair<int, int>> edges;  // edges in the MST\n};\n\nclass Solution {\npublic:\n    int N, M, Q, L, W;\n    vector<int> G;\n    vector<City> cities;\n    vector<vector<int>> groups;\n    vector<vector<Edge>> group_edges;\n    int query_count = 0;\n    \n    void read_input() {\n        cin >> N >> M >> Q >> L >> W;\n        G.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> G[i];\n        }\n        \n        cities.resize(N);\n        for (int i = 0; i < N; i++) {\n            cities[i].id = i;\n            cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n            cities[i].cx = (cities[i].lx + cities[i].rx) / 2.0;\n            cities[i].cy = (cities[i].ly + cities[i].ry) / 2.0;\n            // Calculate uncertainty as the diagonal of the rectangle\n            cities[i].uncertainty = sqrt(pow(cities[i].rx - cities[i].lx, 2) + \n                                        pow(cities[i].ry - cities[i].ly, 2));\n        }\n    }\n    \n    double estimated_distance(int i, int j) {\n        double dx = cities[i].cx - cities[j].cx;\n        double dy = cities[i].cy - cities[j].cy;\n        return sqrt(dx * dx + dy * dy);\n    }\n    \n    void group_cities() {\n        // Sort cities by their estimated center coordinates\n        vector<int> city_ids(N);\n        for (int i = 0; i < N; i++) {\n            city_ids[i] = i;\n        }\n        \n        // We'll use a simple approach: divide the sorted list into groups of the required sizes\n        sort(city_ids.begin(), city_ids.end(), [this](int a, int b) {\n            if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n            return cities[a].cy < cities[b].cy;\n        });\n        \n        // Divide into groups of specified sizes\n        groups.resize(M);\n        int start_idx = 0;\n        for (int i = 0; i < M; i++) {\n            groups[i].resize(G[i]);\n            for (int j = 0; j < G[i]; j++) {\n                groups[i][j] = city_ids[start_idx + j];\n            }\n            start_idx += G[i];\n        }\n    }\n    \n    QueryResult query_mst(const vector<int>& city_subset) {\n        assert(city_subset.size() >= 2 && city_subset.size() <= L);\n        assert(query_count < Q);\n        \n        cout << \"? \" << city_subset.size();\n        for (int city : city_subset) {\n            cout << \" \" << city;\n        }\n        cout << endl;\n        cout.flush();\n        \n        QueryResult result;\n        result.edges.resize(city_subset.size() - 1);\n        for (int i = 0; i < city_subset.size() - 1; i++) {\n            cin >> result.edges[i].first >> result.edges[i].second;\n            if (result.edges[i].first > result.edges[i].second) {\n                swap(result.edges[i].first, result.edges[i].second);\n            }\n        }\n        \n        query_count++;\n        return result;\n    }\n    \n    void gather_mst_info() {\n        group_edges.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            // For each group, perform queries to gather MST information\n            int group_size = G[i];\n            \n            // If the group is small enough, query the entire group at once\n            if (group_size <= L) {\n                vector<int> subset = groups[i];\n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n                continue;\n            }\n            \n            // For larger groups, we'll use a more sophisticated approach\n            // First, sort cities within the group by their estimated positions\n            vector<int> sorted_group = groups[i];\n            sort(sorted_group.begin(), sorted_group.end(), [this](int a, int b) {\n                if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n                return cities[a].cy < cities[b].cy;\n            });\n            \n            // We'll create a list of potential edges, sorted by estimated distance\n            vector<pair<double, pair<int, int>>> potential_edges;\n            for (int u = 0; u < group_size; u++) {\n                for (int v = u + 1; v < group_size; v++) {\n                    double dist = estimated_distance(sorted_group[u], sorted_group[v]);\n                    potential_edges.emplace_back(dist, make_pair(u, v));\n                }\n            }\n            \n            sort(potential_edges.begin(), potential_edges.end());\n            \n            // We'll select subsets for querying based on the shortest potential edges\n            set<int> selected_cities;\n            vector<vector<int>> subsets;\n            \n            // Start with the cities connected by the shortest edges\n            for (const auto& [dist, edge] : potential_edges) {\n                if (query_count >= Q) break;\n                \n                int u = edge.first;\n                int v = edge.second;\n                \n                // If both cities are already in a subset, skip\n                if (selected_cities.count(u) && selected_cities.count(v)) continue;\n                \n                // Create a new subset containing these cities and some nearby ones\n                vector<int> subset;\n                subset.push_back(sorted_group[u]);\n                subset.push_back(sorted_group[v]);\n                selected_cities.insert(u);\n                selected_cities.insert(v);\n                \n                // Add nearby cities until we reach the maximum subset size\n                for (const auto& [dist2, edge2] : potential_edges) {\n                    if (subset.size() >= L) break;\n                    \n                    int u2 = edge2.first;\n                    int v2 = edge2.second;\n                    \n                    if (u2 == u || u2 == v || v2 == u || v2 == v) {\n                        int new_city = (selected_cities.count(u2) == 0) ? u2 : v2;\n                        if (selected_cities.count(new_city) == 0) {\n                            subset.push_back(sorted_group[new_city]);\n                            selected_cities.insert(new_city);\n                        }\n                    }\n                }\n                \n                subsets.push_back(subset);\n                \n                // If we've selected all cities, we're done\n                if (selected_cities.size() >= group_size) break;\n            }\n            \n            // If we haven't selected all cities, add the remaining ones\n            for (int j = 0; j < group_size; j++) {\n                if (selected_cities.count(j) == 0) {\n                    // Create a subset with this city and some nearby ones\n                    vector<int> subset;\n                    subset.push_back(sorted_group[j]);\n                    selected_cities.insert(j);\n                    \n                    // Add the closest cities\n                    for (const auto& [dist, edge] : potential_edges) {\n                        if (subset.size() >= L) break;\n                        \n                        int u = edge.first;\n                        int v = edge.second;\n                        \n                        if (u == j || v == j) {\n                            int other = (u == j) ? v : u;\n                            if (selected_cities.count(other) == 0) {\n                                subset.push_back(sorted_group[other]);\n                                selected_cities.insert(other);\n                            }\n                        }\n                    }\n                    \n                    subsets.push_back(subset);\n                }\n            }\n            \n            // Query each subset\n            for (const auto& subset : subsets) {\n                if (query_count >= Q) break;\n                if (subset.size() < 2) continue;\n                \n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n            }\n            \n            if (query_count >= Q) break;  // We've used all our queries\n        }\n    }\n    \n    void construct_final_msts() {\n        // For each group, we'll use the edges we've gathered to construct a connected graph\n        // If we don't have enough edges to form a spanning tree, we'll add more\n        \n        for (int i = 0; i < M; i++) {\n            // We need G[i] - 1 edges to connect G[i] cities\n            \n            // First, let's create a graph from the edges we've gathered\n            vector<vector<int>> graph(G[i]);\n            map<pair<int, int>, int> edge_to_index;\n            \n            for (int j = 0; j < group_edges[i].size(); j++) {\n                const Edge& e = group_edges[i][j];\n                int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                \n                graph[u_idx].push_back(v_idx);\n                graph[v_idx].push_back(u_idx);\n                \n                edge_to_index[{min(u_idx, v_idx), max(u_idx, v_idx)}] = j;\n            }\n            \n            // Check if the graph is connected\n            vector<bool> visited(G[i], false);\n            queue<int> q;\n            q.push(0);\n            visited[0] = true;\n            int visited_count = 1;\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                for (int v : graph[u]) {\n                    if (!visited[v]) {\n                        visited[v] = true;\n                        visited_count++;\n                        q.push(v);\n                    }\n                }\n            }\n            \n            if (visited_count == G[i]) {\n                // The graph is already connected, so we can use a subset of the edges\n                // We'll use Kruskal's algorithm to find the MST\n                vector<Edge> mst_edges;\n                vector<int> parent(G[i]);\n                for (int j = 0; j < G[i]; j++) {\n                    parent[j] = j;\n                }\n                \n                function<int(int)> find = [&](int x) {\n                    if (parent[x] != x) {\n                        parent[x] = find(parent[x]);\n                    }\n                    return parent[x];\n                };\n                \n                auto unite = [&](int x, int y) {\n                    x = find(x);\n                    y = find(y);\n                    if (x != y) {\n                        parent[x] = y;\n                        return true;\n                    }\n                    return false;\n                };\n                \n                // Sort edges by estimated distance\n                sort(group_edges[i].begin(), group_edges[i].end(), \n                    [](const Edge& a, const Edge& b) {\n                        return a.estimated_dist < b.estimated_dist;\n                    });\n                \n                for (const Edge& e : group_edges[i]) {\n                    int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                    int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                    \n                    if (unite(u_idx, v_idx)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == G[i] - 1) break;\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            } else {\n                // The graph is not connected, so we need to add more edges\n                // We'll use Prim's algorithm starting from the visited component\n                \n                // First, let's create a complete graph with estimated distances\n                vector<vector<pair<int, double>>> complete_graph(G[i]);\n                for (int u = 0; u < G[i]; u++) {\n                    for (int v = u + 1; v < G[i]; v++) {\n                        double dist = estimated_distance(groups[i][u], groups[i][v]);\n                        complete_graph[u].emplace_back(v, dist);\n                        complete_graph[v].emplace_back(u, dist);\n                    }\n                }\n                \n                // Use Prim's algorithm to find the MST\n                vector<bool> in_mst(G[i], false);\n                vector<Edge> mst_edges;\n                priority_queue<pair<double, pair<int, int>>, \n                              vector<pair<double, pair<int, int>>>, \n                              greater<pair<double, pair<int, int>>>> pq;\n                \n                // Start with the visited component\n                for (int u = 0; u < G[i]; u++) {\n                    if (visited[u]) {\n                        in_mst[u] = true;\n                        for (const auto& [v, dist] : complete_graph[u]) {\n                            if (!in_mst[v]) {\n                                pq.emplace(dist, make_pair(u, v));\n                            }\n                        }\n                    }\n                }\n                \n                while (!pq.empty() && mst_edges.size() < G[i] - 1) {\n                    auto [dist, edge] = pq.top();\n                    pq.pop();\n                    int u = edge.first;\n                    int v = edge.second;\n                    \n                    if (!in_mst[v]) {\n                        in_mst[v] = true;\n                        Edge e;\n                        e.u = groups[i][u];\n                        e.v = groups[i][v];\n                        e.weight = 0;\n                        e.estimated_dist = dist;\n                        mst_edges.push_back(e);\n                        \n                        for (const auto& [next_v, next_dist] : complete_graph[v]) {\n                            if (!in_mst[next_v]) {\n                                pq.emplace(next_dist, make_pair(v, next_v));\n                            }\n                        }\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            }\n        }\n    }\n    \n    void output_solution() {\n        cout << \"!\" << endl;\n        \n        for (int i = 0; i < M; i++) {\n            // Output the cities in the group\n            for (int j = 0; j < G[i]; j++) {\n                if (j > 0) cout << \" \";\n                cout << groups[i][j];\n            }\n            cout << endl;\n            \n            // Output the edges\n            for (const auto& edge : group_edges[i]) {\n                cout << edge.u << \" \" << edge.v << endl;\n            }\n        }\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        group_cities();\n        gather_mst_info();\n        construct_final_msts();\n        output_solution();\n    }\n};\n\nint main() {\n    Solution solution;\n    solution.solve();\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <array>\n#include <string>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int MAX_ACTIONS = 2 * N * M;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> blocks;\n    vector<string> actions;\n    int remaining_actions;\n    \n    State(int i, int j, int budget = MAX_ACTIONS) : i(i), j(j), blocks(N, vector<bool>(N, false)), remaining_actions(budget) {}\n    \n    bool is_valid(int ni, int nj) const {\n        return ni >= 0 && ni < N && nj >= 0 && nj < N;\n    }\n    \n    bool can_move(int dir) const {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        return is_valid(ni, nj) && !blocks[ni][nj];\n    }\n    \n    State move(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        new_state.i += di[dir];\n        new_state.j += dj[dir];\n        new_state.actions.push_back(string(1, 'M') + dir_chars[dir]);\n        new_state.remaining_actions--;\n        return new_state;\n    }\n    \n    pair<State, int> slide(int dir) const {\n        if (remaining_actions <= 0) return {*this, 0};\n        State new_state = *this;\n        int ni = i, nj = j;\n        int steps = 0;\n        \n        while (true) {\n            int nni = ni + di[dir];\n            int nnj = nj + dj[dir];\n            \n            if (!is_valid(nni, nnj) || blocks[nni][nnj]) {\n                break;\n            }\n            \n            ni = nni;\n            nj = nnj;\n            steps++;\n        }\n        \n        if (steps > 0) {\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.actions.push_back(string(1, 'S') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return {new_state, steps};\n    }\n    \n    State alter(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (is_valid(ni, nj)) {\n            new_state.blocks[ni][nj] = !blocks[ni][nj];\n            new_state.actions.push_back(string(1, 'A') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return new_state;\n    }\n    \n    int manhattan_distance(int ti, int tj) const {\n        return abs(i - ti) + abs(j - tj);\n    }\n    \n    vector<string> find_path(int target_i, int target_j) const {\n        if (remaining_actions <= 0) return vector<string>();\n        \n        queue<tuple<int, int, vector<string>>> q;\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n        \n        q.push({i, j, vector<string>()});\n        visited[i][j] = true;\n        \n        while (!q.empty()) {\n            auto [ci, cj, path] = q.front();\n            q.pop();\n            \n            if (ci == target_i && cj == target_j) {\n                vector<string> result;\n                while (ci != i || cj != j) {\n                    auto [pi, pj] = parent[ci][cj];\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (pi + di[dir] == ci && pj + dj[dir] == cj) {\n                            result.push_back(string(1, 'M') + dir_chars[dir]);\n                            break;\n                        }\n                    }\n                    ci = pi;\n                    cj = pj;\n                }\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ci + di[dir];\n                int nj = cj + dj[dir];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj] && !blocks[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent[ni][nj] = {ci, cj};\n                    vector<string> new_path = path;\n                    new_path.push_back(string(1, 'M') + dir_chars[dir]);\n                    q.push({ni, nj, new_path});\n                }\n            }\n        }\n        \n        return vector<string>();\n    }\n    \n    bool try_slide_to_target(int target_i, int target_j) {\n        if (remaining_actions < 10) return false; // Not enough actions for sliding\n        \n        int initial_manhattan = manhattan_distance(target_i, target_j);\n        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n        \n        // Try all directions as primary\n        for (int primary_dir = 0; primary_dir < 4; primary_dir++) {\n            State temp_state = *this;\n            \n            // Slide in primary direction\n            auto [slide_state, slide_steps] = temp_state.slide(primary_dir);\n            temp_state = slide_state;\n            \n            if (temp_state.manhattan_distance(target_i, target_j) >= initial_manhattan) {\n                continue; // No improvement\n            }\n            \n            // Try to place a block to stop at target\n            for (int stop_dir = 0; stop_dir < 4; stop_dir++) {\n                if (stop_dir == primary_dir || stop_dir == (primary_dir ^ 1)) {\n                    continue; // Same or opposite direction\n                }\n                \n                State temp_state2 = temp_state;\n                \n                // Calculate where to place the stopping block\n                int stop_i = target_i + di[stop_dir];\n                int stop_j = target_j + dj[stop_dir];\n                \n                if (temp_state2.is_valid(stop_i, stop_j)) {\n                    // Try to place block if not already there\n                    if (!temp_state2.blocks[stop_i][stop_j]) {\n                        temp_state2 = temp_state2.alter(stop_dir);\n                        \n                        // Try sliding to target\n                        auto [slide_result, steps] = temp_state2.slide(stop_dir);\n                        if (slide_result.i == target_i && slide_result.j == target_j) {\n                            *this = slide_result;\n                            return true;\n                        }\n                        \n                        // If slide didn't reach target, try moving from there\n                        auto path = slide_result.find_path(target_i, target_j);\n                        if (!path.empty() && path.size() <= 5) {\n                            for (const auto& action : path) {\n                                for (int dir = 0; dir < 4; dir++) {\n                                    if (action[1] == dir_chars[dir]) {\n                                        slide_result = slide_result.move(dir);\n                                        break;\n                                    }\n                                }\n                            }\n                            \n                            if (slide_result.i == target_i && slide_result.j == target_j) {\n                                *this = slide_result;\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return false;\n    }\n    \n    void remove_unnecessary_blocks(const vector<pair<int, int>>& future_targets) {\n        // Remove blocks that are not needed for future targets\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (blocks[i][j]) {\n                    bool needed = false;\n                    \n                    // Check if block is near any future target\n                    for (const auto& target : future_targets) {\n                        if (abs(i - target.first) <= 2 && abs(j - target.second) <= 2) {\n                            needed = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!needed) {\n                        // Remove the block\n                        for (int dir = 0; dir < 4; dir++) {\n                            if (i - di[dir] == this->i && j - dj[dir] == this->j) {\n                                *this = alter(dir);\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    void optimize_blocks(const vector<pair<int, int>>& targets, int current_target_idx) {\n        // Only optimize if we have enough actions\n        if (remaining_actions < 50) return;\n        \n        vector<pair<int, int>> future_targets(targets.begin() + current_target_idx + 1, \n                                            targets.begin() + min(current_target_idx + 6, (int)targets.size()));\n        \n        // Remove unnecessary blocks first\n        remove_unnecessary_blocks(future_targets);\n        \n        // Place blocks for future targets only if beneficial\n        for (const auto& target : future_targets) {\n            int target_i = target.first;\n            int target_j = target.second;\n            \n            // Only place blocks if we're far from the target\n            if (manhattan_distance(target_i, target_j) > 5) {\n                // Try to place a block that will help slide to this target\n                for (int dir = 0; dir < 4; dir++) {\n                    int block_i = target_i + di[dir];\n                    int block_j = target_j + dj[dir];\n                    \n                    if (is_valid(block_i, block_j) && !blocks[block_i][block_j]) {\n                        // Check if placing this block would create a good sliding opportunity\n                        int path_cost = manhattan_distance(block_i, block_j) + 2; // Move to adjacent + alter\n                        if (path_cost < manhattan_distance(target_i, target_j) * 0.7) {\n                            auto path = find_path(block_i, block_j);\n                            if (!path.empty() && path.size() <= 5) {\n                                for (const auto& action : path) {\n                                    for (int d = 0; d < 4; d++) {\n                                        if (action[1] == dir_chars[d]) {\n                                            *this = move(d);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                *this = alter(dir);\n                                break; // Only place one block per target\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<pair<int, int>> targets(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    State current(targets[0].first, targets[0].second);\n    \n    for (int k = 1; k < m; k++) {\n        int target_i = targets[k].first;\n        int target_j = targets[k].second;\n        \n        // If we're running low on actions, use BFS only\n        if (current.remaining_actions < 100) {\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n            continue;\n        }\n        \n        int manhattan = current.manhattan_distance(target_i, target_j);\n        \n        // Try sliding for medium to long distances\n        if (manhattan > 3 && current.try_slide_to_target(target_i, target_j)) {\n            // Sliding succeeded, continue\n        } else {\n            // Use BFS for short distances or when sliding fails\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Optimize blocks for future targets\n        current.optimize_blocks(targets, k);\n    }\n    \n    for (const auto& action : current.actions) {\n        cout << action[0] << \" \" << action[1] << '\\n';\n    }\n    \n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;  // (a, b) and (c, d) are diagonal vertices\n    \n    Rectangle(int a = 0, int b = 0, int c = 0, int d = 0) : a(a), b(b), c(c), d(d) {\n        if (a > c) swap(a, c);\n        if (b > d) swap(b, d);\n    }\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(int x, int y) const {\n        return a <= x && x < c && b <= y && y < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n    \n    int overlap_area(const Rectangle& other) const {\n        int overlap_a = max(a, other.a);\n        int overlap_b = max(b, other.b);\n        int overlap_c = min(c, other.c);\n        int overlap_d = min(d, other.d);\n        \n        if (overlap_a >= overlap_c || overlap_b >= overlap_d) return 0;\n        return (overlap_c - overlap_a) * (overlap_d - overlap_b);\n    }\n};\n\nstruct Company {\n    int x, y, r;\n    Rectangle rect;\n    \n    double satisfaction() const {\n        int s = rect.area();\n        if (!rect.contains(x, y)) return 0.0;\n        \n        double min_val = min(r, s);\n        double max_val = max(r, s);\n        return 1.0 - pow(1.0 - min_val / max_val, 2);\n    }\n};\n\nvector<Rectangle> solve(int n, const vector<pair<int, int>>& points, const vector<int>& rs) {\n    vector<Company> companies(n);\n    for (int i = 0; i < n; ++i) {\n        companies[i].x = points[i].first;\n        companies[i].y = points[i].second;\n        companies[i].r = rs[i];\n    }\n    \n    // Sort companies by desired area (largest first)\n    vector<int> indices(n);\n    for (int i = 0; i < n; ++i) indices[i] = i;\n    sort(indices.begin(), indices.end(), [&](int i, int j) {\n        return companies[i].r > companies[j].r;\n    });\n    \n    // Create a space-filling curve based initial placement\n    vector<pair<int, int>> space_order;\n    for (int y = 0; y < 100; ++y) {\n        for (int x = 0; x < 100; ++x) {\n            space_order.emplace_back(x, y);\n        }\n    }\n    \n    // Shuffle the space order for better distribution\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    shuffle(space_order.begin(), space_order.end(), rng);\n    \n    // Initialize rectangles\n    vector<Rectangle> placed_rectangles;\n    for (int i : indices) {\n        int x = companies[i].x;\n        int y = companies[i].y;\n        int r = companies[i].r;\n        \n        // Find dimensions that give area close to r\n        int w = min(10000, static_cast<int>(sqrt(r)) + 1);\n        int h = r / w;\n        if (w * h < r) h++;\n        \n        // Try to place the rectangle at different positions\n        Rectangle best_rect;\n        double best_score = -1.0;\n        \n        // Try positions based on the space order\n        for (const auto& pos : space_order) {\n            int base_x = pos.first * 100;\n            int base_y = pos.second * 100;\n            \n            // Try to place the rectangle with the desired point inside\n            int a = max(0, min(base_x, x - w/2));\n            int c = min(10000, a + w);\n            if (c - a < w) a = c - w;\n            \n            int b = max(0, min(base_y, y - h/2));\n            int d = min(10000, b + h);\n            if (d - b < h) b = d - h;\n            \n            Rectangle rect(a, b, c, d);\n            \n            // Check if the rectangle contains the desired point\n            if (!rect.contains(x, y)) continue;\n            \n            // Check for overlaps with already placed rectangles\n            bool has_overlap = false;\n            for (const auto& placed : placed_rectangles) {\n                if (rect.overlaps(placed)) {\n                    has_overlap = true;\n                    break;\n                }\n            }\n            \n            if (!has_overlap) {\n                // Calculate a score based on how close the area is to the desired area\n                int area = rect.area();\n                double score = 1.0 - abs(area - r) / max(area, r);\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rect = rect;\n                }\n            }\n        }\n        \n        // If we couldn't find a non-overlapping position, use a minimal rectangle\n        if (best_score < 0) {\n            best_rect = Rectangle(x, y, x + 1, y + 1);\n        }\n        \n        companies[i].rect = best_rect;\n        placed_rectangles.push_back(best_rect);\n    }\n    \n    // Resolve overlaps iteratively\n    const int MAX_ITERATIONS = 100;\n    for (int iter = 0; iter < MAX_ITERATIONS; ++iter) {\n        bool has_overlap = false;\n        \n        for (int i = 0; i < n; ++i) {\n            for (int j = i + 1; j < n; ++j) {\n                if (companies[i].rect.overlaps(companies[j].rect)) {\n                    has_overlap = true;\n                    \n                    // Calculate overlap area\n                    int overlap_area = companies[i].rect.overlap_area(companies[j].rect);\n                    \n                    // Resolve overlap by shrinking the rectangle with smaller desired area\n                    if (companies[i].r < companies[j].r) {\n                        // Shrink company i's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_i.a < rect_j.a) {\n                                rect_i.c = min(rect_i.c, rect_j.a);\n                            } else {\n                                rect_i.a = max(rect_i.a, rect_j.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_i.b < rect_j.b) {\n                                rect_i.d = min(rect_i.d, rect_j.b);\n                            } else {\n                                rect_i.b = max(rect_i.b, rect_j.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                            // Try a different approach\n                            rect_i = companies[i].rect;\n                            if (rect_j.a < rect_i.a) {\n                                rect_i.a = rect_j.c;\n                            } else {\n                                rect_i.c = rect_j.a;\n                            }\n                            \n                            if (!rect_i.contains(companies[i].x, companies[i].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_i = Rectangle(companies[i].x, companies[i].y, companies[i].x + 1, companies[i].y + 1);\n                            }\n                        }\n                    } else {\n                        // Shrink company j's rectangle\n                        Rectangle& rect_i = companies[i].rect;\n                        Rectangle& rect_j = companies[j].rect;\n                        \n                        // Determine which dimension to shrink\n                        int overlap_width = min(rect_i.c, rect_j.c) - max(rect_i.a, rect_j.a);\n                        int overlap_height = min(rect_i.d, rect_j.d) - max(rect_i.b, rect_j.b);\n                        \n                        if (overlap_width < overlap_height) {\n                            // Shrink width\n                            if (rect_j.a < rect_i.a) {\n                                rect_j.c = min(rect_j.c, rect_i.a);\n                            } else {\n                                rect_j.a = max(rect_j.a, rect_i.c);\n                            }\n                        } else {\n                            // Shrink height\n                            if (rect_j.b < rect_i.b) {\n                                rect_j.d = min(rect_j.d, rect_i.b);\n                            } else {\n                                rect_j.b = max(rect_j.b, rect_i.d);\n                            }\n                        }\n                        \n                        // Ensure the rectangle still contains the desired point\n                        if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                            // Try a different approach\n                            rect_j = companies[j].rect;\n                            if (rect_i.a < rect_j.a) {\n                                rect_j.a = rect_i.c;\n                            } else {\n                                rect_j.c = rect_i.a;\n                            }\n                            \n                            if (!rect_j.contains(companies[j].x, companies[j].y)) {\n                                // If still not containing, give up and use a minimal rectangle\n                                rect_j = Rectangle(companies[j].x, companies[j].y, companies[j].x + 1, companies[j].y + 1);\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (!has_overlap) break;\n    }\n    \n    // Final optimization using simulated annealing\n    rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n    double temperature = 100.0;\n    const double COOLING_RATE = 0.95;\n    const int SA_ITERATIONS = 1000;\n    \n    double current_score = 0.0;\n    for (int i = 0; i < n; ++i) {\n        current_score += companies[i].satisfaction();\n    }\n    \n    for (int iter = 0; iter < SA_ITERATIONS; ++iter) {\n        temperature *= COOLING_RATE;\n        \n        // Choose a random company to modify\n        int i = rng() % n;\n        Rectangle old_rect = companies[i].rect;\n        double old_satisfaction = companies[i].satisfaction();\n        \n        // Choose a random modification\n        int mod_type = rng() % 8;\n        \n        switch (mod_type) {\n            case 0: {  // Move left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                companies[i].rect.c -= delta;\n                break;\n            }\n            case 1: {  // Move right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.a += delta;\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 2: {  // Move up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                companies[i].rect.d -= delta;\n                break;\n            }\n            case 3: {  // Move down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.b += delta;\n                companies[i].rect.d += delta;\n                break;\n            }\n            case 4: {  // Expand left\n                int delta = min(rng() % 10 + 1, companies[i].rect.a);\n                companies[i].rect.a -= delta;\n                break;\n            }\n            case 5: {  // Expand right\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.c);\n                companies[i].rect.c += delta;\n                break;\n            }\n            case 6: {  // Expand up\n                int delta = min(rng() % 10 + 1, companies[i].rect.b);\n                companies[i].rect.b -= delta;\n                break;\n            }\n            case 7: {  // Expand down\n                int delta = min(rng() % 10 + 1, 10000 - companies[i].rect.d);\n                companies[i].rect.d += delta;\n                break;\n            }\n        }\n        \n        // Check constraints\n        bool valid = true;\n        \n        // Check if the rectangle still contains the desired point\n        if (!companies[i].rect.contains(companies[i].x, companies[i].y)) {\n            valid = false;\n        }\n        \n        // Check for overlaps\n        if (valid) {\n            for (int j = 0; j < n; ++j) {\n                if (i != j && companies[i].rect.overlaps(companies[j].rect)) {\n                    valid = false;\n                    break;\n                }\n            }\n        }\n        \n        if (valid) {\n            double new_satisfaction = companies[i].satisfaction();\n            double delta_score = new_satisfaction - old_satisfaction;\n            \n            // Accept or reject the move based on simulated annealing\n            if (delta_score > 0 || exp(delta_score / temperature) > (rng() % 1000) / 1000.0) {\n                current_score += delta_score;\n            } else {\n                companies[i].rect = old_rect;\n            }\n        } else {\n            companies[i].rect = old_rect;\n        }\n    }\n    \n    // Extract the final rectangles\n    vector<Rectangle> result;\n    for (int i = 0; i < n; ++i) {\n        result.push_back(companies[i].rect);\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n;\n    cin >> n;\n    \n    vector<pair<int, int>> points(n);\n    vector<int> rs(n);\n    \n    for (int i = 0; i < n; ++i) {\n        cin >> points[i].first >> points[i].second >> rs[i];\n    }\n    \n    vector<Rectangle> solution = solve(n, points, rs);\n    \n    for (const auto& rect : solution) {\n        cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n    }\n    \n    return 0;\n}","ahc002":"#include <iostream>\n#include <vector>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <random>\n#include <numeric>\n\nusing namespace std;\n\nstruct Tile {\n    int id;\n    vector<pair<int, int>> squares;\n    int total_value;\n    set<int> adjacent_tiles;\n    bool is_1x1;\n    pair<int, int> other_square;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<vector<int>> tiles(50, vector<int>(50));\n    vector<vector<int>> points(50, vector<int>(50));\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> tiles[i][j];\n        }\n    }\n    \n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            cin >> points[i][j];\n        }\n    }\n    \n    // Build tile information\n    map<int, Tile> tile_map;\n    for (int i = 0; i < 50; ++i) {\n        for (int j = 0; j < 50; ++j) {\n            int tile_id = tiles[i][j];\n            if (tile_map.find(tile_id) == tile_map.end()) {\n                tile_map[tile_id] = {tile_id, {}, 0, {}, true, {-1, -1}};\n            }\n            tile_map[tile_id].squares.emplace_back(i, j);\n            tile_map[tile_id].total_value += points[i][j];\n        }\n    }\n    \n    // Determine tile types and other square\n    for (auto& [id, tile] : tile_map) {\n        if (tile.squares.size() == 2) {\n            tile.is_1x1 = false;\n            if (tile.squares[0].first == tile.squares[1].first) {\n                // 1x2 tile\n                if (tile.squares[0].second < tile.squares[1].second) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            } else {\n                // 2x1 tile\n                if (tile.squares[0].first < tile.squares[1].first) {\n                    tile.other_square = tile.squares[1];\n                } else {\n                    tile.other_square = tile.squares[0];\n                }\n            }\n        }\n    }\n    \n    // Build adjacency information\n    for (auto& [id, tile] : tile_map) {\n        for (auto& [i, j] : tile.squares) {\n            vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n            for (auto& [di, dj] : directions) {\n                int ni = i + di, nj = j + dj;\n                if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                    int neighbor_tile_id = tiles[ni][nj];\n                    if (neighbor_tile_id != id) {\n                        tile.adjacent_tiles.insert(neighbor_tile_id);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Start tile\n    int start_tile_id = tiles[si][sj];\n    set<int> visited_tiles;\n    visited_tiles.insert(start_tile_id);\n    int current_i = si, current_j = sj;\n    string path;\n    \n    // If starting tile is 1x2 or 2x1, move to the other square\n    if (!tile_map[start_tile_id].is_1x1) {\n        auto [oi, oj] = tile_map[start_tile_id].other_square;\n        if (oi < current_i) {\n            path += 'U';\n            current_i = oi;\n        } else if (oi > current_i) {\n            path += 'D';\n            current_i = oi;\n        } else if (oj < current_j) {\n            path += 'L';\n            current_j = oj;\n        } else if (oj > current_j) {\n            path += 'R';\n            current_j = oj;\n        }\n    }\n    \n    // Greedy walk with probabilistic selection\n    random_device rd;\n    mt19937 gen(rd());\n    \n    while (true) {\n        vector<pair<int, pair<char, pair<int, int>>>> candidates;\n        \n        vector<pair<char, pair<int, int>>> directions = {\n            {'U', {-1, 0}}, {'D', {1, 0}}, {'L', {0, -1}}, {'R', {0, 1}}\n        };\n        \n        for (auto& [dir, delta] : directions) {\n            int ni = current_i + delta.first;\n            int nj = current_j + delta.second;\n            \n            if (ni >= 0 && ni < 50 && nj >= 0 && nj < 50) {\n                int next_tile_id = tiles[ni][nj];\n                \n                if (visited_tiles.find(next_tile_id) == visited_tiles.end()) {\n                    int score = tile_map[next_tile_id].total_value;\n                    \n                    // Consider connectivity\n                    int adjacent_unvisited = 0;\n                    for (int adj_id : tile_map[next_tile_id].adjacent_tiles) {\n                        if (visited_tiles.find(adj_id) == visited_tiles.end()) {\n                            adjacent_unvisited++;\n                        }\n                    }\n                    \n                    score += adjacent_unvisited * 10;  // Weight for connectivity\n                    candidates.emplace_back(score, make_pair(dir, make_pair(ni, nj)));\n                }\n            }\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Probabilistic selection\n        vector<double> probabilities;\n        for (int i = 0; i < candidates.size(); ++i) {\n            probabilities.push_back(pow(0.8, i));\n        }\n        \n        double sum_probs = accumulate(probabilities.begin(), probabilities.end(), 0.0);\n        for (double& prob : probabilities) {\n            prob /= sum_probs;\n        }\n        \n        uniform_real_distribution<> dis(0.0, 1.0);\n        double r = dis(gen);\n        double cumulative = 0.0;\n        int selected_idx = 0;\n        \n        for (int i = 0; i < probabilities.size(); ++i) {\n            cumulative += probabilities[i];\n            if (r <= cumulative) {\n                selected_idx = i;\n                break;\n            }\n        }\n        \n        auto& [score, move_info] = candidates[selected_idx];\n        auto& [dir, next_pos] = move_info;\n        auto& [ni, nj] = next_pos;\n        \n        int next_tile_id = tiles[ni][nj];\n        \n        path += dir;\n        visited_tiles.insert(next_tile_id);\n        current_i = ni;\n        current_j = nj;\n        \n        // If tile is 1x2 or 2x1, move to the other square\n        if (!tile_map[next_tile_id].is_1x1) {\n            auto [oi, oj] = tile_map[next_tile_id].other_square;\n            if (oi != ni || oj != nj) {\n                if (oi < ni) {\n                    path += 'U';\n                    current_i = oi;\n                } else if (oi > ni) {\n                    path += 'D';\n                    current_i = oi;\n                } else if (oj < nj) {\n                    path += 'L';\n                    current_j = oj;\n                } else if (oj > nj) {\n                    path += 'R';\n                    current_j = oj;\n                }\n            }\n        }\n    }\n    \n    cout << path << endl;\n    \n    return 0;\n}","ahc003":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <tuple>\n#include <functional>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int N = 30;\n\nint main() {\n    vector<vector<double>> hor_est(N, vector<double>(N-1, 5000.0));\n    vector<vector<double>> ver_est(N-1, vector<double>(N, 5000.0));\n\n    for (int k = 0; k < 1000; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n\n        vector<vector<double>> dist(N, vector<double>(N, 1e18));\n        vector<vector<tuple<int, int, char>>> parent(N, vector<tuple<int, int, char>>(N, make_tuple(-1, -1, ' ')));\n        priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n\n        dist[si][sj] = 0;\n        pq.push({0.0, si, sj});\n\n        while (!pq.empty()) {\n            auto [d, i, j] = pq.top();\n            pq.pop();\n            if (i == ti && j == tj) {\n                break;\n            }\n            if (d > dist[i][j]) {\n                continue;\n            }\n\n            if (i > 0) {\n                double w = ver_est[i-1][j];\n                if (d + w < dist[i-1][j]) {\n                    dist[i-1][j] = d + w;\n                    parent[i-1][j] = make_tuple(i, j, 'U');\n                    pq.push({dist[i-1][j], i-1, j});\n                }\n            }\n            if (i < N-1) {\n                double w = ver_est[i][j];\n                if (d + w < dist[i+1][j]) {\n                    dist[i+1][j] = d + w;\n                    parent[i+1][j] = make_tuple(i, j, 'D');\n                    pq.push({dist[i+1][j], i+1, j});\n                }\n            }\n            if (j > 0) {\n                double w = hor_est[i][j-1];\n                if (d + w < dist[i][j-1]) {\n                    dist[i][j-1] = d + w;\n                    parent[i][j-1] = make_tuple(i, j, 'L');\n                    pq.push({dist[i][j-1], i, j-1});\n                }\n            }\n            if (j < N-1) {\n                double w = hor_est[i][j];\n                if (d + w < dist[i][j+1]) {\n                    dist[i][j+1] = d + w;\n                    parent[i][j+1] = make_tuple(i, j, 'R');\n                    pq.push({dist[i][j+1], i, j+1});\n                }\n            }\n        }\n\n        string path_str = \"\";\n        int i = ti, j = tj;\n        while (i != si || j != sj) {\n            auto [pi, pj, dir] = parent[i][j];\n            path_str += dir;\n            i = pi;\n            j = pj;\n        }\n        reverse(path_str.begin(), path_str.end());\n\n        cout << path_str << endl;\n        cout.flush();\n\n        int y;\n        cin >> y;\n\n        double L_est = 0.0;\n        vector<double*> edges_in_path;\n        i = si; j = sj;\n        for (char c : path_str) {\n            if (c == 'U') {\n                L_est += ver_est[i-1][j];\n                edges_in_path.push_back(&ver_est[i-1][j]);\n                i--;\n            } else if (c == 'D') {\n                L_est += ver_est[i][j];\n                edges_in_path.push_back(&ver_est[i][j]);\n                i++;\n            } else if (c == 'L') {\n                L_est += hor_est[i][j-1];\n                edges_in_path.push_back(&hor_est[i][j-1]);\n                j--;\n            } else if (c == 'R') {\n                L_est += hor_est[i][j];\n                edges_in_path.push_back(&hor_est[i][j]);\n                j++;\n            }\n        }\n\n        int m = edges_in_path.size();\n        double error = y - L_est;\n        for (double* ptr : edges_in_path) {\n            *ptr += 0.1 * error / m;\n        }\n    }\n\n    return 0;\n}","ahc004":"#include <iostream>\n#include <vector>\n#include <string>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <chrono>\n#include <array>\n#include <cassert>\n\nusing namespace std;\nusing namespace std::chrono;\n\nconstexpr int FIXED_N = 20;\nconstexpr char EMPTY = '.';\nconstexpr array<char, 8> CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H'};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Problem {\n    int N;\n    int M;\n    vector<string> strings;\n    vector<vector<array<int, 8>>> char_freq;\n    vector<int> string_importance;\n    \n    Problem(int N, int M, const vector<string>& strings) : N(N), M(M), strings(strings) {\n        assert(N == FIXED_N);\n        char_freq.resize(N);\n        for (int i = 0; i < N; i++) {\n            char_freq[i].resize(N);\n            for (int j = 0; j < N; j++) {\n                char_freq[i][j].fill(0);\n            }\n        }\n        \n        string_importance.resize(M);\n        for (int i = 0; i < M; i++) {\n            string_importance[i] = strings[i].size();\n        }\n        \n        for (int idx = 0; idx < M; idx++) {\n            const auto& s = strings[idx];\n            int k = s.size();\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    for (int p = 0; p < min(k, N); p++) {\n                        int c = s[p] - 'A';\n                        char_freq[i][(j + p) % N][c] += string_importance[idx];\n                        char_freq[(i + p) % N][j][c] += string_importance[idx];\n                    }\n                }\n            }\n        }\n    }\n};\n\nstruct Solution {\n    const Problem* problem;\n    vector<string> matrix;\n    vector<bool> satisfied;\n    int score;\n    int satisfied_count;\n    int empty_count;\n    \n    Solution(const Problem& problem) : problem(&problem), matrix(problem.N, string(problem.N, EMPTY)), \n                                      satisfied(problem.M, false), score(0), satisfied_count(0), \n                                      empty_count(problem.N * problem.N) {}\n    \n    Solution(const Solution& other) : problem(other.problem), matrix(other.matrix), \n                                      satisfied(other.satisfied), score(other.score), \n                                      satisfied_count(other.satisfied_count), \n                                      empty_count(other.empty_count) {}\n    \n    Solution& operator=(const Solution& other) {\n        if (this != &other) {\n            problem = other.problem;\n            matrix = other.matrix;\n            satisfied = other.satisfied;\n            score = other.score;\n            satisfied_count = other.satisfied_count;\n            empty_count = other.empty_count;\n        }\n        return *this;\n    }\n    \n    bool can_place_string(const string& s, int i, int j, bool horizontal) {\n        int k = s.size();\n        \n        if (horizontal) {\n            for (int p = 0; p < k; p++) {\n                int col = (j + p) % problem->N;\n                if (matrix[i][col] != EMPTY && matrix[i][col] != s[p]) {\n                    return false;\n                }\n            }\n        } else {\n            for (int p = 0; p < k; p++) {\n                int row = (i + p) % problem->N;\n                if (matrix[row][j] != EMPTY && matrix[row][j] != s[p]) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    void place_string(const string& s, int i, int j, bool horizontal) {\n        int k = s.size();\n        \n        if (horizontal) {\n            for (int p = 0; p < k; p++) {\n                int col = (j + p) % problem->N;\n                matrix[i][col] = s[p];\n            }\n        } else {\n            for (int p = 0; p < k; p++) {\n                int row = (i + p) % problem->N;\n                matrix[row][j] = s[p];\n            }\n        }\n    }\n    \n    void fill_based_on_freq() {\n        for (int i = 0; i < problem->N; i++) {\n            for (int j = 0; j < problem->N; j++) {\n                if (matrix[i][j] == EMPTY) {\n                    int max_freq = -1;\n                    char best_char = EMPTY;\n                    for (int c = 0; c < 8; c++) {\n                        if (problem->char_freq[i][j][c] > max_freq) {\n                            max_freq = problem->char_freq[i][j][c];\n                            best_char = 'A' + c;\n                        }\n                    }\n                    if (best_char != EMPTY) {\n                        matrix[i][j] = best_char;\n                    }\n                }\n            }\n        }\n        empty_count = 0;\n    }\n    \n    bool is_subsequence(const string& s) const {\n        int k = s.size();\n        \n        for (int i = 0; i < problem->N; i++) {\n            for (int j = 0; j < problem->N; j++) {\n                bool match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[i][(j + p) % problem->N] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n                \n                match = true;\n                for (int p = 0; p < k; p++) {\n                    if (matrix[(i + p) % problem->N][j] != s[p]) {\n                        match = false;\n                        break;\n                    }\n                }\n                if (match) return true;\n            }\n        }\n        \n        return false;\n    }\n    \n    int calculate_score() {\n        satisfied_count = 0;\n        for (int i = 0; i < problem->M; i++) {\n            satisfied[i] = is_subsequence(problem->strings[i]);\n            if (satisfied[i]) {\n                satisfied_count++;\n            }\n        }\n        \n        if (satisfied_count < problem->M) {\n            score = static_cast<int>(round(1e8 * static_cast<double>(satisfied_count) / problem->M));\n        } else {\n            score = static_cast<int>(round(1e8 * (2.0 * problem->N * problem->N) / (2.0 * problem->N * problem->N - empty_count)));\n        }\n        \n        return score;\n    }\n    \n    void local_search(int iterations) {\n        uniform_int_distribution<int> pos_dist(0, problem->N-1);\n        uniform_int_distribution<int> char_dist(0, 7);\n        uniform_real_distribution<double> real_dist(0.0, 1.0);\n        \n        int current_score = calculate_score();\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Save current state\n            char old_char = EMPTY;\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            \n            if (matrix[i][j] == EMPTY) continue;\n            \n            old_char = matrix[i][j];\n            matrix[i][j] = CHARS[char_dist(rng)];\n            \n            int new_score = calculate_score();\n            \n            if (new_score > current_score) {\n                current_score = new_score;\n            } else {\n                // Revert change\n                matrix[i][j] = old_char;\n            }\n        }\n    }\n    \n    void print() const {\n        for (const auto& row : matrix) {\n            cout << row << endl;\n        }\n    }\n};\n\nSolution solve(const Problem& problem) {\n    Solution solution(problem);\n    \n    // Sort strings by importance (length) descending\n    vector<int> sorted_indices(problem.M);\n    for (int i = 0; i < problem.M; i++) {\n        sorted_indices[i] = i;\n    }\n    sort(sorted_indices.begin(), sorted_indices.end(), [&](int a, int b) {\n        return problem.string_importance[a] > problem.string_importance[b];\n    });\n    \n    // Try to place the most important strings first\n    uniform_int_distribution<int> pos_dist(0, problem.N-1);\n    uniform_real_distribution<double> real_dist(0.0, 1.0);\n    \n    for (int idx : sorted_indices) {\n        const string& s = problem.strings[idx];\n        int k = s.size();\n        \n        bool placed = false;\n        \n        // Try 10 random positions\n        for (int attempt = 0; attempt < 10; attempt++) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            bool horizontal = real_dist(rng) < 0.5;\n            \n            if (solution.can_place_string(s, i, j, horizontal)) {\n                solution.place_string(s, i, j, horizontal);\n                placed = true;\n                break;\n            }\n        }\n    }\n    \n    // Fill remaining cells based on frequency\n    solution.fill_based_on_freq();\n    \n    // Perform a very limited local search\n    solution.local_search(100);\n    \n    return solution;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    assert(N == FIXED_N);\n    \n    vector<string> strings(M);\n    for (int i = 0; i < M; i++) {\n        cin >> strings[i];\n    }\n    \n    Problem problem(N, M, strings);\n    Solution solution = solve(problem);\n    solution.print();\n    \n    return 0;\n}","ahc005":"#include <iostream>\n#include <vector>\n#include <list>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <unordered_map>\n#include <unordered_set>\n#include <string>\n#include <utility>\n#include <array>\nusing namespace std;\n\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    Point(int i_=0, int j_=0) : i(i_), j(j_) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    bool operator<(const Point& other) const {\n        if (i != other.i) return i < other.i;\n        return j < other.j;\n    }\n};\n\nstruct Segment {\n    bool is_horizontal;\n    int fixed_index;\n    int start, end;\n    Segment(bool h, int idx, int s, int e) : is_horizontal(h), fixed_index(idx), start(s), end(e) {}\n    bool operator==(const Segment& other) const {\n        return is_horizontal == other.is_horizontal && fixed_index == other.fixed_index && start == other.start && end == other.end;\n    }\n    bool operator<(const Segment& other) const {\n        if (is_horizontal != other.is_horizontal) return is_horizontal < other.is_horizontal;\n        if (fixed_index != other.fixed_index) return fixed_index < other.fixed_index;\n        if (start != other.start) return start < other.start;\n        return end < other.end;\n    }\n};\n\nvector<Point> dial_shortest_path(const vector<vector<int>>& grid_cost, int N, Point start, Point end) {\n    int max_cost = 9 * N * N;\n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n    vector<list<Point>> buckets(max_cost + 1);\n\n    dist[start.i][start.j] = 0;\n    buckets[0].push_back(start);\n\n    for (int idx = 0; idx <= max_cost; idx++) {\n        while (!buckets[idx].empty()) {\n            Point p = buckets[idx].front();\n            buckets[idx].pop_front();\n            if (dist[p.i][p.j] < idx) continue;\n            if (p == end) break;\n            for (auto [di, dj] : {array<int,2>{-1,0}, {1,0}, {0,-1}, {0,1}}) {\n                int ni = p.i + di;\n                int nj = p.j + dj;\n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                if (grid_cost[ni][nj] == -1) continue;\n                int new_cost = dist[p.i][p.j] + grid_cost[ni][nj];\n                if (new_cost < dist[ni][nj]) {\n                    dist[ni][nj] = new_cost;\n                    parent[ni][nj] = p;\n                    if (new_cost <= max_cost) {\n                        buckets[new_cost].push_front(Point(ni, nj));\n                    }\n                }\n            }\n        }\n    }\n\n    vector<Point> path;\n    if (dist[end.i][end.j] == INF) {\n        return path;\n    }\n    Point cur = end;\n    while (cur != start) {\n        path.push_back(cur);\n        cur = parent[cur.i][cur.j];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\nvector<int> bipartite_matching(const vector<vector<int>>& graph, int nH, int nV) {\n    vector<int> matchH(nH, -1);\n    vector<int> matchV(nV, -1);\n    vector<bool> visited;\n\n    function<bool(int)> dfs = [&](int u) {\n        visited[u] = true;\n        for (int v : graph[u]) {\n            if (matchV[v] == -1 || (!visited[matchV[v]] && dfs(matchV[v]))) {\n                matchH[u] = v;\n                matchV[v] = u;\n                return true;\n            }\n        }\n        return false;\n    };\n\n    for (int u = 0; u < nH; u++) {\n        visited.assign(nH, false);\n        dfs(u);\n    }\n\n    vector<int> matching(nH, -1);\n    for (int u = 0; u < nH; u++) {\n        if (matchH[u] != -1) {\n            matching[u] = matchH[u];\n        }\n    }\n    return matching;\n}\n\nvector<Segment> konig_vertex_cover(const vector<vector<int>>& graph, const vector<int>& matching, int nH, int nV) {\n    vector<vector<int>> residual_graph(nH + nV);\n    for (int u = 0; u < nH; u++) {\n        for (int v : graph[u]) {\n            if (matching[u] == v) {\n                residual_graph[nH + v].push_back(u);\n            } else {\n                residual_graph[u].push_back(nH + v);\n            }\n        }\n    }\n\n    vector<bool> marked(nH + nV, false);\n    queue<int> q;\n    for (int u = 0; u < nH; u++) {\n        if (matching[u] == -1) {\n            marked[u] = true;\n            q.push(u);\n        }\n    }\n\n    while (!q.empty()) {\n        int node = q.front();\n        q.pop();\n        for (int neighbor : residual_graph[node]) {\n            if (!marked[neighbor]) {\n                marked[neighbor] = true;\n                q.push(neighbor);\n            }\n        }\n    }\n\n    vector<Segment> vertex_cover;\n    for (int u = 0; u < nH; u++) {\n        if (!marked[u]) {\n            vertex_cover.push_back(Segment(true, u, 0, 0));\n        }\n    }\n    for (int v = 0; v < nV; v++) {\n        if (marked[nH + v]) {\n            vertex_cover.push_back(Segment(false, v, 0, 0));\n        }\n    }\n    return vertex_cover;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, si, sj;\n    cin >> N >> si >> sj;\n    vector<string> grid_str(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid_str[i];\n    }\n\n    vector<vector<int>> grid_cost(N, vector<int>(N, -1));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                grid_cost[i][j] = grid_str[i][j] - '0';\n            }\n        }\n    }\n\n    vector<Segment> h_segments, v_segments;\n    vector<vector<Segment*>> h_segment_ptr(N, vector<Segment*>(N, nullptr));\n    vector<vector<Segment*>> v_segment_ptr(N, vector<Segment*>(N, nullptr));\n\n    for (int i = 0; i < N; i++) {\n        int j = 0;\n        while (j < N) {\n            if (grid_str[i][j] == '#') {\n                j++;\n                continue;\n            }\n            int start = j;\n            while (j < N && grid_str[i][j] != '#') {\n                j++;\n            }\n            int end = j - 1;\n            h_segments.emplace_back(true, i, start, end);\n            Segment* seg = &h_segments.back();\n            for (int k = start; k <= end; k++) {\n                h_segment_ptr[i][k] = seg;\n            }\n        }\n    }\n\n    for (int j = 0; j < N; j++) {\n        int i = 0;\n        while (i < N) {\n            if (grid_str[i][j] == '#') {\n                i++;\n                continue;\n            }\n            int start = i;\n            while (i < N && grid_str[i][j] != '#') {\n                i++;\n            }\n            int end = i - 1;\n            v_segments.emplace_back(false, j, start, end);\n            Segment* seg = &v_segments.back();\n            for (int k = start; k <= end; k++) {\n                v_segment_ptr[k][j] = seg;\n            }\n        }\n    }\n\n    unordered_map<Segment*, int> h_segment_to_id;\n    unordered_map<Segment*, int> v_segment_to_id;\n    for (int i = 0; i < h_segments.size(); i++) {\n        h_segment_to_id[&h_segments[i]] = i;\n    }\n    for (int i = 0; i < v_segments.size(); i++) {\n        v_segment_to_id[&v_segments[i]] = i;\n    }\n\n    vector<vector<int>> bipartite_graph(h_segments.size());\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid_str[i][j] != '#') {\n                Segment* h_seg = h_segment_ptr[i][j];\n                Segment* v_seg = v_segment_ptr[i][j];\n                int h_id = h_segment_to_id[h_seg];\n                int v_id = v_segment_to_id[v_seg];\n                bipartite_graph[h_id].push_back(v_id);\n            }\n        }\n    }\n\n    vector<int> matching = bipartite_matching(bipartite_graph, h_segments.size(), v_segments.size());\n    vector<Segment> vertex_cover_segments = konig_vertex_cover(bipartite_graph, matching, h_segments.size(), v_segments.size());\n\n    Segment* h_start_seg = h_segment_ptr[si][sj];\n    Segment* v_start_seg = v_segment_ptr[si][sj];\n    vector<Segment> segments_to_cover;\n    for (const Segment& seg : vertex_cover_segments) {\n        if (seg.is_horizontal) {\n            if (&h_segments[seg.fixed_index] != h_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        } else {\n            if (&v_segments[seg.fixed_index] != v_start_seg) {\n                segments_to_cover.push_back(seg);\n            }\n        }\n    }\n\n    vector<Point> candidate_points;\n    for (const Segment& seg : segments_to_cover) {\n        if (seg.is_horizontal) {\n            candidate_points.emplace_back(seg.fixed_index, seg.start);\n        } else {\n            candidate_points.emplace_back(seg.start, seg.fixed_index);\n        }\n    }\n\n    vector<Point> P;\n    P.emplace_back(si, sj);\n    P.insert(P.end(), candidate_points.begin(), candidate_points.end());\n    int total_points = P.size();\n\n    vector<vector<int>> dist_matrix(total_points, vector<int>(total_points, INF));\n    vector<vector<vector<Point>>> paths(total_points, vector<vector<Point>>(total_points));\n\n    for (int i = 0; i < total_points; i++) {\n        vector<Point> path_to_end = dial_shortest_path(grid_cost, N, P[i], P[i]);\n        for (int j = 0; j < total_points; j++) {\n            if (i == j) {\n                dist_matrix[i][j] = 0;\n                paths[i][j] = {P[i]};\n                continue;\n            }\n            vector<Point> path_ij = dial_shortest_path(grid_cost, N, P[i], P[j]);\n            if (path_ij.empty()) {\n                dist_matrix[i][j] = INF;\n                paths[i][j] = {};\n            } else {\n                int total_cost = 0;\n                Point cur = P[i];\n                for (const Point& p : path_ij) {\n                    total_cost += grid_cost[p.i][p.j];\n                }\n                dist_matrix[i][j] = total_cost;\n                paths[i][j] = path_ij;\n            }\n        }\n    }\n\n    vector<int> tour;\n    vector<bool> visited(total_points, false);\n    visited[0] = true;\n    tour.push_back(0);\n    int current = 0;\n    for (int step = 1; step < total_points; step++) {\n        int best_next = -1;\n        int best_dist = INF;\n        for (int j = 0; j < total_points; j++) {\n            if (!visited[j] && dist_matrix[current][j] < best_dist) {\n                best_dist = dist_matrix[current][j];\n                best_next = j;\n            }\n        }\n        if (best_next == -1) break;\n        visited[best_next] = true;\n        tour.push_back(best_next);\n        current = best_next;\n    }\n    tour.push_back(0);\n\n    vector<Point> full_route;\n    full_route.push_back(P[0]);\n    for (int idx = 0; idx < tour.size() - 1; idx++) {\n        int i = tour[idx];\n        int j = tour[idx+1];\n        if (i == j) continue;\n        vector<Point>& path_segment = paths[i][j];\n        full_route.insert(full_route.end(), path_segment.begin(), path_segment.end());\n    }\n\n    string moves;\n    for (int i = 0; i < full_route.size() - 1; i++) {\n        Point a = full_route[i];\n        Point b = full_route[i+1];\n        if (b.i < a.i) moves += 'U';\n        else if (b.i > a.i) moves += 'D';\n        else if (b.j < a.j) moves += 'L';\n        else if (b.j > a.j) moves += 'R';\n    }\n\n    cout << moves << endl;\n\n    return 0;\n}","future-contest-2022-qual":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <set>\n#include <cstdlib>\n#include <cstring>\n#include <sys/select.h>\n#include <unistd.h>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n\n    vector<vector<int>> d(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    vector<vector<int>> prerequisites(N);\n    for (int i = 0; i < R; ++i) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        prerequisites[v].push_back(u);\n    }\n\n    vector<int> task_status(N, -1);\n    vector<int> member_status(M, -1);\n    vector<int> start_day(N, 0);\n\n    vector<vector<int>> S(M, vector<int>(K, 0));\n\n    int current_day = 1;\n\n    while (true) {\n        string line;\n        getline(cin, line);\n        if (line == \"-1\") {\n            break;\n        }\n\n        vector<int> tokens;\n        char* cstr = new char[line.length() + 1];\n        strcpy(cstr, line.c_str());\n        char* p = strtok(cstr, \" \");\n        while (p != nullptr) {\n            tokens.push_back(atoi(p));\n            p = strtok(nullptr, \" \");\n        }\n        delete[] cstr;\n\n        int n = tokens[0];\n        vector<int> completed_members;\n        for (int i = 1; i <= n; ++i) {\n            completed_members.push_back(tokens[i]);\n        }\n\n        for (int idx = 0; idx < n; ++idx) {\n            int j0 = completed_members[idx];\n            int j = j0 - 1;\n            if (member_status[j] == -1) {\n                continue;\n            }\n            int task_i = member_status[j];\n            task_status[task_i] = 1;\n            member_status[j] = -1;\n\n            int t_taken = current_day - start_day[task_i];\n\n            if (t_taken == 1) {\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        S[j][k] = d[task_i][k];\n                    }\n                }\n            } else {\n                int current_w = 0;\n                for (int k = 0; k < K; ++k) {\n                    if (d[task_i][k] > S[j][k]) {\n                        current_w += d[task_i][k] - S[j][k];\n                    }\n                }\n\n                if (current_w > t_taken + 3) {\n                    int reduction_needed = current_w - (t_taken + 3);\n                    vector<pair<int, int>> deficits;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[task_i][k] > S[j][k]) {\n                            int deficit_k = d[task_i][k] - S[j][k];\n                            deficits.emplace_back(deficit_k, k);\n                        }\n                    }\n                    sort(deficits.begin(), deficits.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                        return a.first > b.first;\n                    });\n                    for (auto& def : deficits) {\n                        if (reduction_needed <= 0) break;\n                        int deficit_k = def.first;\n                        int k = def.second;\n                        int increase = min(deficit_k, reduction_needed);\n                        S[j][k] += increase;\n                        reduction_needed -= increase;\n                    }\n                }\n            }\n        }\n\n        vector<int> available_tasks;\n        for (int i = 0; i < N; ++i) {\n            if (task_status[i] != -1) continue;\n            bool available = true;\n            for (int pre : prerequisites[i]) {\n                if (task_status[pre] != 1) {\n                    available = false;\n                    break;\n                }\n            }\n            if (available) {\n                available_tasks.push_back(i);\n            }\n        }\n\n        vector<int> free_team_members;\n        for (int j = 0; j < M; ++j) {\n            if (member_status[j] == -1) {\n                free_team_members.push_back(j);\n            }\n        }\n\n        vector<pair<int, int>> assignments;\n        if (!available_tasks.empty() && !free_team_members.empty()) {\n            vector<pair<int, int>> task_list;\n            for (int i : available_tasks) {\n                int min_exp = -1;\n                for (int j : free_team_members) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (min_exp == -1 || exp_time < min_exp) {\n                        min_exp = exp_time;\n                    }\n                }\n                task_list.emplace_back(min_exp, i);\n            }\n\n            sort(task_list.begin(), task_list.end(), [](const pair<int, int>& a, const pair<int, int>& b) {\n                return a.first > b.first;\n            });\n\n            set<int> free_set(free_team_members.begin(), free_team_members.end());\n            for (auto& p : task_list) {\n                if (free_set.empty()) break;\n                int i = p.second;\n                int best_j = -1;\n                int best_exp = -1;\n                for (int j : free_set) {\n                    int w = 0;\n                    for (int k = 0; k < K; ++k) {\n                        if (d[i][k] > S[j][k]) {\n                            w += d[i][k] - S[j][k];\n                        }\n                    }\n                    int exp_time = (w == 0) ? 1 : max(1, w);\n                    if (best_j == -1 || exp_time < best_exp) {\n                        best_j = j;\n                        best_exp = exp_time;\n                    }\n                }\n                assignments.emplace_back(best_j, i);\n                free_set.erase(best_j);\n            }\n        }\n\n        cout << assignments.size();\n        for (auto& p : assignments) {\n            cout << \" \" << p.first + 1 << \" \" << p.second + 1;\n        }\n        cout << endl;\n        cout.flush();\n\n        for (auto& p : assignments) {\n            int j = p.first;\n            int i = p.second;\n            task_status[i] = 0;\n            member_status[j] = i;\n            start_day[i] = current_day;\n        }\n\n        current_day++;\n    }\n\n    return 0;\n}","ahc006":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <set>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Order {\n    int id;\n    int a, b;  // restaurant\n    int c, d;  // destination\n};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n    \n    int manhattan_distance(const Point& other) const {\n        return abs(x - other.x) + abs(y - other.y);\n    }\n};\n\nvector<Order> orders;\nvector<int> selected_orders;\nvector<Point> route;\n\nmt19937 rng;\n\nint calculate_total_distance(const vector<Point>& route) {\n    int total = 0;\n    for (size_t i = 0; i < route.size() - 1; i++) {\n        total += route[i].manhattan_distance(route[i + 1]);\n    }\n    return total;\n}\n\nbool is_valid_route(const vector<int>& selected, const vector<Point>& route) {\n    vector<pair<int, int>> positions(1001, {-1, -1});\n    \n    for (size_t i = 0; i < route.size(); i++) {\n        for (int order_id : selected) {\n            const auto& order = orders[order_id];\n            if (route[i].x == order.a && route[i].y == order.b) {\n                if (positions[order_id].first == -1) {\n                    positions[order_id].first = i;\n                }\n            } else if (route[i].x == order.c && route[i].y == order.d) {\n                if (positions[order_id].second == -1) {\n                    positions[order_id].second = i;\n                }\n            }\n        }\n    }\n    \n    for (int order_id : selected) {\n        if (positions[order_id].first == -1 || positions[order_id].second == -1) {\n            return false;\n        }\n        if (positions[order_id].first >= positions[order_id].second) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nvector<Point> construct_greedy_route(const vector<int>& selected) {\n    vector<Point> route = {Point(400, 400)};\n    set<int> remaining_orders(selected.begin(), selected.end());\n    \n    while (!remaining_orders.empty()) {\n        int best_order = -1;\n        int best_pos = -1;\n        int best_increase = 1e9;\n        \n        for (int order_id : remaining_orders) {\n            const auto& order = orders[order_id];\n            \n            // Try inserting restaurant and destination in all possible positions\n            for (size_t i = 0; i <= route.size(); i++) {\n                for (size_t j = i + 1; j <= route.size(); j++) {\n                    vector<Point> temp_route = route;\n                    temp_route.insert(temp_route.begin() + i, Point(order.a, order.b));\n                    temp_route.insert(temp_route.begin() + j, Point(order.c, order.d));\n                    \n                    int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n                    \n                    if (increase < best_increase) {\n                        best_increase = increase;\n                        best_order = order_id;\n                        best_pos = i;\n                    }\n                }\n            }\n        }\n        \n        if (best_order == -1) break;\n        \n        const auto& best_order_data = orders[best_order];\n        size_t insert_dest_pos = best_pos + 1;\n        \n        // Find best position for destination\n        for (size_t j = best_pos + 1; j <= route.size(); j++) {\n            vector<Point> temp_route = route;\n            temp_route.insert(temp_route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n            temp_route.insert(temp_route.begin() + j, Point(best_order_data.c, best_order_data.d));\n            \n            int increase = calculate_total_distance(temp_route) - calculate_total_distance(route);\n            \n            if (increase < best_increase) {\n                best_increase = increase;\n                insert_dest_pos = j;\n            }\n        }\n        \n        route.insert(route.begin() + best_pos, Point(best_order_data.a, best_order_data.b));\n        route.insert(route.begin() + insert_dest_pos, Point(best_order_data.c, best_order_data.d));\n        remaining_orders.erase(best_order);\n    }\n    \n    route.push_back(Point(400, 400));\n    \n    assert(is_valid_route(selected, route));\n    return route;\n}\n\nvector<int> select_initial_orders() {\n    // Calculate center of mass for all orders\n    double center_x = 0, center_y = 0;\n    for (const auto& order : orders) {\n        center_x += (order.a + order.c) / 2.0;\n        center_y += (order.b + order.d) / 2.0;\n    }\n    center_x /= orders.size();\n    center_y /= orders.size();\n    \n    // Calculate distances from center for each order\n    vector<pair<double, int>> order_distances;\n    for (size_t i = 0; i < orders.size(); i++) {\n        const auto& order = orders[i];\n        double mid_x = (order.a + order.c) / 2.0;\n        double mid_y = (order.b + order.d) / 2.0;\n        double dist = abs(mid_x - center_x) + abs(mid_y - center_y);\n        order_distances.emplace_back(dist, i);\n    }\n    \n    // Sort by distance and select the closest 50\n    sort(order_distances.begin(), order_distances.end());\n    vector<int> selected;\n    for (int i = 0; i < 50; i++) {\n        selected.push_back(order_distances[i].second);\n    }\n    \n    return selected;\n}\n\nvector<Point> simulated_annealing(const vector<int>& initial_selected, const vector<Point>& initial_route) {\n    vector<int> current_selected = initial_selected;\n    vector<Point> current_route = initial_route;\n    int current_distance = calculate_total_distance(current_route);\n    \n    vector<int> best_selected = current_selected;\n    vector<Point> best_route = current_route;\n    int best_distance = current_distance;\n    \n    const double initial_temp = 1000.0;\n    const double final_temp = 1.0;\n    const int iterations = 100000;\n    \n    double temp = initial_temp;\n    \n    for (int iter = 0; iter < iterations; iter++) {\n        temp = initial_temp * pow(final_temp / initial_temp, (double)iter / iterations);\n        \n        // Choose a random operation\n        int operation = uniform_int_distribution<int>(0, 2)(rng);\n        \n        if (operation == 0) {\n            // Swap two points in the route\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            int j = uniform_int_distribution<int>(1, current_route.size() - 2)(rng);\n            \n            if (i == j) continue;\n            \n            vector<Point> new_route = current_route;\n            swap(new_route[i], new_route[j]);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else if (operation == 1) {\n            // Reverse a segment\n            if (current_route.size() < 4) continue;\n            \n            int i = uniform_int_distribution<int>(1, current_route.size() - 3)(rng);\n            int j = uniform_int_distribution<int>(i + 1, current_route.size() - 2)(rng);\n            \n            vector<Point> new_route = current_route;\n            reverse(new_route.begin() + i, new_route.begin() + j + 1);\n            \n            if (is_valid_route(current_selected, new_route)) {\n                int new_distance = calculate_total_distance(new_route);\n                int delta = new_distance - current_distance;\n                \n                if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                    current_route = new_route;\n                    current_distance = new_distance;\n                    \n                    if (current_distance < best_distance) {\n                        best_route = current_route;\n                        best_distance = current_distance;\n                    }\n                }\n            }\n        } else {\n            // Swap an order in the selected set with one not in the set\n            vector<int> unselected;\n            for (size_t i = 0; i < orders.size(); i++) {\n                if (find(current_selected.begin(), current_selected.end(), i) == current_selected.end()) {\n                    unselected.push_back(i);\n                }\n            }\n            \n            if (unselected.empty()) continue;\n            \n            int idx_to_remove = uniform_int_distribution<int>(0, current_selected.size() - 1)(rng);\n            int idx_to_add = uniform_int_distribution<int>(0, unselected.size() - 1)(rng);\n            \n            vector<int> new_selected = current_selected;\n            new_selected[idx_to_remove] = unselected[idx_to_add];\n            sort(new_selected.begin(), new_selected.end());\n            \n            vector<Point> new_route = construct_greedy_route(new_selected);\n            int new_distance = calculate_total_distance(new_route);\n            int delta = new_distance - current_distance;\n            \n            if (delta < 0 || exp(-delta / temp) > uniform_real_distribution<double>(0, 1)(rng)) {\n                current_selected = new_selected;\n                current_route = new_route;\n                current_distance = new_distance;\n                \n                if (current_distance < best_distance) {\n                    best_selected = current_selected;\n                    best_route = current_route;\n                    best_distance = current_distance;\n                }\n            }\n        }\n    }\n    \n    return best_route;\n}\n\nvoid solve() {\n    // Read input\n    orders.resize(1000);\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].a >> orders[i].b >> orders[i].c >> orders[i].d;\n        orders[i].id = i;\n    }\n    \n    // Initialize random number generator\n    rng = mt19937(high_resolution_clock::now().time_since_epoch().count());\n    \n    // Select initial orders\n    selected_orders = select_initial_orders();\n    \n    // Construct initial route\n    route = construct_greedy_route(selected_orders);\n    \n    // Optimize with simulated annealing\n    route = simulated_annealing(selected_orders, route);\n    \n    // Output the result\n    cout << selected_orders.size();\n    for (int order_id : selected_orders) {\n        cout << \" \" << order_id + 1;  // Convert to 1-based indexing\n    }\n    cout << endl;\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.x << \" \" << p.y;\n    }\n    cout << endl;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc007":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <iomanip>\n#include <set>\n#include <cstring>\n\nusing namespace std;\n\nclass DSU {\nprivate:\n    vector<int> parent;\n    vector<int> rank;\npublic:\n    DSU(int n) {\n        parent.resize(n);\n        rank.resize(n, 0);\n        for (int i = 0; i < n; i++) {\n            parent[i] = i;\n        }\n    }\n\n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n\n    void union_set(int x, int y) {\n        int rx = find(x);\n        int ry = find(y);\n        if (rx == ry) {\n            return;\n        }\n        if (rank[rx] < rank[ry]) {\n            parent[rx] = ry;\n        } else if (rank[rx] > rank[ry]) {\n            parent[ry] = rx;\n        } else {\n            parent[ry] = rx;\n            rank[rx]++;\n        }\n    }\n};\n\nstruct Edge {\n    int u, v;\n    double d;\n    int index;\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N = 400;\n    int M = 1995;\n\n    vector<pair<int, int>> coords(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n\n    vector<Edge> edges(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v;\n        edges[i].index = i;\n        int u = edges[i].u, v = edges[i].v;\n        double dx = coords[u].first - coords[v].first;\n        double dy = coords[u].second - coords[v].second;\n        double dist = sqrt(dx*dx + dy*dy);\n        edges[i].d = round(dist);\n    }\n\n    vector<int> tree_id(M, -1);\n    vector<Edge> remaining_edges = edges;\n    for (int t = 0; t < 5; t++) {\n        sort(remaining_edges.begin(), remaining_edges.end(), [](const Edge& a, const Edge& b) {\n            return a.d < b.d;\n        });\n\n        DSU dsu_temp(N);\n        vector<Edge> tree_edges;\n        vector<Edge> new_remaining;\n\n        for (Edge& e : remaining_edges) {\n            int u = e.u, v = e.v;\n            if (dsu_temp.find(u) != dsu_temp.find(v)) {\n                dsu_temp.union_set(u, v);\n                tree_edges.push_back(e);\n                tree_id[e.index] = t+1;\n            } else {\n                new_remaining.push_back(e);\n            }\n        }\n\n        remaining_edges = new_remaining;\n    }\n\n    DSU dsu_online(N);\n    vector<vector<int>> comp_edge_count(N, vector<int>(N, 0));\n\n    for (int i = 0; i < M; i++) {\n        int u = edges[i].u, v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n        if (a != b) {\n            comp_edge_count[a][b]++;\n            comp_edge_count[b][a]++;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n\n        int u = edges[i].u;\n        int v = edges[i].v;\n        int a = dsu_online.find(u);\n        int b = dsu_online.find(v);\n\n        if (a == b) {\n            cout << 0 << endl;\n            cout.flush();\n            continue;\n        }\n\n        comp_edge_count[a][b]--;\n        comp_edge_count[b][a]--;\n\n        bool adopt = false;\n        if (comp_edge_count[a][b] == 0) {\n            adopt = true;\n        } else {\n            double progress = static_cast<double>(i) / M;\n            double base_threshold = 1.0;\n            double max_threshold = 3.0;\n            double factor = (6.0 - tree_id[i]) / 5.0;\n            double threshold = base_threshold + progress * (max_threshold - base_threshold) * factor;\n            if (l_i <= threshold * edges[i].d) {\n                adopt = true;\n            }\n        }\n\n        if (adopt) {\n            int root_a = a;\n            int root_b = b;\n            dsu_online.union_set(u, v);\n            int new_root = dsu_online.find(u);\n            int old_root = (new_root == root_a) ? root_b : root_a;\n\n            for (int c = 0; c < N; c++) {\n                int root_c = dsu_online.find(c);\n                if (root_c != c) continue;\n                if (root_c == new_root) continue;\n                if (comp_edge_count[old_root][root_c] > 0) {\n                    comp_edge_count[new_root][root_c] += comp_edge_count[old_root][root_c];\n                    comp_edge_count[root_c][new_root] += comp_edge_count[root_c][old_root];\n                    comp_edge_count[old_root][root_c] = 0;\n                    comp_edge_count[root_c][old_root] = 0;\n                }\n            }\n\n            cout << 1 << endl;\n            cout.flush();\n        } else {\n            cout << 0 << endl;\n            cout.flush();\n        }\n    }\n\n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <set>\n#include <cmath>\n#include <algorithm>\n#include <cctype>\n#include <cstring>\n#include <iomanip>\nusing namespace std;\n\nconst int GRID_SIZE = 30;\n\nstruct Position {\n    int x, y;\n    Position(int x=0, int y=0) : x(x), y(y) {}\n    bool operator<(const Position& other) const {\n        if (x != other.x) return x < other.x;\n        return y < other.y;\n    }\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nbool adjacent(const Position& a, const Position& b) {\n    return (abs(a.x - b.x) + abs(a.y - b.y) == 1);\n}\n\nbool is_buildable(int x, int y, const vector<Position>& pets, const vector<Position>& humans) {\n    for (const auto& pet : pets) {\n        if (pet.x == x && pet.y == y) {\n            return false;\n        }\n    }\n    for (const auto& human : humans) {\n        if (human.x == x && human.y == y) {\n            return false;\n        }\n    }\n\n    vector<pair<int,int>> adj = {{x-1,y}, {x+1,y}, {x,y-1}, {x,y+1}};\n    for (const auto& [ax, ay] : adj) {\n        if (ax < 1 || ax > 30 || ay < 1 || ay > 30) {\n            continue;\n        }\n        for (const auto& pet : pets) {\n            if (pet.x == ax && pet.y == ay) {\n                return false;\n            }\n        }\n    }\n    return true;\n}\n\nbool is_safe_to_move(int x, int y, bool grid[31][31], const set<Position>& building_set) {\n    if (x < 1 || x > 30 || y < 1 || y > 30) {\n        return false;\n    }\n    if (!grid[x][y]) {\n        return false;\n    }\n    if (building_set.find(Position(x,y)) != building_set.end()) {\n        return false;\n    }\n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(0);\n\n    int N, M;\n    cin >> N;\n    vector<Position> pets(N);\n    vector<int> pet_types(N);\n    for (int i = 0; i < N; i++) {\n        cin >> pets[i].x >> pets[i].y >> pet_types[i];\n    }\n    cin >> M;\n    vector<Position> humans(M);\n    for (int i = 0; i < M; i++) {\n        cin >> humans[i].x >> humans[i].y;\n    }\n\n    bool grid[31][31];\n    for (int i = 1; i <= 30; i++) {\n        for (int j = 1; j <= 30; j++) {\n            grid[i][j] = true;\n        }\n    }\n\n    vector<Position> perimeter;\n    for (int y = 10; y <= 20; y++) {\n        perimeter.push_back(Position(10, y));\n    }\n    for (int x = 11; x <= 20; x++) {\n        perimeter.push_back(Position(x, 20));\n    }\n    for (int y = 19; y >= 10; y--) {\n        perimeter.push_back(Position(20, y));\n    }\n    for (int x = 19; x >= 11; x--) {\n        perimeter.push_back(Position(x, 10));\n    }\n\n    vector<queue<Position>> human_queues(M);\n    int segment_size = perimeter.size() / M;\n    int extra = perimeter.size() % M;\n    int index = 0;\n    for (int i = 0; i < M; i++) {\n        int size = segment_size + (i < extra ? 1 : 0);\n        for (int j = 0; j < size; j++) {\n            human_queues[i].push(perimeter[index++]);\n        }\n    }\n\n    for (int turn = 0; turn < 300; turn++) {\n        string actions(M, '.');\n\n        if (turn < 20) {\n            for (int i = 0; i < M; i++) {\n                int x = humans[i].x;\n                int y = humans[i].y;\n                if (x >= 10 && x <= 20 && y >= 10 && y <= 20) {\n                    actions[i] = '.';\n                } else {\n                    int dx = 15 - x;\n                    int dy = 15 - y;\n                    if (abs(dx) > abs(dy)) {\n                        actions[i] = (dx > 0) ? 'D' : 'U';\n                    } else {\n                        actions[i] = (dy > 0) ? 'R' : 'L';\n                    }\n                }\n            }\n        } else {\n            set<Position> building_set;\n            vector<bool> will_build(M, false);\n\n            for (int i = 0; i < M; i++) {\n                if (human_queues[i].empty()) continue;\n                Position target = human_queues[i].front();\n                if (adjacent(humans[i], target) && is_buildable(target.x, target.y, pets, humans)) {\n                    building_set.insert(target);\n                    will_build[i] = true;\n                }\n            }\n\n            for (int i = 0; i < M; i++) {\n                if (will_build[i]) {\n                    Position target = human_queues[i].front();\n                    int dx = humans[i].x - target.x;\n                    int dy = humans[i].y - target.y;\n                    if (dx == -1) actions[i] = 'd';\n                    else if (dx == 1) actions[i] = 'u';\n                    else if (dy == -1) actions[i] = 'r';\n                    else if (dy == 1) actions[i] = 'l';\n                    human_queues[i].pop();\n                } else {\n                    if (human_queues[i].empty()) {\n                        actions[i] = '.';\n                    } else {\n                        Position target = human_queues[i].front();\n                        if (adjacent(humans[i], target)) {\n                            human_queues[i].pop();\n                            human_queues[i].push(target);\n                            actions[i] = '.';\n                        } else {\n                            vector<pair<int,int>> move_deltas = {{-1,0},{1,0},{0,-1},{0,1}};\n                            vector<char> move_dirs = {'U','D','L','R'};\n                            char best_move = '.';\n                            int best_dist = 1000000;\n                            for (int j = 0; j < 4; j++) {\n                                int nx = humans[i].x + move_deltas[j].first;\n                                int ny = humans[i].y + move_deltas[j].second;\n                                if (!is_safe_to_move(nx, ny, grid, building_set)) {\n                                    continue;\n                                }\n                                int d = abs(nx - target.x) + abs(ny - target.y);\n                                if (d < best_dist) {\n                                    best_dist = d;\n                                    best_move = move_dirs[j];\n                                }\n                            }\n                            actions[i] = best_move;\n                        }\n                    }\n                }\n            }\n\n            for (const auto& pos : building_set) {\n                grid[pos.x][pos.y] = false;\n            }\n        }\n\n        cout << actions << endl;\n        cout.flush();\n\n        for (int i = 0; i < N; i++) {\n            string s;\n            cin >> s;\n            for (char c : s) {\n                if (c == '.') break;\n                if (c == 'U') pets[i].x--;\n                else if (c == 'D') pets[i].x++;\n                else if (c == 'L') pets[i].y--;\n                else if (c == 'R') pets[i].y++;\n            }\n        }\n\n        for (int i = 0; i < M; i++) {\n            if (actions[i] == 'U') humans[i].x--;\n            else if (actions[i] == 'D') humans[i].x++;\n            else if (actions[i] == 'L') humans[i].y--;\n            else if (actions[i] == 'R') humans[i].y++;\n        }\n    }\n\n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n#include <climits>\n#include <random>\n#include <unordered_map>\nusing namespace std;\n\nstruct State {\n    int i, j;\n    string path;\n    double priority;\n    \n    bool operator>(const State& other) const {\n        return priority > other.priority;\n    }\n};\n\nvector<string> h_global, v_global;\n\nstring bfs_shortest_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\", 0});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            return s.path;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj], 0});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nstring astar_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> g_score(20, vector<int>(20, INT_MAX));\n    vector<vector<int>> f_score(20, vector<int>(20, INT_MAX));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    priority_queue<State, vector<State>, greater<State>> open_set;\n    \n    g_score[si][sj] = 0;\n    f_score[si][sj] = abs(si - ti) + abs(sj - tj);\n    open_set.push({si, sj, \"\", f_score[si][sj]});\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    while (!open_set.empty()) {\n        State current = open_set.top();\n        open_set.pop();\n        \n        if (current.i == ti && current.j == tj) {\n            return current.path;\n        }\n        \n        if (current.priority > f_score[current.i][current.j]) {\n            continue;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = current.i + di[d];\n            int nj = current.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (current.i > 0) can_move = (v[current.i-1][current.j] == '0');\n            } else if (d == 1) { // D\n                if (current.i < 19) can_move = (v[current.i][current.j] == '0');\n            } else if (d == 2) { // L\n                if (current.j > 0) can_move = (h[current.i][current.j-1] == '0');\n            } else { // R\n                if (current.j < 19) can_move = (h[current.i][current.j] == '0');\n            }\n            \n            if (!can_move) continue;\n            \n            int tentative_g_score = g_score[current.i][current.j] + 1;\n            \n            if (tentative_g_score < g_score[ni][nj]) {\n                paths[ni][nj] = current.path + dc[d];\n                g_score[ni][nj] = tentative_g_score;\n                f_score[ni][nj] = tentative_g_score + abs(ni - ti) + abs(nj - tj);\n                open_set.push({ni, nj, paths[ni][nj], f_score[ni][nj]});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nstring randomized_path(int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v) {\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<string>> paths(20, vector<string>(20, \"\"));\n    queue<State> q;\n    q.push({si, sj, \"\", 0});\n    dist[si][sj] = 0;\n    \n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    const char dc[] = {'U', 'D', 'L', 'R'};\n    \n    mt19937 rng(random_device{}());\n    \n    while (!q.empty()) {\n        State s = q.front();\n        q.pop();\n        \n        if (s.i == ti && s.j == tj) {\n            return s.path;\n        }\n        \n        vector<int> dirs = {0, 1, 2, 3};\n        shuffle(dirs.begin(), dirs.end(), rng);\n        \n        for (int d : dirs) {\n            int ni = s.i + di[d];\n            int nj = s.j + dj[d];\n            \n            if (ni < 0 || ni >= 20 || nj < 0 || nj >= 20) continue;\n            \n            bool can_move = false;\n            if (d == 0) { // U\n                if (s.i > 0) can_move = (v[s.i-1][s.j] == '0');\n            } else if (d == 1) { // D\n                if (s.i < 19) can_move = (v[s.i][s.j] == '0');\n            } else if (d == 2) { // L\n                if (s.j > 0) can_move = (h[s.i][s.j-1] == '0');\n            } else { // R\n                if (s.j < 19) can_move = (h[s.i][s.j] == '0');\n            }\n            \n            if (can_move && dist[ni][nj] == -1) {\n                dist[ni][nj] = dist[s.i][s.j] + 1;\n                paths[ni][nj] = s.path + dc[d];\n                q.push({ni, nj, paths[ni][nj], 0});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nint count_adjacent_walls(int i, int j, const vector<string>& h, const vector<string>& v) {\n    int walls = 0;\n    if (i == 0 || v[i-1][j] == '1') walls++;\n    if (i == 19 || v[i][j] == '1') walls++;\n    if (j == 0 || h[i][j-1] == '1') walls++;\n    if (j == 19 || h[i][j] == '1') walls++;\n    return walls;\n}\n\ndouble monte_carlo_score(const string& path, const vector<int>& redundancies, int si, int sj, int ti, int tj, const vector<string>& h, const vector<string>& v, double p, int trials = 1000) {\n    const int di[] = {-1, 1, 0, 0};\n    const int dj[] = {0, 0, -1, 1};\n    \n    double total_score = 0.0;\n    mt19937 rng(random_device{}());\n    uniform_real_distribution<double> dist(0.0, 1.0);\n    \n    for (int trial = 0; trial < trials; trial++) {\n        int ci = si, cj = sj;\n        int steps = 0;\n        bool reached = false;\n        int move_idx = 0;\n        int step_in_move = 0;\n        \n        while (steps < 200 && !reached) {\n            if (ci == ti && cj == tj) {\n                reached = true;\n                break;\n            }\n            \n            if (move_idx >= path.size()) {\n                break;\n            }\n            \n            char c = path[move_idx];\n            if (dist(rng) < p) {\n                // Forget, stay in place\n                step_in_move++;\n            } else {\n                // Try to move\n                int ni = ci, nj = cj;\n                bool can_move = false;\n                \n                if (c == 'U') {\n                    if (ci > 0 && v[ci-1][cj] == '0') {\n                        ni = ci - 1;\n                        can_move = true;\n                    }\n                } else if (c == 'D') {\n                    if (ci < 19 && v[ci][cj] == '0') {\n                        ni = ci + 1;\n                        can_move = true;\n                    }\n                } else if (c == 'L') {\n                    if (cj > 0 && h[ci][cj-1] == '0') {\n                        nj = cj - 1;\n                        can_move = true;\n                    }\n                } else if (c == 'R') {\n                    if (cj < 19 && h[ci][cj] == '0') {\n                        nj = cj + 1;\n                        can_move = true;\n                    }\n                }\n                \n                if (can_move) {\n                    ci = ni;\n                    cj = nj;\n                }\n                step_in_move++;\n            }\n            \n            if (step_in_move >= redundancies[move_idx]) {\n                move_idx++;\n                step_in_move = 0;\n            }\n            \n            steps++;\n        }\n        \n        if (reached) {\n            total_score += (401 - steps);\n        }\n    }\n    \n    return total_score / trials;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(19);\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    h_global = h;\n    v_global = v;\n    \n    vector<string> candidate_paths;\n    \n    string shortest = bfs_shortest_path(si, sj, ti, tj, h, v);\n    if (!shortest.empty()) candidate_paths.push_back(shortest);\n    \n    string astar = astar_path(si, sj, ti, tj, h, v);\n    if (!astar.empty() && astar != shortest) candidate_paths.push_back(astar);\n    \n    for (int i = 0; i < 3; i++) {\n        string rand_path = randomized_path(si, sj, ti, tj, h, v);\n        if (!rand_path.empty() && find(candidate_paths.begin(), candidate_paths.end(), rand_path) == candidate_paths.end()) {\n            candidate_paths.push_back(rand_path);\n        }\n    }\n    \n    if (candidate_paths.empty()) {\n        cout << \"\" << endl;\n        return 0;\n    }\n    \n    string best_path = \"\";\n    double best_score = -1;\n    vector<int> best_redundancies;\n    \n    for (const string& path : candidate_paths) {\n        vector<int> redundancies;\n        int total_length = 0;\n        int ci = si, cj = sj;\n        \n        for (char c : path) {\n            int walls = count_adjacent_walls(ci, cj, h, v);\n            int r = 1;\n            while (r <= 10) {\n                double prob = 1.0 - pow(p, r);\n                if (prob >= 0.95) {\n                    break;\n                }\n                r++;\n            }\n            r += walls / 2;\n            if (r > 10) r = 10;\n            redundancies.push_back(r);\n            total_length += r;\n            \n            if (c == 'U' && ci > 0 && v[ci-1][cj] == '0') ci--;\n            else if (c == 'D' && ci < 19 && v[ci][cj] == '0') ci++;\n            else if (c == 'L' && cj > 0 && h[ci][cj-1] == '0') cj--;\n            else if (c == 'R' && cj < 19 && h[ci][cj] == '0') cj++;\n        }\n        \n        if (total_length > 200) {\n            double scale = 200.0 / total_length;\n            vector<int> scaled_redundancies;\n            int scaled_length = 0;\n            for (int r : redundancies) {\n                int new_r = max(1, static_cast<int>(r * scale));\n                scaled_redundancies.push_back(new_r);\n                scaled_length += new_r;\n            }\n            redundancies = scaled_redundancies;\n        }\n        \n        double score = monte_carlo_score(path, redundancies, si, sj, ti, tj, h, v, p);\n        if (score > best_score) {\n            best_score = score;\n            best_path = path;\n            best_redundancies = redundancies;\n        }\n    }\n    \n    string robust_path;\n    for (int i = 0; i < best_path.size(); i++) {\n        robust_path += string(best_redundancies[i], best_path[i]);\n    }\n    \n    cout << robust_path << endl;\n    \n    return 0;\n}","ahc010":"","ahc011":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <string>\n#include <unordered_set>\n#include <tuple>\n#include <cmath>\n#include <climits>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nconst int dx[] = {0, 0, -1, 1};\nconst int dy[] = {-1, 1, 0, 0};\nconst char dir_char[] = {'L', 'R', 'U', 'D'};\n\nstruct State {\n    vector<vector<int>> board;\n    int empty_x, empty_y;\n    int last_move;\n    int connections;\n    int max_component;\n    string moves;\n};\n\nbool are_connected(int tile1, int tile2, int direction) {\n    if (direction == 0) return (tile1 & 1) && (tile2 & 4);\n    if (direction == 1) return (tile1 & 4) && (tile2 & 1);\n    if (direction == 2) return (tile1 & 2) && (tile2 & 8);\n    if (direction == 3) return (tile1 & 8) && (tile2 & 2);\n    return false;\n}\n\nint count_connections_full(const vector<vector<int>>& board, int N) {\n    int connections = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0) continue;\n            int tile = board[i][j];\n            if (i < N - 1 && board[i+1][j] != 0) {\n                if (are_connected(tile, board[i+1][j], 3)) {\n                    connections++;\n                }\n            }\n            if (j < N - 1 && board[i][j+1] != 0) {\n                if (are_connected(tile, board[i][j+1], 1)) {\n                    connections++;\n                }\n            }\n        }\n    }\n    return connections;\n}\n\nint compute_components(vector<vector<int>>& board, int N) {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_comp = 0;\n    for (int i = 0; i < N; ++i) {\n        for (int j = 0; j < N; ++j) {\n            if (board[i][j] == 0 || visited[i][j]) continue;\n            queue<pair<int, int>> q;\n            q.push({i, j});\n            visited[i][j] = true;\n            int comp_size = 0;\n            while (!q.empty()) {\n                auto [x, y] = q.front(); q.pop();\n                comp_size++;\n                for (int d = 0; d < 4; ++d) {\n                    int nx = x + dx[d];\n                    int ny = y + dy[d];\n                    if (nx >= 0 && nx < N && ny >= 0 && ny < N && !visited[nx][ny] && board[nx][ny] != 0) {\n                        if (are_connected(board[x][y], board[nx][ny], d)) {\n                            visited[nx][ny] = true;\n                            q.push({nx, ny});\n                        }\n                    }\n                }\n            }\n            max_comp = max(max_comp, comp_size);\n        }\n    }\n    return max_comp;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(0));\n\n    int N, T;\n    cin >> N >> T;\n    vector<vector<int>> initial_board(N, vector<int>(N));\n    int empty_x = -1, empty_y = -1;\n\n    for (int i = 0; i < N; ++i) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; ++j) {\n            char c = s[j];\n            if (c == '0') {\n                initial_board[i][j] = 0;\n                empty_x = i;\n                empty_y = j;\n            } else {\n                if (c >= '0' && c <= '9') {\n                    initial_board[i][j] = c - '0';\n                } else {\n                    initial_board[i][j] = 10 + (c - 'a');\n                }\n            }\n        }\n    }\n\n    vector<State> best_states;\n    int num_iterations = 2;\n    double gamma = 1.0;\n\n    for (int iter = 0; iter < num_iterations; ++iter) {\n        State current;\n        current.board = initial_board;\n        current.empty_x = empty_x;\n        current.empty_y = empty_y;\n        current.last_move = -1;\n        current.connections = count_connections_full(current.board, N);\n        current.max_component = compute_components(current.board, N);\n        current.moves = \"\";\n\n        for (int step = 0; step < T; ++step) {\n            if (step % 10 == 0) {\n                current.max_component = compute_components(current.board, N);\n                if (current.max_component == N * N - 1) {\n                    break;\n                }\n            }\n\n            int best_delta = -1000000;\n            int best_move = -1;\n            int best_new_connections = -1;\n\n            for (int dir = 0; dir < 4; ++dir) {\n                if (dir == (current.last_move ^ 1)) continue;\n\n                int nx = current.empty_x + dx[dir];\n                int ny = current.empty_y + dy[dir];\n                if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;\n\n                int new_connections = current.connections;\n                int tile = current.board[nx][ny];\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = nx + dx[d];\n                    int y = ny + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections--;\n                        }\n                    }\n                }\n\n                for (int d = 0; d < 4; ++d) {\n                    int x = current.empty_x + dx[d];\n                    int y = current.empty_y + dy[d];\n                    if (x >= 0 && x < N && y >= 0 && y < N && current.board[x][y] != 0) {\n                        if (x == nx && y == ny) continue;\n                        if (are_connected(tile, current.board[x][y], d)) {\n                            new_connections++;\n                        }\n                    }\n                }\n\n                double delta = new_connections - current.connections;\n                delta += gamma * (current.max_component * 0.01);\n                delta += (rand() % 100) * 0.001;\n\n                if (delta > best_delta) {\n                    best_delta = delta;\n                    best_move = dir;\n                    best_new_connections = new_connections;\n                }\n            }\n\n            if (best_move == -1) break;\n\n            int nx = current.empty_x + dx[best_move];\n            int ny = current.empty_y + dy[best_move];\n            swap(current.board[current.empty_x][current.empty_y], current.board[nx][ny]);\n            current.empty_x = nx;\n            current.empty_y = ny;\n            current.connections = best_new_connections;\n            current.moves += dir_char[best_move];\n            current.last_move = best_move;\n        }\n\n        current.max_component = compute_components(current.board, N);\n        best_states.push_back(current);\n    }\n\n    sort(best_states.begin(), best_states.end(), [](const State& a, const State& b) {\n        if (a.max_component != b.max_component) {\n            return a.max_component > b.max_component;\n        }\n        return a.moves.size() < b.moves.size();\n    });\n\n    cout << best_states[0].moves << endl;\n\n    return 0;\n}","ahc012":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <numeric>\n#include <unordered_map>\n#include <set>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nusing Point = pair<long long, long long>;\nusing Line = pair<Point, Point>;\n\nconst long long RADIUS = 10000;\nconst long long RADIUS_SQ = 100000000;\n\nstruct Solution {\n    vector<Line> lines;\n    double score;\n};\n\nlong long cross(const Point& O, const Point& A, const Point& B) {\n    return (A.first - O.first) * (B.second - O.second) - (A.second - O.second) * (B.first - O.first);\n}\n\nlong long side(const Line& line, const Point& P) {\n    const Point& A = line.first;\n    const Point& B = line.second;\n    return cross(A, B, P);\n}\n\nbool is_inside_circle(const Point& p) {\n    return p.first * p.first + p.second * p.second < RADIUS_SQ;\n}\n\ndouble calculate_score(const vector<int>& a, const vector<int>& b) {\n    int total_distributed = 0;\n    int total_attendees = 0;\n    \n    for (int d = 1; d <= 10; d++) {\n        total_distributed += min(a[d-1], b[d-1]);\n        total_attendees += a[d-1];\n    }\n    \n    return 1000000.0 * total_distributed / total_attendees;\n}\n\nvector<int> count_strawberries(const vector<Point>& strawberries, const vector<Line>& lines) {\n    if (lines.empty()) {\n        return {static_cast<int>(strawberries.size())};\n    }\n    \n    unordered_map<string, int> region_counts;\n    \n    for (const auto& strawberry : strawberries) {\n        string signature;\n        bool on_line = false;\n        \n        for (const auto& line : lines) {\n            long long s = side(line, strawberry);\n            if (s == 0) {\n                on_line = true;\n                break;\n            }\n            signature += (s > 0) ? '1' : '0';\n        }\n        \n        if (!on_line) {\n            region_counts[signature]++;\n        }\n    }\n    \n    vector<int> distribution(10, 0);\n    for (const auto& [_, count] : region_counts) {\n        if (count >= 1 && count <= 10) {\n            distribution[count-1]++;\n        }\n    }\n    \n    return distribution;\n}\n\nvector<Line> generate_candidate_lines(const vector<Point>& strawberries, mt19937& rng, int num_candidates = 20) {\n    vector<Line> candidates;\n    int n = strawberries.size();\n    \n    // Random lines through two strawberries\n    for (int i = 0; i < num_candidates / 2 && i < n * n / 2; i++) {\n        int idx1 = rng() % n;\n        int idx2 = rng() % n;\n        if (idx1 != idx2) {\n            candidates.push_back({strawberries[idx1], strawberries[idx2]});\n        }\n    }\n    \n    // Random lines in random directions\n    uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n    for (int i = 0; i < num_candidates / 2; i++) {\n        Point p1 = {coord_dist(rng), coord_dist(rng)};\n        Point p2 = {coord_dist(rng), coord_dist(rng)};\n        candidates.push_back({p1, p2});\n    }\n    \n    return candidates;\n}\n\nSolution solve(int N, int K, const vector<int>& a, const vector<Point>& strawberries) {\n    mt19937 rng(12345);\n    \n    Solution best_solution;\n    best_solution.lines = {};\n    vector<int> initial_dist = count_strawberries(strawberries, {});\n    best_solution.score = calculate_score(a, initial_dist);\n    \n    vector<Line> current_lines;\n    double current_score = best_solution.score;\n    \n    int no_improve_count = 0;\n    int max_no_improve = 5; // Stop after 5 consecutive non-improving iterations\n    \n    for (int iter = 0; iter < min(K, 50); iter++) { // Limit to 50 iterations\n        vector<Line> candidates = generate_candidate_lines(strawberries, rng);\n        \n        Line best_line;\n        double best_score = current_score;\n        bool improved = false;\n        \n        for (const auto& line : candidates) {\n            vector<Line> new_lines = current_lines;\n            new_lines.push_back(line);\n            \n            vector<int> distribution = count_strawberries(strawberries, new_lines);\n            double score = calculate_score(a, distribution);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_line = line;\n                improved = true;\n            }\n        }\n        \n        if (improved) {\n            current_lines.push_back(best_line);\n            current_score = best_score;\n            no_improve_count = 0;\n            \n            if (current_score > best_solution.score) {\n                best_solution.lines = current_lines;\n                best_solution.score = current_score;\n            }\n        } else {\n            no_improve_count++;\n            if (no_improve_count >= max_no_improve) {\n                break;\n            }\n            // Add a random line anyway to continue exploring\n            uniform_int_distribution<long long> coord_dist(-1000000000, 1000000000);\n            Point p1 = {coord_dist(rng), coord_dist(rng)};\n            Point p2 = {coord_dist(rng), coord_dist(rng)};\n            current_lines.push_back({p1, p2});\n        }\n    }\n    \n    return best_solution;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, K;\n    cin >> N >> K;\n    \n    vector<int> a(10);\n    for (int i = 0; i < 10; i++) {\n        cin >> a[i];\n    }\n    \n    vector<Point> strawberries(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].first >> strawberries[i].second;\n    }\n    \n    Solution solution = solve(N, K, a, strawberries);\n    \n    cout << solution.lines.size() << \"\\n\";\n    for (const auto& line : solution.lines) {\n        cout << line.first.first << \" \" << line.first.second << \" \"\n             << line.second.first << \" \" << line.second.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <tuple>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M;\n    cin >> N >> M;\n\n    int c = (N - 1) / 2;\n\n    vector<vector<bool>> grid(N, vector<bool>(N, false));\n    vector<set<int>> col_dots(N);\n    vector<set<int>> row_dots(N);\n    set<tuple<int, int, int, int>> segments;\n\n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n    }\n\n    vector<tuple<int, int, int, int, int, int, int, int>> operations;\n\n    while (true) {\n        vector<pair<int, int>> non_dot_points;\n        for (int x = 0; x < N; x++) {\n            for (int y = 0; y < N; y++) {\n                if (!grid[x][y]) {\n                    non_dot_points.emplace_back(x, y);\n                }\n            }\n        }\n\n        if (non_dot_points.empty()) {\n            break;\n        }\n\n        sort(non_dot_points.begin(), non_dot_points.end(), \n            [c](const pair<int, int>& a, const pair<int, int>& b) {\n                int wa = (a.first - c) * (a.first - c) + (a.second - c) * (a.second - c) + 1;\n                int wb = (b.first - c) * (b.first - c) + (b.second - c) * (b.second - c) + 1;\n                return wa > wb;\n            });\n\n        tuple<int, int, int, int, int, int, int, int> best_op;\n        vector<tuple<int, int, int, int>> best_segments_list;\n        int best_weight = -1;\n        bool found = false;\n\n        for (auto [x, y] : non_dot_points) {\n            int weight = (x - c) * (x - c) + (y - c) * (y - c) + 1;\n\n            bool found_axis = false;\n            for (int x2 = 0; x2 < N; x2++) {\n                if (x2 == x) continue;\n                if (!grid[x2][y]) continue;\n\n                if (col_dots[x].size() <= col_dots[x2].size()) {\n                    for (int y2 : col_dots[x]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x2].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                } else {\n                    for (int y2 : col_dots[x2]) {\n                        if (y2 == y) continue;\n                        if (col_dots[x].count(y2)) {\n                            int x1 = min(x, x2);\n                            int x2_val = max(x, x2);\n                            int y1 = min(y, y2);\n                            int y2_val = max(y, y2);\n\n                            bool valid = true;\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y1]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int xx = x1 + 1; xx < x2_val; xx++) {\n                                if (grid[xx][y2_val]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x1][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            for (int yy = y1 + 1; yy < y2_val; yy++) {\n                                if (grid[x2_val][yy]) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            vector<tuple<int, int, int, int>> seg_list;\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y1, xx + 1, y1);\n                            }\n                            for (int xx = x1; xx < x2_val; xx++) {\n                                seg_list.emplace_back(xx, y2_val, xx + 1, y2_val);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x1, yy, x1, yy + 1);\n                            }\n                            for (int yy = y1; yy < y2_val; yy++) {\n                                seg_list.emplace_back(x2_val, yy, x2_val, yy + 1);\n                            }\n\n                            for (auto& seg : seg_list) {\n                                if (segments.count(seg)) {\n                                    valid = false;\n                                    break;\n                                }\n                            }\n                            if (!valid) continue;\n\n                            if (best_weight < weight) {\n                                best_weight = weight;\n                                best_segments_list = seg_list;\n                                best_op = make_tuple(x, y, x, y2, x2, y2, x2, y);\n                                found = true;\n                            }\n                            found_axis = true;\n                            break;\n                        }\n                    }\n                    if (found_axis) break;\n                }\n            }\n\n            bool found_diamond = false;\n            for (int role = 0; role < 4; role++) {\n                int max_a;\n                if (role == 0) {\n                    max_a = min({(N - 1 - x) / 2, (N - 1 - y), y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x + a;\n                        int cy = y;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + 2 * a - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + i;\n                            int x2 = x + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a + i;\n                            int y1 = y + a - i;\n                            int x2 = x + a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + 2 * a - i;\n                            int y1 = y - i;\n                            int x2 = x + 2 * a - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a + i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Cx, Cy, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 1) {\n                    max_a = min({x, N - 1 - x, y / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y - a;\n                        int Ax = cx - a, Ay = cy;\n                        int Cx = cx + a, Cy = cy;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y - a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - 2 * a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y - i;\n                            int x2 = x + i + 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y - a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y - a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - 2 * a + i;\n                            int x2 = x - i - 1;\n                            int y2 = y - 2 * a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y - a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Dx, Dy, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 2) {\n                    max_a = min({x / 2, y, N - 1 - y});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x - a;\n                        int cy = y;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Dx = cx, Dy = cy - a;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Dx < 0 || Dx >= N || Dy < 0 || Dy >= N || !grid[Dx][Dy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a - i][y - a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - 2 * a + i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y - i;\n                            int x2 = x - i - 1;\n                            int y2 = y - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a - i;\n                            int y1 = y - a + i;\n                            int x2 = x - a - i - 1;\n                            int y2 = y - a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - 2 * a + i;\n                            int y1 = y + i;\n                            int x2 = x - 2 * a + i + 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a - i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Bx, By, Ax, Ay, Dx, Dy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                } else if (role == 3) {\n                    max_a = min({x, N - 1 - x, (N - 1 - y) / 2});\n                    for (int a = 1; a <= max_a; a++) {\n                        int cx = x;\n                        int cy = y + a;\n                        int Ax = cx - a, Ay = cy;\n                        int Bx = cx, By = cy + a;\n                        int Cx = cx + a, Cy = cy;\n\n                        if (Ax < 0 || Ax >= N || Ay < 0 || Ay >= N || !grid[Ax][Ay]) continue;\n                        if (Bx < 0 || Bx >= N || By < 0 || By >= N || !grid[Bx][By]) continue;\n                        if (Cx < 0 || Cx >= N || Cy < 0 || Cy >= N || !grid[Cx][Cy]) continue;\n\n                        bool valid = true;\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - i][y + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x - a + i][y + a + i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + i][y + 2 * a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        for (int i = 1; i < a; i++) {\n                            if (grid[x + a - i][y + a - i]) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        vector<tuple<int, int, int, int>> seg_list;\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - i;\n                            int y1 = y + i;\n                            int x2 = x - i - 1;\n                            int y2 = y + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x - a + i;\n                            int y1 = y + a + i;\n                            int x2 = x - a + i + 1;\n                            int y2 = y + a + i + 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + i;\n                            int y1 = y + 2 * a - i;\n                            int x2 = x + i + 1;\n                            int y2 = y + 2 * a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n                        for (int i = 0; i < a; i++) {\n                            int x1 = x + a - i;\n                            int y1 = y + a - i;\n                            int x2 = x + a - i - 1;\n                            int y2 = y + a - i - 1;\n                            seg_list.emplace_back(min(x1, x2), min(y1, y2), max(x1, x2), max(y1, y2));\n                        }\n\n                        for (auto& seg : seg_list) {\n                            if (segments.count(seg)) {\n                                valid = false;\n                                break;\n                            }\n                        }\n                        if (!valid) continue;\n\n                        if (best_weight < weight) {\n                            best_weight = weight;\n                            best_segments_list = seg_list;\n                            best_op = make_tuple(x, y, Ax, Ay, Bx, By, Cx, Cy);\n                            found = true;\n                        }\n                        found_diamond = true;\n                        break;\n                    }\n                    if (found_diamond) break;\n                }\n            }\n        }\n\n        if (!found) {\n            break;\n        }\n\n        auto [x, y, x1, y1, x2, y2, x3, y3] = best_op;\n        grid[x][y] = true;\n        col_dots[x].insert(y);\n        row_dots[y].insert(x);\n        for (auto& seg : best_segments_list) {\n            segments.insert(seg);\n        }\n        operations.push_back(best_op);\n    }\n\n    cout << operations.size() << \"\\n\";\n    for (auto& op : operations) {\n        auto [x, y, x1, y1, x2, y2, x3, y3] = op;\n        cout << x << \" \" << y << \" \" << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << \" \" << x3 << \" \" << y3 << \"\\n\";\n    }\n\n    return 0;\n}","ahc015":"#include <iostream>\n#include <vector>\n#include <array>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\n#include <queue>\n#include <map>\n\nusing namespace std;\n\nstruct Grid {\n    vector<vector<int>> cells;\n    int rows, cols;\n    \n    Grid(int r = 10, int c = 10) : rows(r), cols(c), cells(r, vector<int>(c, 0)) {}\n    \n    bool is_valid(int r, int c) const {\n        return r >= 0 && r < rows && c >= 0 && c < cols;\n    }\n    \n    int get_empty_count() const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) count++;\n            }\n        }\n        return count;\n    }\n    \n    pair<int, int> get_nth_empty(int n) const {\n        int count = 0;\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] == 0) {\n                    count++;\n                    if (count == n) return {r, c};\n                }\n            }\n        }\n        return {-1, -1}; // Should not happen\n    }\n    \n    void tilt(char direction) {\n        if (direction == 'F') { // Forward (up)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = 0;\n                for (int r = 0; r < rows; ++r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'B') { // Backward (down)\n            for (int c = 0; c < cols; ++c) {\n                int write_pos = rows - 1;\n                for (int r = rows - 1; r >= 0; --r) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != r) {\n                            cells[write_pos][c] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        } else if (direction == 'L') { // Left\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = 0;\n                for (int c = 0; c < cols; ++c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos++;\n                    }\n                }\n            }\n        } else if (direction == 'R') { // Right\n            for (int r = 0; r < rows; ++r) {\n                int write_pos = cols - 1;\n                for (int c = cols - 1; c >= 0; --c) {\n                    if (cells[r][c] != 0) {\n                        if (write_pos != c) {\n                            cells[r][write_pos] = cells[r][c];\n                            cells[r][c] = 0;\n                        }\n                        write_pos--;\n                    }\n                }\n            }\n        }\n    }\n    \n    void place(int r, int c, int flavor) {\n        cells[r][c] = flavor;\n    }\n    \n    double calculate_score() const {\n        vector<bool> visited(rows * cols, false);\n        vector<int> component_sizes;\n        \n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0 && !visited[r * cols + c]) {\n                    int flavor = cells[r][c];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({r, c});\n                    visited[r * cols + c] = true;\n                    \n                    while (!q.empty()) {\n                        auto [cr, cc] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int dr = -1; dr <= 1; ++dr) {\n                            for (int dc = -1; dc <= 1; ++dc) {\n                                if (abs(dr) + abs(dc) != 1) continue;\n                                int nr = cr + dr;\n                                int nc = cc + dc;\n                                if (is_valid(nr, nc) && cells[nr][nc] == flavor && \n                                    !visited[nr * cols + nc]) {\n                                    visited[nr * cols + nc] = true;\n                                    q.push({nr, nc});\n                                }\n                            }\n                        }\n                    }\n                    \n                    component_sizes.push_back(size);\n                }\n            }\n        }\n        \n        double sum_squares = 0;\n        for (int size : component_sizes) {\n            sum_squares += size * size;\n        }\n        \n        array<int, 4> flavor_counts = {0, 0, 0, 0};\n        for (int r = 0; r < rows; ++r) {\n            for (int c = 0; c < cols; ++c) {\n                if (cells[r][c] != 0) {\n                    flavor_counts[cells[r][c]]++;\n                }\n            }\n        }\n        \n        double denominator = 0;\n        for (int i = 1; i <= 3; ++i) {\n            denominator += flavor_counts[i] * flavor_counts[i];\n        }\n        \n        return sum_squares / denominator;\n    }\n    \n    pair<int, int> get_tilted_position(int r, int c, char direction) const {\n        if (direction == 'F') { // Forward (up)\n            while (r > 0 && cells[r - 1][c] == 0) {\n                r--;\n            }\n        } else if (direction == 'B') { // Backward (down)\n            while (r < rows - 1 && cells[r + 1][c] == 0) {\n                r++;\n            }\n        } else if (direction == 'L') { // Left\n            while (c > 0 && cells[r][c - 1] == 0) {\n                c--;\n            }\n        } else if (direction == 'R') { // Right\n            while (c < cols - 1 && cells[r][c + 1] == 0) {\n                c++;\n            }\n        }\n        return {r, c};\n    }\n    \n    int count_same_flavor_neighbors(int r, int c, int flavor) const {\n        int count = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n    \n    bool would_break_cluster(int r, int c, int flavor, char direction) const {\n        // Check if tilting would disconnect this candy from its current cluster\n        int neighbors = count_same_flavor_neighbors(r, c, flavor);\n        if (neighbors <= 1) return false; // Can't break a cluster if already isolated or only one neighbor\n        \n        // Simulate the tilt and check if it disconnects the candy\n        auto [new_r, new_c] = get_tilted_position(r, c, direction);\n        if (new_r == r && new_c == c) return false; // No movement\n        \n        // After movement, check if it still has neighbors\n        int new_neighbors = 0;\n        for (int dr = -1; dr <= 1; ++dr) {\n            for (int dc = -1; dc <= 1; ++dc) {\n                if (abs(dr) + abs(dc) != 1) continue;\n                int nr = new_r + dr;\n                int nc = new_c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    // Check if this neighbor would also move to a position adjacent to the candy\n                    auto [neighbor_new_r, neighbor_new_c] = get_tilted_position(nr, nc, direction);\n                    if (abs(neighbor_new_r - new_r) + abs(neighbor_new_c - new_c) == 1) {\n                        new_neighbors++;\n                    }\n                }\n            }\n        }\n        \n        return new_neighbors == 0;\n    }\n    \n    int count_flavor_in_area(int r, int c, int flavor, int radius) const {\n        int count = 0;\n        for (int dr = -radius; dr <= radius; ++dr) {\n            for (int dc = -radius; dc <= radius; ++dc) {\n                int nr = r + dr;\n                int nc = c + dc;\n                if (is_valid(nr, nc) && cells[nr][nc] == flavor) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nclass CandyClustering {\nprivate:\n    Grid grid;\n    vector<int> flavors;\n    array<int, 4> flavor_counts = {0, 0, 0, 0};\n    vector<pair<int, int>> flavor_region_centers; // Fixed centers based on regions\n    vector<pair<int, int>> flavor_centers; // Dynamic centers of mass\n    vector<vector<int>> flavor_regions; // Which region each cell belongs to\n    \npublic:\n    CandyClustering(const vector<int>& f) : flavors(f) {\n        // Count flavors\n        for (int f : flavors) {\n            flavor_counts[f]++;\n        }\n        \n        // Initialize regions and centers\n        initialize_flavor_regions();\n        initialize_flavor_centers();\n    }\n    \n    void initialize_flavor_regions() {\n        flavor_regions.assign(grid.rows, vector<int>(grid.cols, 0));\n        \n        // Sort flavors by count (descending)\n        vector<pair<int, int>> sorted_flavors;\n        for (int i = 1; i <= 3; ++i) {\n            sorted_flavors.emplace_back(flavor_counts[i], i);\n        }\n        sort(sorted_flavors.rbegin(), sorted_flavors.rend());\n        \n        // Assign regions proportional to flavor counts\n        int total = grid.rows * grid.cols;\n        int assigned = 0;\n        \n        for (auto [count, flavor] : sorted_flavors) {\n            if (count == 0) continue;\n            \n            // Calculate how many cells this flavor should get\n            int cells_needed = round(static_cast<double>(count) / 100 * total);\n            \n            // Assign contiguous blocks\n            int rows_needed = (cells_needed + grid.cols - 1) / grid.cols;\n            \n            // Start from the top-left and assign rows\n            for (int r = assigned / grid.cols; r < grid.rows && rows_needed > 0; ++r) {\n                for (int c = 0; c < grid.cols; ++c) {\n                    if (flavor_regions[r][c] == 0) {\n                        flavor_regions[r][c] = flavor;\n                        cells_needed--;\n                        if (cells_needed <= 0) break;\n                    }\n                }\n                if (cells_needed <= 0) break;\n                rows_needed--;\n            }\n            \n            assigned += count;\n        }\n    }\n    \n    void initialize_flavor_centers() {\n        flavor_region_centers.resize(4);\n        flavor_centers.resize(4);\n        \n        // Calculate the center of each flavor's region\n        array<vector<pair<int, int>>, 4> region_positions;\n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (flavor_regions[r][c] != 0) {\n                    region_positions[flavor_regions[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!region_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : region_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_region_centers[f] = {sum_r / region_positions[f].size(), \n                                          sum_c / region_positions[f].size()};\n                flavor_centers[f] = flavor_region_centers[f];\n            }\n        }\n    }\n    \n    char decide_direction(int step, int pos) {\n        auto [r, c] = grid.get_nth_empty(pos);\n        int flavor = flavors[step - 1];\n        grid.place(r, c, flavor);\n        \n        if (step == 100) return ' ';\n        \n        // Update centers more frequently\n        if (step % 5 == 0) {\n            update_flavor_centers();\n        }\n        \n        char best_dir = 'F';\n        double best_score = -1e9;\n        \n        for (char dir : {'F', 'B', 'L', 'R'}) {\n            Grid temp_grid = grid;\n            temp_grid.tilt(dir);\n            \n            double score = calculate_direction_score(temp_grid, flavor, r, c, dir, step);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_dir = dir;\n            }\n        }\n        \n        grid.tilt(best_dir);\n        return best_dir;\n    }\n    \n    void update_flavor_centers() {\n        array<vector<pair<int, int>>, 4> flavor_positions;\n        \n        for (int r = 0; r < grid.rows; ++r) {\n            for (int c = 0; c < grid.cols; ++c) {\n                if (grid.cells[r][c] != 0) {\n                    flavor_positions[grid.cells[r][c]].emplace_back(r, c);\n                }\n            }\n        }\n        \n        for (int f = 1; f <= 3; ++f) {\n            if (!flavor_positions[f].empty()) {\n                int sum_r = 0, sum_c = 0;\n                for (auto [r, c] : flavor_positions[f]) {\n                    sum_r += r;\n                    sum_c += c;\n                }\n                flavor_centers[f] = {sum_r / flavor_positions[f].size(), \n                                     sum_c / flavor_positions[f].size()};\n            }\n        }\n    }\n    \n    double calculate_direction_score(const Grid& g, int flavor, int r, int c, char dir, int step) {\n        double score = 0;\n        \n        // Get new position after tilting\n        auto [new_r, new_c] = g.get_tilted_position(r, c, dir);\n        \n        // Distance to dynamic center (center of mass)\n        auto center = flavor_centers[flavor];\n        double distance_before = sqrt(pow(r - center.first, 2) + pow(c - center.second, 2));\n        double distance_after = sqrt(pow(new_r - center.first, 2) + pow(new_c - center.second, 2));\n        score += (distance_before - distance_after) * 15;\n        \n        // Distance to fixed region center\n        auto region_center = flavor_region_centers[flavor];\n        double region_distance_before = sqrt(pow(r - region_center.first, 2) + pow(c - region_center.second, 2));\n        double region_distance_after = sqrt(pow(new_r - region_center.first, 2) + pow(new_c - region_center.second, 2));\n        score += (region_distance_before - region_distance_after) * 5;\n        \n        // Same-flavor neighbors\n        int same_flavor_neighbors = g.count_same_flavor_neighbors(new_r, new_c, flavor);\n        score += same_flavor_neighbors * 100;\n        \n        // Density of same flavor in the area\n        int density = g.count_flavor_in_area(new_r, new_c, flavor, 2);\n        score += density * 10;\n        \n        // Penalty for isolation\n        if (same_flavor_neighbors == 0) {\n            score -= 30;\n        }\n        \n        // Penalty for breaking clusters\n        if (grid.would_break_cluster(r, c, flavor, dir)) {\n            score -= 50;\n        }\n        \n        // Stage-specific scoring\n        if (step < 30) {\n            // Early stage: prioritize moving to region\n            score += (region_distance_before - region_distance_after) * 10;\n        } else if (step < 70) {\n            // Middle stage: balance between region and clustering\n            score += (distance_before - distance_after) * 10;\n        } else {\n            // Late stage: prioritize clustering and overall score\n            double current_score = grid.calculate_score();\n            double new_score = g.calculate_score();\n            score += (new_score - current_score) * 5000;\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    vector<int> flavors(100);\n    for (int i = 0; i < 100; ++i) {\n        cin >> flavors[i];\n    }\n    \n    CandyClustering solver(flavors);\n    \n    for (int t = 1; t <= 100; ++t) {\n        int pos;\n        cin >> pos;\n        \n        char direction = solver.decide_direction(t, pos);\n        \n        if (t < 100) {\n            cout << direction << endl;\n            cout.flush();\n        }\n    }\n    \n    return 0;\n}","ahc016":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <climits>\n#include <utility>\n#include <iomanip>\n\nusing namespace std;\n\nvector<pair<int, int>> generate_clique_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int c = 2; c <= N; ++c) {\n        pairs.push_back({c, 0});\n    }\n    return pairs;\n}\n\nvector<pair<int, int>> generate_bipartite_pairs(int N) {\n    vector<pair<int, int>> pairs;\n    for (int a = 1; a <= N/2; ++a) {\n        for (int b = a; b <= N - a; ++b) {\n            pairs.push_back({a, b});\n        }\n    }\n    return pairs;\n}\n\nvector<double> get_expected_clique_degrees(int c, int N, double eps) {\n    double exp_clique = (c - 1) * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    for (int i = 0; i < N - c; ++i) {\n        deg[i] = exp_iso;\n    }\n    for (int i = N - c; i < N; ++i) {\n        deg[i] = exp_clique;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_bipartite_degrees(int a, int b, int N, double eps) {\n    double exp_a = b * (1 - 2 * eps) + eps * (N - 1);\n    double exp_b = a * (1 - 2 * eps) + eps * (N - 1);\n    double exp_iso = eps * (N - 1);\n    vector<double> deg(N);\n    int idx = 0;\n    for (int i = 0; i < N - a - b; ++i) {\n        deg[idx++] = exp_iso;\n    }\n    for (int i = 0; i < b; ++i) {\n        deg[idx++] = exp_b;\n    }\n    for (int i = 0; i < a; ++i) {\n        deg[idx++] = exp_a;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nvector<double> get_expected_star_degrees(int N, double eps) {\n    double exp_center = (N - 1) * (1 - eps);\n    double exp_leaf = 1 + (N - 2) * eps;\n    vector<double> deg(N);\n    deg[0] = exp_center;\n    for (int i = 1; i < N; ++i) {\n        deg[i] = exp_leaf;\n    }\n    sort(deg.begin(), deg.end());\n    return deg;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int M;\n    double eps;\n    cin >> M >> eps;\n\n    int N = 4;\n    while (true) {\n        int num_cliques = max(0, N - 1);\n        int num_bipartite = (N / 2) * ((N + 1) / 2);\n        int num_graphs = num_cliques + num_bipartite;\n        if (num_graphs >= M) {\n            break;\n        }\n        N++;\n        if (N > 100) {\n            N = 100;\n            break;\n        }\n    }\n\n    vector<pair<int, int>> clique_pairs = generate_clique_pairs(N);\n    vector<pair<int, int>> bipartite_pairs = generate_bipartite_pairs(N);\n\n    vector<pair<int, int>> candidate_pairs;\n    candidate_pairs.insert(candidate_pairs.end(), clique_pairs.begin(), clique_pairs.end());\n    candidate_pairs.insert(candidate_pairs.end(), bipartite_pairs.begin(), bipartite_pairs.end());\n\n    vector<vector<double>> candidate_expected;\n    for (auto& p : candidate_pairs) {\n        if (p.second == 0) {\n            candidate_expected.push_back(get_expected_clique_degrees(p.first, N, eps));\n        } else {\n            candidate_expected.push_back(get_expected_bipartite_degrees(p.first, p.second, N, eps));\n        }\n    }\n\n    vector<int> selected_indices;\n    if (M > 0) {\n        selected_indices.push_back(0);\n    }\n\n    for (int i = 1; i < M; ++i) {\n        double max_min_dist_sq = -1.0;\n        int best_index = -1;\n\n        for (int idx = 0; idx < candidate_expected.size(); ++idx) {\n            if (find(selected_indices.begin(), selected_indices.end(), idx) != selected_indices.end()) {\n                continue;\n            }\n\n            double min_dist_sq = numeric_limits<double>::max();\n            for (int sel : selected_indices) {\n                double dist_sq = 0.0;\n                for (int j = 0; j < N; ++j) {\n                    double diff = candidate_expected[idx][j] - candidate_expected[sel][j];\n                    dist_sq += diff * diff;\n                }\n                if (dist_sq < min_dist_sq) {\n                    min_dist_sq = dist_sq;\n                }\n            }\n\n            if (min_dist_sq > max_min_dist_sq) {\n                max_min_dist_sq = min_dist_sq;\n                best_index = idx;\n            }\n        }\n\n        if (best_index != -1) {\n            selected_indices.push_back(best_index);\n        }\n    }\n\n    cout << N << endl;\n    for (int idx : selected_indices) {\n        auto p = candidate_pairs[idx];\n        string s;\n        s.reserve(N * (N - 1) / 2);\n        if (p.second == 0) {\n            int c = p.first;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if (i < c && j < c) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        } else {\n            int a = p.first;\n            int b = p.second;\n            for (int i = 0; i < N; ++i) {\n                for (int j = i + 1; j < N; ++j) {\n                    if ((i < a && j >= a && j < a + b) || (j < a && i >= a && i < a + b)) {\n                        s += '1';\n                    } else {\n                        s += '0';\n                    }\n                }\n            }\n        }\n        cout << s << endl;\n    }\n    cout.flush();\n\n    vector<vector<double>> selected_expected;\n    for (int idx : selected_indices) {\n        selected_expected.push_back(candidate_expected[idx]);\n    }\n\n    for (int q = 0; q < 100; ++q) {\n        string H;\n        cin >> H;\n\n        vector<int> deg(N, 0);\n        int idx = 0;\n        for (int i = 0; i < N; ++i) {\n            for (int j = i + 1; j < N; ++j) {\n                if (H[idx] == '1') {\n                    deg[i]++;\n                    deg[j]++;\n                }\n                idx++;\n            }\n        }\n\n        sort(deg.begin(), deg.end());\n\n        int best_index = -1;\n        double best_dist_sq = numeric_limits<double>::max();\n\n        for (int t = 0; t < M; ++t) {\n            double dist_sq = 0.0;\n            for (int i = 0; i < N; ++i) {\n                double diff = deg[i] - selected_expected[t][i];\n                dist_sq += diff * diff;\n            }\n            if (dist_sq < best_dist_sq) {\n                best_dist_sq = dist_sq;\n                best_index = t;\n            }\n        }\n\n        cout << best_index << endl;\n        cout.flush();\n    }\n\n    return 0;\n}","ahc017":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <iomanip>\n#include <random>\n#include <chrono>\n#include <unordered_map>\n#include <numeric>\n#include <stack>\n\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int index;\n};\n\nusing ll = long long;\n\nll compute_alt(int u, int v, const Edge& e, const vector<vector<pair<int, int>>>& adj) {\n    int n = adj.size();\n    vector<ll> dist(n, LLONG_MAX);\n    dist[u] = 0;\n    priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n    pq.push({0, u});\n\n    while (!pq.empty()) {\n        auto [d, node] = pq.top();\n        pq.pop();\n        if (d != dist[node]) continue;\n        if (node == v) return d;\n        for (auto [neighbor, weight] : adj[node]) {\n            if ((node == e.u && neighbor == e.v) || (node == e.v && neighbor == e.u)) {\n                continue;\n            }\n            ll new_dist = d + weight;\n            if (new_dist < dist[neighbor]) {\n                dist[neighbor] = new_dist;\n                pq.push({new_dist, neighbor});\n            }\n        }\n    }\n    return dist[v];\n}\n\nvector<double> compute_betweenness(const vector<vector<pair<int, int>>>& adj, int N) {\n    vector<double> betweenness(N, 0.0);\n    vector<vector<int>> predecessors(N);\n    vector<ll> dist(N);\n    vector<int> count(N);\n    vector<double> dependency(N, 0.0);\n    \n    for (int s = 0; s < N; s++) {\n        // Initialize\n        fill(predecessors.begin(), predecessors.end(), vector<int>());\n        fill(dist.begin(), dist.end(), LLONG_MAX);\n        fill(count.begin(), count.end(), 0);\n        fill(dependency.begin(), dependency.end(), 0.0);\n        \n        stack<int> stk;\n        queue<int> q;\n        \n        dist[s] = 0;\n        count[s] = 1;\n        q.push(s);\n        \n        while (!q.empty()) {\n            int v = q.front();\n            q.pop();\n            stk.push(v);\n            \n            for (auto [w, weight] : adj[v]) {\n                if (dist[w] > dist[v] + weight) {\n                    dist[w] = dist[v] + weight;\n                    predecessors[w].clear();\n                    predecessors[w].push_back(v);\n                    count[w] = count[v];\n                    q.push(w);\n                } else if (dist[w] == dist[v] + weight) {\n                    predecessors[w].push_back(v);\n                    count[w] += count[v];\n                }\n            }\n        }\n        \n        while (!stk.empty()) {\n            int w = stk.top();\n            stk.pop();\n            for (int v : predecessors[w]) {\n                double partial = (double)count[v] / count[w] * (1.0 + dependency[w]);\n                dependency[v] += partial;\n            }\n            if (w != s) {\n                betweenness[w] += dependency[w];\n            }\n        }\n    }\n    \n    // Normalize betweenness for undirected graph\n    for (int i = 0; i < N; i++) {\n        betweenness[i] /= 2.0;\n    }\n    \n    return betweenness;\n}\n\ndouble estimate_frustration(const vector<vector<pair<int, int>>>& adj, \n                           const vector<Edge>& edges,\n                           const vector<int>& day_edges,\n                           int N, int sample_size = 50) {\n    if (day_edges.empty()) return 0.0;\n    \n    // Create graph without the edges in day_edges\n    vector<vector<pair<int, int>>> temp_adj = adj;\n    for (int e_idx : day_edges) {\n        const Edge& e = edges[e_idx];\n        // Remove edge from adjacency list\n        auto it1 = find_if(temp_adj[e.u].begin(), temp_adj[e.u].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.v; });\n        if (it1 != temp_adj[e.u].end()) temp_adj[e.u].erase(it1);\n        \n        auto it2 = find_if(temp_adj[e.v].begin(), temp_adj[e.v].end(), \n                          [e](const pair<int, int>& p) { return p.first == e.u; });\n        if (it2 != temp_adj[e.v].end()) temp_adj[e.v].erase(it2);\n    }\n    \n    double total_increase = 0.0;\n    int samples = 0;\n    \n    // Sample vertices to estimate frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    uniform_int_distribution<int> dist(0, N-1);\n    \n    for (int i = 0; i < sample_size; i++) {\n        int s = dist(rng);\n        vector<ll> dist_s(N, LLONG_MAX);\n        dist_s[s] = 0;\n        priority_queue<pair<ll, int>, vector<pair<ll, int>>, greater<pair<ll, int>>> pq;\n        pq.push({0, s});\n        \n        while (!pq.empty()) {\n            auto [d, node] = pq.top();\n            pq.pop();\n            if (d != dist_s[node]) continue;\n            for (auto [neighbor, weight] : temp_adj[node]) {\n                ll new_dist = d + weight;\n                if (new_dist < dist_s[neighbor]) {\n                    dist_s[neighbor] = new_dist;\n                    pq.push({new_dist, neighbor});\n                }\n            }\n        }\n        \n        // For now, we'll use a simplified frustration calculation\n        // In a real implementation, we would compare with original distances\n        for (int j = 0; j < N; j++) {\n            if (s == j) continue;\n            if (dist_s[j] == LLONG_MAX) {\n                total_increase += 1000000000; // Disconnected penalty\n            } else {\n                total_increase += max(0LL, dist_s[j] - 1000); // Placeholder\n            }\n            samples++;\n        }\n    }\n    \n    return total_increase / max(1, samples);\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, D, K;\n    cin >> N >> M >> D >> K;\n\n    vector<Edge> edges(M);\n    vector<vector<pair<int, int>>> adj(N);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].index = i;\n        adj[edges[i].u].push_back({edges[i].v, edges[i].w});\n        adj[edges[i].v].push_back({edges[i].u, edges[i].w});\n    }\n\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n\n    // Precompute original distances (simplified for performance)\n    vector<vector<ll>> original_dist(N, vector<ll>(N, 1000)); // Placeholder\n\n    // Compute vertex betweenness centrality\n    vector<double> vertex_betweenness = compute_betweenness(adj, N);\n\n    // Enhanced criticality calculation\n    vector<double> criticality(M, 0.0);\n    for (int idx = 0; idx < M; idx++) {\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        int w = e.w;\n        \n        // Distance increase component\n        ll alt_dist = compute_alt(u, v, e, adj);\n        if (alt_dist == LLONG_MAX) {\n            alt_dist = 1000000000;\n        }\n        ll increase = alt_dist - w;\n        if (increase < 0) increase = 0;\n        \n        // Betweenness component\n        double betweenness_component = vertex_betweenness[u] + vertex_betweenness[v];\n        \n        // Connectivity penalty\n        int degree_u = adj[u].size();\n        int degree_v = adj[v].size();\n        double connectivity_penalty = 1.0 / min(degree_u, degree_v);\n        \n        // Combined criticality\n        criticality[idx] = (double)increase * (1.0 + betweenness_component) + \n                          connectivity_penalty * 1000000.0;\n    }\n\n    // Initial assignment using enhanced criticality\n    vector<int> edge_indices(M);\n    for (int i = 0; i < M; i++) {\n        edge_indices[i] = i;\n    }\n\n    sort(edge_indices.begin(), edge_indices.end(), [&](int a, int b) {\n        return criticality[a] > criticality[b];\n    });\n\n    double max_crit = *max_element(criticality.begin(), criticality.end());\n\n    vector<int> assignment(M, -1);\n    vector<double> day_criticality(D, 0.0);\n    vector<int> day_count(D, 0);\n    vector<vector<int>> vertex_day_count(N, vector<int>(D, 0));\n\n    // Phase 1: Initial assignment\n    for (int i = 0; i < M; i++) {\n        int idx = edge_indices[i];\n        Edge e = edges[idx];\n        int u = e.u;\n        int v = e.v;\n        double min_cost = 1e20;\n        int best_day = -1;\n        for (int d = 0; d < D; d++) {\n            if (day_count[d] >= K) continue;\n            int conflict_count = vertex_day_count[u][d] + vertex_day_count[v][d];\n            double norm_crit = (max_crit > 0) ? (criticality[idx] / max_crit) : 0.0;\n            double cost = conflict_count + 10.0 * norm_crit;\n            if (cost < min_cost) {\n                min_cost = cost;\n                best_day = d;\n            }\n        }\n        assignment[idx] = best_day;\n        day_criticality[best_day] += criticality[idx];\n        day_count[best_day]++;\n        vertex_day_count[u][best_day]++;\n        vertex_day_count[v][best_day]++;\n    }\n\n    // Phase 2: Local search to balance frustration\n    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n    int num_iterations = 5000;\n    \n    for (int iter = 0; iter < num_iterations; iter++) {\n        // Select a random day\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        \n        // Get edges in this day\n        vector<int> edges_in_d1;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) {\n                edges_in_d1.push_back(i);\n            }\n        }\n        if (edges_in_d1.empty()) continue;\n        \n        // Select a random edge from this day\n        uniform_int_distribution<int> dist_edge(0, (int)edges_in_d1.size()-1);\n        int e_idx = edges_in_d1[dist_edge(rng)];\n        \n        // Find candidate days to move to\n        vector<int> candidate_days;\n        for (int d2 = 0; d2 < D; d2++) {\n            if (d2 == d1) continue;\n            if (day_count[d2] >= K) continue;\n            candidate_days.push_back(d2);\n        }\n        if (candidate_days.empty()) continue;\n        \n        // Try each candidate day\n        double best_delta = 1e20;\n        int best_d2 = -1;\n        \n        for (int d2 : candidate_days) {\n            // Estimate frustration change\n            double delta = day_criticality[d1] + day_criticality[d2];\n            double new_d1 = day_criticality[d1] - criticality[e_idx];\n            double new_d2 = day_criticality[d2] + criticality[e_idx];\n            delta -= (new_d1 + new_d2);\n            \n            if (delta < best_delta) {\n                best_delta = delta;\n                best_d2 = d2;\n            }\n        }\n        \n        if (best_delta < 0) {\n            // Make the move\n            assignment[e_idx] = best_d2;\n            day_criticality[d1] -= criticality[e_idx];\n            day_criticality[best_d2] += criticality[e_idx];\n            day_count[d1]--;\n            day_count[best_d2]++;\n            vertex_day_count[edges[e_idx].u][d1]--;\n            vertex_day_count[edges[e_idx].v][d1]--;\n            vertex_day_count[edges[e_idx].u][best_d2]++;\n            vertex_day_count[edges[e_idx].v][best_d2]++;\n        }\n    }\n\n    // Phase 3: Simulated annealing for further optimization\n    double temperature = 1000.0;\n    double cooling_rate = 0.99;\n    int sa_iterations = 2000;\n    \n    double current_cost = 0.0;\n    for (int d = 0; d < D; d++) {\n        current_cost += day_criticality[d] * day_criticality[d];\n    }\n    \n    for (int iter = 0; iter < sa_iterations; iter++) {\n        temperature *= cooling_rate;\n        \n        // Select two random days\n        uniform_int_distribution<int> dist_day(0, D-1);\n        int d1 = dist_day(rng);\n        int d2 = dist_day(rng);\n        if (d1 == d2) continue;\n        \n        // Select random edges from each day\n        vector<int> edges_d1, edges_d2;\n        for (int i = 0; i < M; i++) {\n            if (assignment[i] == d1) edges_d1.push_back(i);\n            if (assignment[i] == d2) edges_d2.push_back(i);\n        }\n        \n        if (edges_d1.empty() || edges_d2.empty()) continue;\n        \n        uniform_int_distribution<int> dist_e1(0, (int)edges_d1.size()-1);\n        uniform_int_distribution<int> dist_e2(0, (int)edges_d2.size()-1);\n        int e1 = edges_d1[dist_e1(rng)];\n        int e2 = edges_d2[dist_e2(rng)];\n        \n        // Compute cost change for swapping\n        double old_cost = day_criticality[d1] * day_criticality[d1] + \n                         day_criticality[d2] * day_criticality[d2];\n        \n        double new_d1 = day_criticality[d1] - criticality[e1] + criticality[e2];\n        double new_d2 = day_criticality[d2] - criticality[e2] + criticality[e1];\n        double new_cost = new_d1 * new_d1 + new_d2 * new_d2;\n        \n        double delta = new_cost - old_cost;\n        \n        // Accept with probability based on temperature\n        if (delta < 0 || exp(-delta / temperature) > (double)rng() / rng.max()) {\n            // Make the swap\n            assignment[e1] = d2;\n            assignment[e2] = d1;\n            day_criticality[d1] = new_d1;\n            day_criticality[d2] = new_d2;\n            \n            // Update vertex counts\n            vertex_day_count[edges[e1].u][d1]--;\n            vertex_day_count[edges[e1].v][d1]--;\n            vertex_day_count[edges[e1].u][d2]++;\n            vertex_day_count[edges[e1].v][d2]++;\n            \n            vertex_day_count[edges[e2].u][d2]--;\n            vertex_day_count[edges[e2].v][d2]--;\n            vertex_day_count[edges[e2].u][d1]++;\n            vertex_day_count[edges[e2].v][d1]++;\n            \n            current_cost += delta;\n        }\n    }\n\n    for (int i = 0; i < M; i++) {\n        cout << assignment[i] + 1;\n        if (i < M - 1) {\n            cout << \" \";\n        } else {\n            cout << endl;\n        }\n    }\n\n    return 0;\n}","ahc019":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <tuple>\n#include <set>\n#include <map>\n#include <cstring>\n\nusing namespace std;\n\nconst int dx[6] = {1, 0, 0, -1, 0, 0};\nconst int dy[6] = {0, 1, 0, 0, -1, 0};\nconst int dz[6] = {0, 0, 1, 0, 0, -1};\n\nusing Point = tuple<int, int, int>;\n\nvector<set<Point>> get_connected_components_from_set(const set<Point>& points) {\n    set<Point> visited;\n    vector<set<Point>> components;\n    for (const auto& p : points) {\n        if (visited.find(p) == visited.end()) {\n            set<Point> comp;\n            queue<Point> q;\n            q.push(p);\n            visited.insert(p);\n            while (!q.empty()) {\n                auto [x, y, z] = q.front(); q.pop();\n                comp.insert({x, y, z});\n                for (int dir = 0; dir < 6; dir++) {\n                    int nx = x + dx[dir], ny = y + dy[dir], nz = z + dz[dir];\n                    Point np = {nx, ny, nz};\n                    if (points.find(np) != points.end() && visited.find(np) == visited.end()) {\n                        visited.insert(np);\n                        q.push(np);\n                    }\n                }\n            }\n            components.push_back(comp);\n        }\n    }\n    return components;\n}\n\nvector<set<Point>> get_connected_components_from_grid(const vector<vector<vector<bool>>>& grid, int D) {\n    vector<vector<vector<bool>>> visited(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<set<Point>> components;\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (grid[z][x][y] && !visited[z][x][y]) {\n                    set<Point> comp;\n                    queue<Point> q;\n                    q.push({x, y, z});\n                    visited[z][x][y] = true;\n                    while (!q.empty()) {\n                        auto [cx, cy, cz] = q.front(); q.pop();\n                        comp.insert({cx, cy, cz});\n                        for (int dir = 0; dir < 6; dir++) {\n                            int nx = cx + dx[dir], ny = cy + dy[dir], nz = cz + dz[dir];\n                            if (nx < 0 || nx >= D || ny < 0 || ny >= D || nz < 0 || nz >= D) \n                                continue;\n                            if (grid[nz][nx][ny] && !visited[nz][nx][ny]) {\n                                visited[nz][nx][ny] = true;\n                                q.push({nx, ny, nz});\n                            }\n                        }\n                    }\n                    components.push_back(comp);\n                }\n            }\n        }\n    }\n    return components;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int D;\n    cin >> D;\n\n    vector<string> f1(D), r1(D), f2(D), r2(D);\n    for (int i = 0; i < D; i++) cin >> f1[i];\n    for (int i = 0; i < D; i++) cin >> r1[i];\n    for (int i = 0; i < D; i++) cin >> f2[i];\n    for (int i = 0; i < D; i++) cin >> r2[i];\n\n    vector<vector<vector<bool>>> cand1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> cand2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> Common(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n\n    for (int z = 0; z < D; z++) {\n        for (int x = 0; x < D; x++) {\n            for (int y = 0; y < D; y++) {\n                if (f1[z][x] == '1' && r1[z][y] == '1') {\n                    cand1[z][x][y] = true;\n                }\n                if (f2[z][x] == '1' && r2[z][y] == '1') {\n                    cand2[z][x][y] = true;\n                }\n                if (cand1[z][x][y] && cand2[z][x][y]) {\n                    Common[z][x][y] = true;\n                }\n            }\n        }\n    }\n\n    auto process_object = [&](const vector<string>& f, const vector<string>& r, \n                              const vector<vector<vector<bool>>>& cand, \n                              const vector<vector<vector<bool>>>& common) {\n        set<Point> additional_set;\n        vector<vector<bool>> covered_front(D, vector<bool>(D, false));\n        vector<vector<bool>> covered_right(D, vector<bool>(D, false));\n\n        // Mark requirements covered by common cells\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                for (int y = 0; y < D; y++) {\n                    if (common[z][x][y]) {\n                        covered_front[z][x] = true;\n                        covered_right[z][y] = true;\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered front requirements\n        for (int z = 0; z < D; z++) {\n            for (int x = 0; x < D; x++) {\n                if (f[z][x] == '1' && !covered_front[z][x]) {\n                    bool found = false;\n                    for (int y = 0; y < D; y++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int y = 0; y < D; y++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Cover uncovered right requirements\n        for (int z = 0; z < D; z++) {\n            for (int y = 0; y < D; y++) {\n                if (r[z][y] == '1' && !covered_right[z][y]) {\n                    bool found = false;\n                    for (int x = 0; x < D; x++) {\n                        if (cand[z][x][y] && !common[z][x][y]) {\n                            additional_set.insert({x, y, z});\n                            covered_front[z][x] = true;\n                            covered_right[z][y] = true;\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        // Fallback: try any candidate cell (should not happen per problem statement)\n                        for (int x = 0; x < D; x++) {\n                            if (cand[z][x][y]) {\n                                additional_set.insert({x, y, z});\n                                covered_front[z][x] = true;\n                                covered_right[z][y] = true;\n                                found = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        return additional_set;\n    };\n\n    set<Point> A1_set = process_object(f1, r1, cand1, Common);\n    set<Point> B1_set = process_object(f2, r2, cand2, Common);\n\n    auto common_components = get_connected_components_from_grid(Common, D);\n    auto a1_components = get_connected_components_from_set(A1_set);\n    auto b1_components = get_connected_components_from_set(B1_set);\n\n    int n = common_components.size() + a1_components.size() + b1_components.size();\n    vector<int> arr1(D*D*D, 0);\n    vector<int> arr2(D*D*D, 0);\n\n    int block_id = 1;\n    for (const auto& comp : common_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : a1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr1[index] = block_id;\n        }\n        block_id++;\n    }\n\n    for (const auto& comp : b1_components) {\n        for (const auto& p : comp) {\n            auto [x, y, z] = p;\n            int index = x * D*D + y * D + z;\n            arr2[index] = block_id;\n        }\n        block_id++;\n    }\n\n    cout << n << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr1[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n    for (int i = 0; i < D*D*D; i++) {\n        cout << arr2[i] << (i < D*D*D-1 ? \" \" : \"\");\n    }\n    cout << \"\\n\";\n\n    return 0;\n}","ahc020":"#include <iostream>\n#include <vector>\n#include <cmath>\n#include <algorithm>\n#include <random>\n#include <queue>\n#include <unordered_set>\n#include <chrono>\n#include <iomanip>\n#include <limits>\n\nusing namespace std;\nusing ll = long long;\n\nstruct Point {\n    ll x, y;\n    \n    Point() : x(0), y(0) {}\n    Point(ll x, ll y) : x(x), y(y) {}\n    \n    ll dist2(const Point& other) const {\n        ll dx = x - other.x;\n        ll dy = y - other.y;\n        return dx * dx + dy * dy;\n    }\n    \n    double dist(const Point& other) const {\n        return sqrt(dist2(other));\n    }\n};\n\nstruct Edge {\n    int u, v;\n    ll w;\n    int idx;\n    \n    Edge(int u, int v, ll w, int idx) : u(u), v(v), w(w), idx(idx) {}\n    \n    bool operator<(const Edge& other) const {\n        return w < other.w;\n    }\n};\n\nstruct Solution {\n    vector<int> P;\n    vector<int> B;\n    ll cost;\n    int covered;\n    \n    Solution(int N, int M) : P(N, 0), B(M, 0), cost(0), covered(0) {}\n};\n\nclass TVNetworkOptimizer {\nprivate:\n    int N, M, K;\n    vector<Point> stations;\n    vector<Point> residents;\n    vector<Edge> edges;\n    vector<vector<pair<int, ll>>> adj; // adjacency list\n    \n    // Random number generation\n    mt19937 rng;\n    \n    // Best solution found\n    Solution best_solution;\n    \n    // Distance matrices\n    vector<vector<double>> station_to_resident_dist;\n    vector<vector<double>> station_to_station_dist;\n    \npublic:\n    TVNetworkOptimizer() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void read_input() {\n        cin >> N >> M >> K;\n        \n        stations.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> stations[i].x >> stations[i].y;\n        }\n        \n        edges.reserve(M);\n        adj.resize(N);\n        for (int i = 0; i < M; i++) {\n            int u, v;\n            ll w;\n            cin >> u >> v >> w;\n            u--; v--;\n            edges.emplace_back(u, v, w, i);\n            adj[u].emplace_back(v, w);\n            adj[v].emplace_back(u, w);\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].x >> residents[i].y;\n        }\n        \n        // Precompute distances\n        compute_distances();\n    }\n    \n    void compute_distances() {\n        station_to_resident_dist.resize(N, vector<double>(K));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < K; j++) {\n                station_to_resident_dist[i][j] = stations[i].dist(residents[j]);\n            }\n        }\n        \n        station_to_station_dist.resize(N, vector<double>(N));\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                station_to_station_dist[i][j] = stations[i].dist(stations[j]);\n            }\n        }\n    }\n    \n    // Build initial MST solution\n    Solution build_mst_solution() {\n        Solution sol(N, M);\n        \n        // Prim's algorithm for MST\n        vector<bool> in_mst(N, false);\n        vector<ll> min_edge(N, numeric_limits<ll>::max());\n        vector<int> parent(N, -1);\n        \n        min_edge[0] = 0;\n        \n        for (int i = 0; i < N; i++) {\n            int u = -1;\n            for (int v = 0; v < N; v++) {\n                if (!in_mst[v] && (u == -1 || min_edge[v] < min_edge[u])) {\n                    u = v;\n                }\n            }\n            \n            if (min_edge[u] == numeric_limits<ll>::max()) break;\n            \n            in_mst[u] = true;\n            \n            if (parent[u] != -1) {\n                // Find the edge between u and parent[u]\n                for (const auto& edge : edges) {\n                    if ((edge.u == u && edge.v == parent[u]) || \n                        (edge.u == parent[u] && edge.v == u)) {\n                        sol.B[edge.idx] = 1;\n                        sol.cost += edge.w;\n                        break;\n                    }\n                }\n            }\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!in_mst[v] && w < min_edge[v]) {\n                    min_edge[v] = w;\n                    parent[v] = u;\n                }\n            }\n        }\n        \n        // Assign powers to cover residents\n        assign_powers(sol);\n        \n        return sol;\n    }\n    \n    // Assign powers to vertices to cover residents\n    void assign_powers(Solution& sol) {\n        vector<bool> covered(K, false);\n        sol.covered = 0;\n        \n        // First, find which vertices are reachable from vertex 1\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find the closest reachable station\n        vector<vector<int>> assignments(N);\n        for (int k = 0; k < K; k++) {\n            double min_dist = numeric_limits<double>::max();\n            int best_station = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (reachable[i] && station_to_resident_dist[i][k] < min_dist) {\n                    min_dist = station_to_resident_dist[i][k];\n                    best_station = i;\n                }\n            }\n            \n            if (best_station != -1) {\n                assignments[best_station].push_back(k);\n            }\n        }\n        \n        // Calculate power for each station\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            if (!assignments[i].empty()) {\n                double max_dist = 0;\n                for (int k : assignments[i]) {\n                    max_dist = max(max_dist, station_to_resident_dist[i][k]);\n                }\n                sol.P[i] = min(5000, static_cast<int>(ceil(max_dist)));\n                power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n                \n                for (int k : assignments[i]) {\n                    if (!covered[k]) {\n                        covered[k] = true;\n                        sol.covered++;\n                    }\n                }\n            } else {\n                sol.P[i] = 0;\n            }\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    // Find vertices reachable from vertex 1\n    vector<bool> find_reachable(const vector<int>& B) {\n        vector<bool> reachable(N, false);\n        queue<int> q;\n        q.push(0);\n        reachable[0] = true;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!reachable[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                reachable[v] = true;\n                                q.push(v);\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return reachable;\n    }\n    \n    // Calculate total edge cost\n    ll get_edge_cost(const vector<int>& B) {\n        ll cost = 0;\n        for (int i = 0; i < M; i++) {\n            if (B[i]) {\n                cost += edges[i].w;\n            }\n        }\n        return cost;\n    }\n    \n    // Try to improve solution by adding/removing edges\n    Solution local_search(const Solution& initial_sol) {\n        Solution best_sol = initial_sol;\n        Solution current_sol = initial_sol;\n        \n        uniform_int_distribution<int> edge_dist(0, M-1);\n        uniform_real_distribution<double> prob_dist(0.0, 1.0);\n        \n        double temperature = 1000.0;\n        double cooling_rate = 0.995;\n        int iterations = 10000;\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            // Try random edge operation\n            int edge_idx = edge_dist(rng);\n            Solution new_sol = current_sol;\n            \n            if (new_sol.B[edge_idx] == 1) {\n                // Try removing edge\n                new_sol.B[edge_idx] = 0;\n                if (is_connected(new_sol.B)) {\n                    assign_powers(new_sol);\n                } else {\n                    new_sol.B[edge_idx] = 1; // Revert if disconnected\n                }\n            } else {\n                // Try adding edge\n                new_sol.B[edge_idx] = 1;\n                assign_powers(new_sol);\n            }\n            \n            // Accept or reject based on simulated annealing\n            if (accept_solution(current_sol, new_sol, temperature)) {\n                current_sol = new_sol;\n                if (current_sol.covered == K && \n                    (best_sol.covered < K || current_sol.cost < best_sol.cost)) {\n                    best_sol = current_sol;\n                }\n            }\n            \n            temperature *= cooling_rate;\n        }\n        \n        return best_sol;\n    }\n    \n    // Check if the graph with selected edges is connected\n    bool is_connected(const vector<int>& B) {\n        vector<bool> visited(N, false);\n        queue<int> q;\n        q.push(0);\n        visited[0] = true;\n        int count = 1;\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            for (const auto& [v, w] : adj[u]) {\n                if (!visited[v]) {\n                    // Check if edge is active\n                    for (const auto& edge : edges) {\n                        if ((edge.u == u && edge.v == v) || \n                            (edge.u == v && edge.v == u)) {\n                            if (B[edge.idx]) {\n                                visited[v] = true;\n                                q.push(v);\n                                count++;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        return count == N;\n    }\n    \n    // Simulated annealing acceptance criterion\n    bool accept_solution(const Solution& current, const Solution& new_sol, double temperature) {\n        if (new_sol.covered > current.covered) return true;\n        if (new_sol.covered < current.covered) return false;\n        \n        if (new_sol.cost < current.cost) return true;\n        \n        if (temperature < 1e-6) return false;\n        \n        double delta = new_sol.cost - current.cost;\n        double prob = exp(-delta / temperature);\n        \n        uniform_real_distribution<double> dist(0.0, 1.0);\n        return dist(rng) < prob;\n    }\n    \n    // Optimize power assignments given fixed network\n    void optimize_powers(Solution& sol) {\n        vector<bool> reachable = find_reachable(sol.B);\n        \n        // For each resident, find all stations that can cover it\n        vector<vector<int>> covering_stations(K);\n        for (int k = 0; k < K; k++) {\n            for (int i = 0; i < N; i++) {\n                if (reachable[i]) {\n                    double dist = station_to_resident_dist[i][k];\n                    if (dist <= 5000) {\n                        covering_stations[k].push_back(i);\n                    }\n                }\n            }\n        }\n        \n        // Greedily assign residents to minimize total power cost\n        vector<bool> covered(K, false);\n        vector<int> assignments(K, -1);\n        sol.covered = 0;\n        \n        // Sort residents by number of covering stations (ascending)\n        vector<int> resident_order(K);\n        for (int k = 0; k < K; k++) resident_order[k] = k;\n        sort(resident_order.begin(), resident_order.end(), \n             [&](int a, int b) { \n                 return covering_stations[a].size() < covering_stations[b].size(); \n             });\n        \n        for (int k : resident_order) {\n            if (covered[k]) continue;\n            \n            // Find best station for this resident\n            int best_station = -1;\n            double best_cost = numeric_limits<double>::max();\n            \n            for (int station : covering_stations[k]) {\n                double dist = station_to_resident_dist[station][k];\n                double additional_cost = dist * dist;\n                \n                // Check how many additional residents this station would cover\n                int additional_cover = 0;\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && station_to_resident_dist[station][other] <= dist) {\n                        additional_cover++;\n                    }\n                }\n                \n                double cost_per_resident = additional_cost / max(1, additional_cover);\n                \n                if (cost_per_resident < best_cost) {\n                    best_cost = cost_per_resident;\n                    best_station = station;\n                }\n            }\n            \n            if (best_station != -1) {\n                double required_power = station_to_resident_dist[best_station][k];\n                \n                // Assign this resident and others that can be covered\n                for (int other : covering_stations[k]) {\n                    if (!covered[other] && \n                        station_to_resident_dist[best_station][other] <= required_power) {\n                        covered[other] = true;\n                        assignments[other] = best_station;\n                        sol.covered++;\n                    }\n                }\n            }\n        }\n        \n        // Set powers based on assignments\n        vector<double> max_power(N, 0.0);\n        for (int k = 0; k < K; k++) {\n            if (assignments[k] != -1) {\n                max_power[assignments[k]] = max(max_power[assignments[k]], \n                                               station_to_resident_dist[assignments[k]][k]);\n            }\n        }\n        \n        // Calculate power cost\n        ll power_cost = 0;\n        for (int i = 0; i < N; i++) {\n            sol.P[i] = min(5000, static_cast<int>(ceil(max_power[i])));\n            power_cost += static_cast<ll>(sol.P[i]) * sol.P[i];\n        }\n        \n        sol.cost = power_cost + get_edge_cost(sol.B);\n    }\n    \n    void solve() {\n        // Build initial MST solution\n        Solution sol = build_mst_solution();\n        \n        // Optimize power assignments\n        optimize_powers(sol);\n        best_solution = sol;\n        \n        // Run local search with simulated annealing\n        for (int trial = 0; trial < 5; trial++) {\n            Solution improved = local_search(best_solution);\n            optimize_powers(improved);\n            \n            if (improved.covered == K && \n                (best_solution.covered < K || improved.cost < best_solution.cost)) {\n                best_solution = improved;\n            }\n        }\n        \n        // Final power optimization\n        optimize_powers(best_solution);\n        \n        // Output solution\n        output_solution(best_solution);\n    }\n    \n    void output_solution(const Solution& sol) {\n        for (int i = 0; i < N; i++) {\n            cout << sol.P[i];\n            if (i < N - 1) cout << \" \";\n        }\n        cout << endl;\n        \n        for (int i = 0; i < M; i++) {\n            cout << sol.B[i];\n            if (i < M - 1) cout << \" \";\n        }\n        cout << endl;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    TVNetworkOptimizer optimizer;\n    optimizer.read_input();\n    optimizer.solve();\n    \n    return 0;\n}","ahc021":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <utility>\n#include <tuple>\n\nusing namespace std;\n\nvector<vector<int>> pyramid;\nvector<tuple<int, int, int, int>> operations;\n\n// Check if two positions are adjacent\nbool is_adjacent(int x1, int y1, int x2, int y2) {\n    return (x1 == x2 - 1 && y1 == y2 - 1) ||\n           (x1 == x2 - 1 && y1 == y2) ||\n           (x1 == x2 && y1 == y2 - 1) ||\n           (x1 == x2 && y1 == y2 + 1) ||\n           (x1 == x2 + 1 && y1 == y2) ||\n           (x1 == x2 + 1 && y1 == y2 + 1);\n}\n\n// Count the number of violations\nint count_violations() {\n    int violations = 0;\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            if (pyramid[x][y] > pyramid[x+1][y]) violations++;\n            if (pyramid[x][y] > pyramid[x+1][y+1]) violations++;\n        }\n    }\n    return violations;\n}\n\n// Swap two balls and record the operation\nvoid swap_balls(int x1, int y1, int x2, int y2) {\n    if (!is_adjacent(x1, y1, x2, y2)) {\n        cerr << \"Error: Attempting to swap non-adjacent balls\" << endl;\n        return;\n    }\n    operations.emplace_back(x1, y1, x2, y2);\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n}\n\n// Top-down pass: ensure each ball is smaller than those below it\nvoid top_down_pass() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            int left_child = pyramid[x+1][y];\n            int right_child = pyramid[x+1][y+1];\n            \n            if (current > left_child || current > right_child) {\n                // Find the smaller child\n                if (left_child < right_child) {\n                    // Swap with left child\n                    swap_balls(x, y, x+1, y);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                } else {\n                    // Swap with right child\n                    swap_balls(x, y, x+1, y+1);\n                    // Check if we need to continue down\n                    int nx = x+1, ny = y+1;\n                    while (nx < 29) {\n                        int ncurrent = pyramid[nx][ny];\n                        int nleft = pyramid[nx+1][ny];\n                        int nright = pyramid[nx+1][ny+1];\n                        \n                        if (ncurrent > nleft || ncurrent > nright) {\n                            if (nleft < nright) {\n                                swap_balls(nx, ny, nx+1, ny);\n                                nx++; ny = ny;\n                            } else {\n                                swap_balls(nx, ny, nx+1, ny+1);\n                                nx++; ny++;\n                            }\n                        } else {\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\n// Bubble up larger numbers towards the bottom\nvoid bubble_up() {\n    for (int x = 28; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check if current is larger than its parent\n            if (x > 0) {\n                int parent_y = -1;\n                if (y <= x-1 && pyramid[x-1][y] < current) {\n                    parent_y = y;\n                } else if (y > 0 && pyramid[x-1][y-1] < current) {\n                    parent_y = y-1;\n                }\n                \n                if (parent_y != -1) {\n                    // Swap with parent\n                    swap_balls(x, y, x-1, parent_y);\n                }\n            }\n        }\n    }\n}\n\n// Local refinement: fix specific violations\nvoid local_refinement() {\n    for (int x = 0; x < 29; x++) {\n        for (int y = 0; y <= x; y++) {\n            int current = pyramid[x][y];\n            \n            // Check violation with left child\n            if (current > pyramid[x+1][y]) {\n                // Try to find a better position for current\n                bool found = false;\n                \n                // Check adjacent positions\n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    // Just swap with the child\n                    swap_balls(x, y, x+1, y);\n                }\n            }\n            \n            // Check violation with right child\n            if (current > pyramid[x+1][y+1]) {\n                // Similar logic as above\n                bool found = false;\n                \n                vector<pair<int, int>> adjacent_positions;\n                if (y > 0) adjacent_positions.emplace_back(x, y-1);\n                if (y < x) adjacent_positions.emplace_back(x, y+1);\n                if (x > 0 && y > 0) adjacent_positions.emplace_back(x-1, y-1);\n                if (x > 0 && y < x-1) adjacent_positions.emplace_back(x-1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y);\n                if (x < 29) adjacent_positions.emplace_back(x+1, y+1);\n                \n                for (auto [ax, ay] : adjacent_positions) {\n                    if (ax >= 0 && ax < 30 && ay >= 0 && ay <= ax) {\n                        if (pyramid[ax][ay] < current && \n                            ((ax == x+1 && ay == y) || \n                             (ax == x+1 && ay == y+1) ||\n                             (ax == x && ay == y-1) ||\n                             (ax == x && ay == y+1) ||\n                             (ax == x-1 && ay == y) ||\n                             (ax == x-1 && ay == y-1))) {\n                            swap_balls(x, y, ax, ay);\n                            found = true;\n                            break;\n                        }\n                    }\n                }\n                \n                if (!found) {\n                    swap_balls(x, y, x+1, y+1);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    pyramid.resize(30);\n    for (int x = 0; x < 30; x++) {\n        pyramid[x].resize(x+1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Apply our algorithm\n    int max_operations = 10000;\n    \n    // Initial top-down pass\n    top_down_pass();\n    \n    // Iterative improvement\n    while (operations.size() < max_operations) {\n        int violations_before = count_violations();\n        if (violations_before == 0) break;\n        \n        // Try different strategies\n        if (operations.size() % 3 == 0) {\n            bubble_up();\n        } else if (operations.size() % 3 == 1) {\n            top_down_pass();\n        } else {\n            local_refinement();\n        }\n        \n        // Check if we're making progress\n        int violations_after = count_violations();\n        if (violations_after >= violations_before) {\n            // Not making progress, try a different approach\n            break;\n        }\n    }\n    \n    // Final pass to fix remaining violations\n    if (operations.size() < max_operations) {\n        local_refinement();\n    }\n    \n    // Output the result\n    cout << operations.size() << endl;\n    for (auto [x1, y1, x2, y2] : operations) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <climits>\n#include <cmath>\n#include <algorithm>\n#include <cstring>\n#include <iomanip>\n\nusing namespace std;\n\nconst int D = 9;\nconst int dx[4] = {0, 0, 1, -1};\nconst int dy[4] = {1, -1, 0, 0};\n\nint grid[D][D];\nint base_distance[D][D];\n\nvoid bfs_base() {\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            base_distance[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    base_distance[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (base_distance[nx][ny] == -1 && grid[nx][ny] != -1) {\n                    base_distance[nx][ny] = base_distance[x][y] + 1;\n                    q.push({nx, ny});\n                }\n            }\n        }\n    }\n}\n\nstruct BFSResult {\n    bool visited[D][D];\n    int dist[D][D];\n};\n\nBFSResult bfs_current() {\n    BFSResult res;\n    memset(res.visited, false, sizeof(res.visited));\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            res.dist[i][j] = -1;\n        }\n    }\n    queue<pair<int, int>> q;\n    res.visited[0][4] = true;\n    res.dist[0][4] = 0;\n    q.push({0, 4});\n    while (!q.empty()) {\n        auto [x, y] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (!res.visited[nx][ny]) {\n                    if (grid[nx][ny] == 0 || grid[nx][ny] == -2) {\n                        res.visited[nx][ny] = true;\n                        res.dist[nx][ny] = res.dist[x][y] + 1;\n                        q.push({nx, ny});\n                    }\n                }\n            }\n        }\n    }\n    return res;\n}\n\nbool check_reachability_after_placing(int i, int j, int t_d) {\n    grid[i][j] = t_d;\n    BFSResult res = bfs_current();\n    vector<pair<int, int>> container_cells;\n    for (int x = 0; x < D; x++) {\n        for (int y = 0; y < D; y++) {\n            if (grid[x][y] >= 0) {\n                container_cells.push_back({x, y});\n            }\n        }\n    }\n    bool all_reachable = true;\n    for (auto [x, y] : container_cells) {\n        bool reachable = false;\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d], ny = y + dy[d];\n            if (nx >= 0 && nx < D && ny >= 0 && ny < D) {\n                if (res.visited[nx][ny]) {\n                    reachable = true;\n                    break;\n                }\n            }\n        }\n        if (!reachable) {\n            all_reachable = false;\n            break;\n        }\n    }\n    grid[i][j] = 0;\n    return all_reachable;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(NULL);\n\n    int N;\n    cin >> N;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            grid[i][j] = 0;\n        }\n    }\n    grid[0][4] = -2;\n    for (int i = 0; i < N; i++) {\n        int r, c;\n        cin >> r >> c;\n        grid[r][c] = -1;\n    }\n\n    bfs_base();\n\n    int min_base = INT_MAX, max_base = INT_MIN;\n    for (int i = 0; i < D; i++) {\n        for (int j = 0; j < D; j++) {\n            if (i == 0 && j == 4) continue;\n            if (grid[i][j] == -1) continue;\n            if (base_distance[i][j] == -1) continue;\n            if (base_distance[i][j] < min_base) min_base = base_distance[i][j];\n            if (base_distance[i][j] > max_base) max_base = base_distance[i][j];\n        }\n    }\n\n    int M = D * D - 1 - N;\n\n    if (M > 0) {\n        for (int d = 0; d < M; d++) {\n            int t_d;\n            cin >> t_d;\n\n            double desired;\n            if (M == 1) {\n                desired = min_base;\n            } else {\n                desired = (double)(t_d) / (M - 1) * (max_base - min_base) + min_base;\n            }\n\n            BFSResult res1 = bfs_current();\n            vector<pair<int, int>> candidate_cells;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] == 0 && res1.visited[i][j]) {\n                        candidate_cells.push_back({i, j});\n                    }\n                }\n            }\n\n            vector<pair<int, int>> valid_candidates;\n            vector<double> costs;\n            vector<int> current_dists;\n\n            for (auto [i, j] : candidate_cells) {\n                if (check_reachability_after_placing(i, j, t_d)) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            if (valid_candidates.empty()) {\n                for (auto [i, j] : candidate_cells) {\n                    valid_candidates.push_back({i, j});\n                    double cost_val = abs(base_distance[i][j] - desired);\n                    costs.push_back(cost_val);\n                    current_dists.push_back(res1.dist[i][j]);\n                }\n            }\n\n            int best_index = 0;\n            for (int idx = 1; idx < valid_candidates.size(); idx++) {\n                if (costs[idx] < costs[best_index]) {\n                    best_index = idx;\n                } else if (costs[idx] == costs[best_index]) {\n                    if (current_dists[idx] < current_dists[best_index]) {\n                        best_index = idx;\n                    } else if (current_dists[idx] == current_dists[best_index]) {\n                        if (base_distance[valid_candidates[idx].first][valid_candidates[idx].second] < \n                            base_distance[valid_candidates[best_index].first][valid_candidates[best_index].second]) {\n                            best_index = idx;\n                        }\n                    }\n                }\n            }\n\n            auto [i, j] = valid_candidates[best_index];\n            grid[i][j] = t_d;\n            cout << i << \" \" << j << endl;\n            cout.flush();\n        }\n    }\n\n    if (M > 0) {\n        vector<pair<int, int>> transport_order;\n        for (int step = 0; step < M; step++) {\n            BFSResult res = bfs_current();\n            vector<pair<int, int>> reachable_containers;\n            for (int i = 0; i < D; i++) {\n                for (int j = 0; j < D; j++) {\n                    if (grid[i][j] >= 0) {\n                        for (int d = 0; d < 4; d++) {\n                            int ni = i + dx[d], nj = j + dy[d];\n                            if (ni >= 0 && ni < D && nj >= 0 && nj < D) {\n                                if (res.visited[ni][nj]) {\n                                    reachable_containers.push_back({i, j});\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            int min_number = INT_MAX;\n            pair<int, int> min_cell = {-1, -1};\n            for (auto [i, j] : reachable_containers) {\n                if (grid[i][j] < min_number) {\n                    min_number = grid[i][j];\n                    min_cell = {i, j};\n                }\n            }\n\n            grid[min_cell.first][min_cell.second] = 0;\n            transport_order.push_back(min_cell);\n        }\n\n        for (auto [i, j] : transport_order) {\n            cout << i << \" \" << j << endl;\n        }\n        cout.flush();\n    }\n\n    return 0;\n}","ahc024":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\nusing namespace std;\n\nconst int dx[4] = {1, 0, -1, 0};\nconst int dy[4] = {0, 1, 0, -1};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int n, m;\n    cin >> n >> m;\n    vector<vector<int>> grid(n, vector<int>(n));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    vector<vector<bool>> adj(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 = grid[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d], nj = j + dy[d];\n                if (ni < 0 || ni >= n || nj < 0 || nj >= n) {\n                    adj[c1][0] = true;\n                    adj[0][c1] = true;\n                } else {\n                    int c2 = grid[ni][nj];\n                    if (c1 != c2) {\n                        adj[c1][c2] = true;\n                        adj[c2][c1] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    vector<vector<int>> new_grid(n, vector<int>(n, -1));\n    vector<vector<bool>> visited(n, vector<bool>(n, false));\n    queue<tuple<int, int, int>> q;\n\n    vector<int> A;\n    for (int c = 1; c <= m; c++) {\n        if (adj[c][0]) {\n            A.push_back(c);\n        }\n    }\n\n    vector<vector<int>> H(A.size());\n    for (int i = 0; i < A.size(); i++) {\n        for (int j = i+1; j < A.size(); j++) {\n            if (adj[A[i]][A[j]]) {\n                H[i].push_back(j);\n                H[j].push_back(i);\n            }\n        }\n    }\n\n    vector<int> order;\n    vector<bool> done(H.size(), false);\n    if (!H.empty()) {\n        queue<int> qq;\n        qq.push(0);\n        done[0] = true;\n        while (!qq.empty()) {\n            int u = qq.front(); qq.pop();\n            order.push_back(u);\n            for (int v : H[u]) {\n                if (!done[v]) {\n                    done[v] = true;\n                    qq.push(v);\n                }\n            }\n        }\n    }\n\n    vector<pair<int, int>> boundary;\n    for (int j = 0; j < n; j++) {\n        boundary.emplace_back(0, j);\n    }\n    for (int i = 1; i < n; i++) {\n        boundary.emplace_back(i, n-1);\n    }\n    for (int j = n-2; j >= 0; j--) {\n        boundary.emplace_back(n-1, j);\n    }\n    for (int i = n-2; i >= 1; i--) {\n        boundary.emplace_back(i, 0);\n    }\n\n    vector<int> boundary_assignment;\n    if (!order.empty()) {\n        boundary_assignment.push_back(A[order[0]]);\n        for (int i = 1; i < order.size(); i++) {\n            int u = order[i-1];\n            int v = order[i];\n            bool adj_in_H = false;\n            for (int w : H[u]) {\n                if (w == v) {\n                    adj_in_H = true;\n                    break;\n                }\n            }\n            if (!adj_in_H) {\n                boundary_assignment.push_back(0);\n            }\n            boundary_assignment.push_back(A[v]);\n        }\n        int u = order.back();\n        int v = order[0];\n        bool adj_in_H = false;\n        for (int w : H[u]) {\n            if (w == v) {\n                adj_in_H = true;\n                break;\n            }\n        }\n        if (!adj_in_H) {\n            boundary_assignment.push_back(0);\n        }\n    }\n\n    for (int idx = 0; idx < boundary.size(); idx++) {\n        int color = (idx < boundary_assignment.size()) ? boundary_assignment[idx] : 0;\n        int i = boundary[idx].first;\n        int j = boundary[idx].second;\n        new_grid[i][j] = color;\n        visited[i][j] = true;\n        if (color != 0) {\n            q.push({i, j, color});\n        }\n    }\n\n    while (!q.empty()) {\n        auto [i, j, c] = q.front(); q.pop();\n        for (int d = 0; d < 4; d++) {\n            int ni = i + dx[d];\n            int nj = j + dy[d];\n            if (ni < 0 || ni >= n || nj < 0 || nj >= n) continue;\n            if (visited[ni][nj]) continue;\n            bool can_assign = true;\n            for (int dd = 0; dd < 4; dd++) {\n                int nni = ni + dx[dd];\n                int nnj = nj + dy[dd];\n                if (nni < 0 || nni >= n || nnj < 0 || nnj >= n) continue;\n                if (new_grid[nni][nnj] == -1) continue;\n                int d_color = new_grid[nni][nnj];\n                if (d_color == 0) continue;\n                if (d_color == c) continue;\n                if (!adj[c][d_color]) {\n                    can_assign = false;\n                    break;\n                }\n            }\n            if (can_assign) {\n                new_grid[ni][nj] = c;\n                visited[ni][nj] = true;\n                q.push({ni, nj, c});\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (new_grid[i][j] == -1) {\n                new_grid[i][j] = 0;\n            }\n        }\n    }\n\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << new_grid[i][j] << (j < n-1 ? ' ' : '\\n');\n        }\n    }\n\n    return 0;\n}","ahc025":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <atcoder/all>\nusing namespace std;\nusing namespace atcoder;\n\nusing ll = long long;\n\n// Random number generator with proper seeding\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\n// Function to output a query and get the result\nchar query(int nL, int nR, const vector<int>& L, const vector<int>& R) {\n    cout << nL << \" \" << nR;\n    for (int i : L) cout << \" \" << i;\n    for (int i : R) cout << \" \" << i;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\n// Function to partition items into D sets based on estimated weights\nvector<int> partition_items(int N, int D, const vector<double>& estimated_weights) {\n    // Create pairs of (item_index, estimated_weight)\n    vector<pair<double, int>> items;\n    for (int i = 0; i < N; i++) {\n        items.emplace_back(estimated_weights[i], i);\n    }\n    \n    // Sort items by estimated weight in descending order\n    sort(items.rbegin(), items.rend());\n    \n    // Initialize D sets\n    vector<double> set_weights(D, 0.0);\n    vector<int> assignment(N, -1);\n    \n    // Greedy assignment: assign each item to the set with the smallest current total weight\n    for (const auto& [weight, idx] : items) {\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        assignment[idx] = min_set;\n        set_weights[min_set] += weight;\n    }\n    \n    // Improvement phase 1: Try to balance by swapping items between sets\n    for (int iter = 0; iter < 100; iter++) {\n        // Calculate the current variance\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        double variance = 0.0;\n        for (double w : set_weights) {\n            variance += (w - mean) * (w - mean);\n        }\n        variance /= D;\n        \n        // Try to find a swap that reduces the variance\n        bool improved = false;\n        \n        // Try swaps between sets\n        for (int trial = 0; trial < 50; trial++) {\n            int i = rng() % N;\n            int j = rng() % N;\n            while (i == j) {\n                j = rng() % N;\n            }\n            \n            if (assignment[i] != assignment[j]) {\n                // Calculate the new variance if we swap items i and j\n                int set_i = assignment[i];\n                int set_j = assignment[j];\n                \n                double new_weight_i = set_weights[set_i] - estimated_weights[i] + estimated_weights[j];\n                double new_weight_j = set_weights[set_j] - estimated_weights[j] + estimated_weights[i];\n                \n                double new_variance = variance;\n                new_variance -= (set_weights[set_i] - mean) * (set_weights[set_i] - mean) / D;\n                new_variance -= (set_weights[set_j] - mean) * (set_weights[set_j] - mean) / D;\n                new_variance += (new_weight_i - mean) * (new_weight_i - mean) / D;\n                new_variance += (new_weight_j - mean) * (new_weight_j - mean) / D;\n                \n                if (new_variance < variance) {\n                    // Swap the items\n                    assignment[i] = set_j;\n                    assignment[j] = set_i;\n                    set_weights[set_i] = new_weight_i;\n                    set_weights[set_j] = new_weight_j;\n                    improved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Improvement phase 2: Try to move items to balance sets\n    for (int iter = 0; iter < 50; iter++) {\n        double mean = accumulate(set_weights.begin(), set_weights.end(), 0.0) / D;\n        \n        // Find the set with the highest weight and the set with the lowest weight\n        int max_set = max_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        int min_set = min_element(set_weights.begin(), set_weights.end()) - set_weights.begin();\n        \n        if (set_weights[max_set] - set_weights[min_set] < 1e-6) break;\n        \n        // Find an item in the max_set that can be moved to min_set to reduce difference\n        bool moved = false;\n        for (int i = 0; i < N; i++) {\n            if (assignment[i] == max_set) {\n                double new_max = set_weights[max_set] - estimated_weights[i];\n                double new_min = set_weights[min_set] + estimated_weights[i];\n                \n                double current_diff = set_weights[max_set] - set_weights[min_set];\n                double new_diff = abs(new_max - new_min);\n                \n                if (new_diff < current_diff) {\n                    // Move the item\n                    assignment[i] = min_set;\n                    set_weights[max_set] = new_max;\n                    set_weights[min_set] = new_min;\n                    moved = true;\n                    break;\n                }\n            }\n        }\n        \n        if (!moved) break;\n    }\n    \n    return assignment;\n}\n\nint main() {\n    int N, D, Q;\n    cin >> N >> D >> Q;\n    \n    // Initialize estimated weights\n    vector<double> estimated_weights(N, 1.0);\n    \n    // Keep track of how many times each item has been compared\n    vector<int> compare_count(N, 0);\n    \n    // Use queries to estimate relative weights\n    for (int q = 0; q < Q; q++) {\n        if (q < Q / 2) {\n            // First half: Compare individual items using tournament method\n            // Find two items with the lowest comparison counts\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            shuffle(indices.begin(), indices.end(), rng);\n            \n            int i = -1, j = -1;\n            for (int idx : indices) {\n                if (i == -1) {\n                    i = idx;\n                } else if (j == -1) {\n                    j = idx;\n                    break;\n                }\n            }\n            \n            char result = query(1, 1, {i}, {j});\n            compare_count[i]++;\n            compare_count[j]++;\n            \n            // Update estimates based on result\n            double adjustment = 0.15;\n            if (result == '>') {\n                estimated_weights[i] *= (1.0 + adjustment);\n                estimated_weights[j] *= (1.0 - adjustment);\n            } else if (result == '<') {\n                estimated_weights[i] *= (1.0 - adjustment);\n                estimated_weights[j] *= (1.0 + adjustment);\n            }\n        } else {\n            // Second half: Compare groups of items to refine estimates\n            // Sort items by estimated weight\n            vector<int> indices(N);\n            iota(indices.begin(), indices.end(), 0);\n            sort(indices.begin(), indices.end(), [&](int a, int b) {\n                return estimated_weights[a] < estimated_weights[b];\n            });\n            \n            // Create two groups of similar weight items\n            int group_size = 2 + rng() % min(4, N / 5);\n            int start = rng() % (N - 2 * group_size);\n            \n            vector<int> group1, group2;\n            for (int k = 0; k < group_size; k++) {\n                group1.push_back(indices[start + k]);\n                group2.push_back(indices[start + group_size + k]);\n            }\n            \n            char result = query(group_size, group_size, group1, group2);\n            \n            // Update estimates based on result\n            double adjustment = 0.08;\n            if (result == '>') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n            } else if (result == '<') {\n                for (int k : group1) {\n                    estimated_weights[k] *= (1.0 - adjustment);\n                }\n                for (int k : group2) {\n                    estimated_weights[k] *= (1.0 + adjustment);\n                }\n            }\n            \n            for (int k : group1) compare_count[k]++;\n            for (int k : group2) compare_count[k]++;\n        }\n    }\n    \n    // Normalize estimated weights to a reasonable scale\n    double min_weight = *min_element(estimated_weights.begin(), estimated_weights.end());\n    for (int i = 0; i < N; i++) {\n        estimated_weights[i] /= min_weight;\n    }\n    \n    // Partition items into D sets\n    vector<int> assignment = partition_items(N, D, estimated_weights);\n    \n    // Output the assignment\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    cout.flush();\n    \n    return 0;\n}","ahc026":"#include <iostream>\n#include <vector>\n#include <algorithm>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    vector<int> position(n + 1);  // position[v] = stack_index\n    \n    // Read input and initialize data structures\n    for (int i = 0; i < m; i++) {\n        stacks[i].resize(n / m);\n        for (int j = 0; j < n / m; j++) {\n            cin >> stacks[i][j];\n            position[stacks[i][j]] = i;\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    int next_box = 1;\n    \n    while (next_box <= n) {\n        // Check if next_box is at the top of any stack\n        bool found_at_top = false;\n        for (int i = 0; i < m; i++) {\n            if (!stacks[i].empty() && stacks[i].back() == next_box) {\n                // Carry out operation\n                stacks[i].pop_back();\n                operations.emplace_back(next_box, 0);\n                next_box++;\n                found_at_top = true;\n                break;\n            }\n        }\n        \n        if (found_at_top) continue;\n        \n        // Find the stack containing next_box\n        int stack_idx = -1;\n        int pos_in_stack = -1;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < stacks[i].size(); j++) {\n                if (stacks[i][j] == next_box) {\n                    stack_idx = i;\n                    pos_in_stack = j;\n                    break;\n                }\n            }\n            if (stack_idx != -1) break;\n        }\n        \n        // The box immediately above next_box\n        int box_above = stacks[stack_idx][pos_in_stack + 1];\n        \n        // Choose destination stack\n        int best_dest = -1;\n        \n        // Prefer empty stacks\n        for (int i = 0; i < m; i++) {\n            if (i != stack_idx && stacks[i].empty()) {\n                best_dest = i;\n                break;\n            }\n        }\n        \n        // If no empty stack, prefer stacks with larger bottom elements\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx && !stacks[i].empty() && stacks[i][0] > next_box) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Otherwise, choose any non-source stack\n        if (best_dest == -1) {\n            for (int i = 0; i < m; i++) {\n                if (i != stack_idx) {\n                    best_dest = i;\n                    break;\n                }\n            }\n        }\n        \n        // Move boxes above next_box (including box_above) to destination\n        vector<int> moved_boxes;\n        for (int i = pos_in_stack + 1; i < stacks[stack_idx].size(); i++) {\n            moved_boxes.push_back(stacks[stack_idx][i]);\n            position[stacks[stack_idx][i]] = best_dest;\n        }\n        \n        // Update source stack\n        stacks[stack_idx].resize(pos_in_stack + 1);\n        \n        // Update destination stack\n        stacks[best_dest].insert(stacks[best_dest].end(), \n                                 moved_boxes.begin(), moved_boxes.end());\n        \n        // Record operation\n        operations.emplace_back(box_above, best_dest + 1);\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <iostream>\n#include <vector>\n#include <string>\n#include <algorithm>\n#include <queue>\n#include <random>\n#include <chrono>\n#include <cmath>\n#include <utility>\n#include <unordered_set>\n#include <atcoder/dsu>\n\nusing namespace std;\nusing namespace atcoder;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n    bool operator!=(const Point& other) const {\n        return !(*this == other);\n    }\n    Point operator+(const Point& other) const {\n        return Point(i + other.i, j + other.j);\n    }\n};\n\nnamespace std {\n    template<>\n    struct hash<Point> {\n        size_t operator()(const Point& p) const {\n            return static_cast<size_t>(p.i) * 1000 + p.j;\n        }\n    };\n}\n\nclass Solution {\npublic:\n    int N;\n    vector<string> h, v;\n    vector<vector<int>> d;\n    vector<vector<bool>> visited;\n    vector<Point> path;\n    string route;\n    \n    // Directions: R, D, L, U\n    const vector<Point> directions = {Point(0, 1), Point(1, 0), Point(0, -1), Point(-1, 0)};\n    const string dir_chars = \"RDLU\";\n    \n    Solution(int n, const vector<string>& h, const vector<string>& v, const vector<vector<int>>& d)\n        : N(n), h(h), v(v), d(d), visited(n, vector<bool>(n, false)) {\n        // Initialize path with starting point\n        path.emplace_back(0, 0);\n    }\n    \n    bool can_move(const Point& from, const Point& to) const {\n        if (to.i < 0 || to.i >= N || to.j < 0 || to.j >= N) return false;\n        \n        // Check horizontal wall\n        if (from.i == to.i) {\n            int j = min(from.j, to.j);\n            if (v[from.i][j] == '1') return false;\n        }\n        // Check vertical wall\n        else if (from.j == to.j) {\n            int i = min(from.i, to.i);\n            if (h[i][from.j] == '1') return false;\n        }\n        return true;\n    }\n    \n    void dfs(Point p) {\n        visited[p.i][p.j] = true;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            Point next = p + directions[dir];\n            if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                !visited[next.i][next.j] && can_move(p, next)) {\n                path.push_back(next);\n                route += dir_chars[dir];\n                dfs(next);\n                path.push_back(p);\n                route += dir_chars[(dir + 2) % 4];\n            }\n        }\n    }\n    \n    vector<Point> bfs(const Point& start, const Point& end) {\n        vector<vector<Point>> parent(N, vector<Point>(N, Point(-1, -1)));\n        vector<vector<bool>> bfs_visited(N, vector<bool>(N, false));\n        queue<Point> q;\n        \n        q.push(start);\n        bfs_visited[start.i][start.j] = true;\n        \n        while (!q.empty()) {\n            Point current = q.front();\n            q.pop();\n            \n            if (current == end) {\n                // Reconstruct path\n                vector<Point> result;\n                Point p = end;\n                while (p != start) {\n                    result.push_back(p);\n                    p = parent[p.i][p.j];\n                }\n                result.push_back(start);\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (const Point& dir : directions) {\n                Point next = current + dir;\n                if (next.i >= 0 && next.i < N && next.j >= 0 && next.j < N && \n                    !bfs_visited[next.i][next.j] && can_move(current, next)) {\n                    bfs_visited[next.i][next.j] = true;\n                    parent[next.i][next.j] = current;\n                    q.push(next);\n                }\n            }\n        }\n        \n        return {}; // No path found\n    }\n    \n    string get_route_string(const vector<Point>& path) {\n        string result;\n        for (size_t i = 1; i < path.size(); i++) {\n            Point from = path[i-1];\n            Point to = path[i];\n            for (int dir = 0; dir < 4; dir++) {\n                if (from + directions[dir] == to) {\n                    result += dir_chars[dir];\n                    break;\n                }\n            }\n        }\n        return result;\n    }\n    \n    void optimize_route() {\n        // Find cells with high dirt susceptibility\n        vector<pair<int, Point>> high_dirt_cells;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                high_dirt_cells.emplace_back(d[i][j], Point(i, j));\n            }\n        }\n        sort(high_dirt_cells.rbegin(), high_dirt_cells.rend());\n        \n        // Try to create shortcuts to high dirt cells\n        for (int iter = 0; iter < 100; iter++) {\n            if (route.length() > 90000) break; // Don't exceed the limit\n            \n            // Select a random high dirt cell\n            int idx = rng() % min(10, (int)high_dirt_cells.size());\n            Point target = high_dirt_cells[idx].second;\n            \n            // Find random positions in the current path\n            int pos1 = rng() % (path.size() - 1);\n            int pos2 = rng() % (path.size() - 1);\n            if (pos1 > pos2) swap(pos1, pos2);\n            \n            // Try to create a shortcut from pos1 to target and back to pos2\n            vector<Point> path1 = bfs(path[pos1], target);\n            vector<Point> path2 = bfs(target, path[pos2]);\n            \n            if (!path1.empty() && !path2.empty() && \n                path1.size() + path2.size() < pos2 - pos1) {\n                // Create new path\n                vector<Point> new_path;\n                for (int i = 0; i <= pos1; i++) {\n                    new_path.push_back(path[i]);\n                }\n                for (size_t i = 1; i < path1.size(); i++) {\n                    new_path.push_back(path1[i]);\n                }\n                for (size_t i = 1; i < path2.size(); i++) {\n                    new_path.push_back(path2[i]);\n                }\n                for (size_t i = pos2 + 1; i < path.size(); i++) {\n                    new_path.push_back(path[i]);\n                }\n                \n                // Update path and route\n                path = new_path;\n                route = get_route_string(path);\n            }\n        }\n        \n        // Ensure we return to (0,0)\n        if (path.back() != Point(0, 0)) {\n            vector<Point> return_path = bfs(path.back(), Point(0, 0));\n            for (size_t i = 1; i < return_path.size(); i++) {\n                path.push_back(return_path[i]);\n            }\n            route = get_route_string(path);\n        }\n        \n        // Ensure length constraint\n        if (route.length() > 100000) {\n            route = route.substr(0, 100000);\n        }\n    }\n    \n    string solve() {\n        // Generate initial route using DFS\n        dfs(Point(0, 0));\n        \n        // Optimize the route\n        optimize_route();\n        \n        return route;\n    }\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> h(N-1);\n    for (int i = 0; i < N-1; i++) {\n        cin >> h[i];\n    }\n    \n    vector<string> v(N);\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\n    \n    vector<vector<int>> d(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    Solution solution(N, h, v, d);\n    string route = solution.solve();\n    cout << route << endl;\n    \n    return 0;\n}","ahc028":"#include <iostream>\n#include <vector>\n#include <string>\n#include <set>\n#include <map>\n#include <queue>\n#include <algorithm>\n#include <climits>\n#include <cmath>\n#include <cstdlib>\n#include <ctime>\n\nusing namespace std;\n\nstruct TargetInfo {\n    string target;\n    int prefix_len;\n    TargetInfo(string t, int pl) : target(t), prefix_len(pl) {}\n    bool operator<(const TargetInfo& other) const {\n        return prefix_len < other.prefix_len; // Longer prefixes first\n    }\n};\n\nint main() {\n    srand(time(0));\n\n    int N, M;\n    cin >> N >> M;\n    int s_i, s_j;\n    cin >> s_i >> s_j;\n\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<string> targets(M);\n    set<string> uncovered_targets;\n    for (int i = 0; i < M; i++) {\n        cin >> targets[i];\n        uncovered_targets.insert(targets[i]);\n    }\n\n    map<string, int> prefix_count;\n    map<string, map<char, int>> next_char_count;\n    priority_queue<TargetInfo> target_queue;\n\n    for (const string& t : targets) {\n        for (int len = 1; len <= 4; len++) {\n            string p = t.substr(0, len);\n            prefix_count[p]++;\n        }\n        for (int len = 0; len < 5; len++) {\n            string p = t.substr(0, len);\n            if (len < 5) {\n                char next_char = t[len];\n                next_char_count[p][next_char]++;\n            }\n        }\n        target_queue.push(TargetInfo(t, 0));\n    }\n\n    int current_i = s_i, current_j = s_j;\n    string current_last4 = string(1, grid[s_i][s_j]);\n    vector<pair<int, int>> path;\n    path.emplace_back(s_i, s_j);\n\n    int steps_since_cover = 0;\n    int total_covered = 0;\n\n    for (int step = 1; step < 5000; step++) {\n        double best_score = -1e18;\n        pair<int, int> best_move = {-1, -1};\n        string best_new_last4;\n        string best_completed_target = \"\";\n\n        // Dynamic bonus based on progress\n        double completion_bonus = 1000000.0 * (1.0 + (double)total_covered / M);\n\n        // Check if we need to explore randomly\n        if (steps_since_cover > 50) {\n            int random_i = rand() % N;\n            int random_j = rand() % N;\n            best_move = {random_i, random_j};\n            steps_since_cover = 0; // Reset counter\n        } else {\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    char c = grid[i][j];\n                    int cost_move = abs(current_i - i) + abs(current_j - j) + 1;\n\n                    string new_last4;\n                    if (current_last4.size() == 4) {\n                        new_last4 = current_last4.substr(1) + c;\n                    } else {\n                        new_last4 = current_last4 + c;\n                    }\n\n                    double score = -cost_move;\n\n                    // Type 1: Complete a target\n                    if (current_last4.size() == 4) {\n                        string candidate = current_last4 + c;\n                        if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                            score += completion_bonus;\n                        }\n                    }\n\n                    // Type 2: Extend existing prefix\n                    if (next_char_count.find(current_last4) != next_char_count.end()) {\n                        const auto& char_count = next_char_count.at(current_last4);\n                        auto it = char_count.find(c);\n                        if (it != char_count.end()) {\n                            // Higher bonus for longer prefixes\n                            score += 10000.0 * it->second * (current_last4.size() + 1);\n                        }\n                    }\n\n                    // Type 3: Create new prefix\n                    if (prefix_count.find(new_last4) != prefix_count.end()) {\n                        score += 1000.0 * prefix_count.at(new_last4);\n                    }\n\n                    // Small random component for exploration\n                    score += (rand() % 1000) * 0.1;\n\n                    if (score > best_score) {\n                        best_score = score;\n                        best_move = {i, j};\n                        best_new_last4 = new_last4;\n                        if (current_last4.size() == 4) {\n                            string candidate = current_last4 + c;\n                            if (uncovered_targets.find(candidate) != uncovered_targets.end()) {\n                                best_completed_target = candidate;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        // Make the move\n        path.push_back(best_move);\n        current_i = best_move.first;\n        current_j = best_move.second;\n        current_last4 = best_new_last4;\n\n        // Update if we completed a target\n        if (!best_completed_target.empty()) {\n            uncovered_targets.erase(best_completed_target);\n            total_covered++;\n            steps_since_cover = 0;\n\n            // Update data structures\n            for (int len = 1; len <= 4; len++) {\n                string p = best_completed_target.substr(0, len);\n                prefix_count[p]--;\n            }\n            for (int len = 0; len < 5; len++) {\n                string p = best_completed_target.substr(0, len);\n                if (len < 5) {\n                    char next_char = best_completed_target[len];\n                    next_char_count[p][next_char]--;\n                }\n            }\n        } else {\n            steps_since_cover++;\n        }\n\n        if (uncovered_targets.empty()) {\n            break;\n        }\n    }\n\n    for (const auto& p : path) {\n        cout << p.first << \" \" << p.second << endl;\n    }\n\n    return 0;\n}","ahc030":"#include <iostream>\n#include <vector>\n#include <random>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <iomanip>\n\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    Point(int i = 0, int j = 0) : i(i), j(j) {}\n    bool operator<(const Point& other) const {\n        return tie(i, j) < tie(other.i, other.j);\n    }\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct OilField {\n    vector<Point> cells;\n    int size;\n};\n\nstruct GridInfo {\n    int N, M;\n    double epsilon;\n    vector<OilField> oil_fields;\n    vector<vector<int>> drilled_values;\n    vector<vector<double>> estimated_values;\n    set<Point> oil_squares;\n    \n    GridInfo(int N, int M, double epsilon) : N(N), M(M), epsilon(epsilon) {\n        drilled_values.assign(N, vector<int>(N, -1));\n        estimated_values.assign(N, vector<double>(N, 0.0));\n    }\n};\n\nvoid read_input(GridInfo& grid) {\n    cin >> grid.N >> grid.M >> grid.epsilon;\n    grid.oil_fields.resize(grid.M);\n    \n    for (int k = 0; k < grid.M; ++k) {\n        int d;\n        cin >> d;\n        grid.oil_fields[k].size = d;\n        grid.oil_fields[k].cells.resize(d);\n        for (int i = 0; i < d; ++i) {\n            cin >> grid.oil_fields[k].cells[i].i >> grid.oil_fields[k].cells[i].j;\n        }\n    }\n}\n\nint drill(GridInfo& grid, int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    grid.drilled_values[i][j] = value;\n    grid.estimated_values[i][j] = value;\n    if (value > 0) {\n        grid.oil_squares.insert(Point(i, j));\n    }\n    return value;\n}\n\nint divine(GridInfo& grid, const vector<Point>& squares) {\n    cout << \"q \" << squares.size();\n    for (const auto& p : squares) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int value;\n    cin >> value;\n    return value;\n}\n\nbool submit_answer(GridInfo& grid, const set<Point>& answer) {\n    cout << \"a \" << answer.size();\n    for (const auto& p : answer) {\n        cout << \" \" << p.i << \" \" << p.j;\n    }\n    cout << endl;\n    cout.flush();\n    int response;\n    cin >> response;\n    return response == 1;\n}\n\nvector<Point> get_region_points(int i1, int j1, int i2, int j2, int N) {\n    vector<Point> points;\n    for (int i = i1; i <= i2; ++i) {\n        for (int j = j1; j <= j2; ++j) {\n            if (i >= 0 && i < N && j >= 0 && j < N) {\n                points.emplace_back(i, j);\n            }\n        }\n    }\n    return points;\n}\n\nvoid explore_grid(GridInfo& grid, int max_operations) {\n    int operations_used = 0;\n    \n    if (operations_used < max_operations) {\n        auto all_points = get_region_points(0, 0, grid.N-1, grid.N-1, grid.N);\n        if (all_points.size() >= 2) {\n            int total_oil_estimate = divine(grid, all_points);\n            operations_used++;\n            \n            double avg_oil = static_cast<double>(total_oil_estimate) / (grid.N * grid.N);\n            for (int i = 0; i < grid.N; ++i) {\n                for (int j = 0; j < grid.N; ++j) {\n                    grid.estimated_values[i][j] = avg_oil;\n                }\n            }\n        }\n    }\n    \n    queue<tuple<int, int, int, int>> regions;\n    regions.push({0, 0, grid.N-1, grid.N-1});\n    \n    while (!regions.empty() && operations_used < max_operations) {\n        auto [i1, j1, i2, j2] = regions.front();\n        regions.pop();\n        \n        auto points = get_region_points(i1, j1, i2, j2, grid.N);\n        if (points.size() < 2) continue;\n        \n        int oil_estimate = divine(grid, points);\n        operations_used++;\n        \n        if (oil_estimate > 0) {\n            int mid_i = (i1 + i2) / 2;\n            int mid_j = (j1 + j2) / 2;\n            \n            if (i2 - i1 > 1 || j2 - j1 > 1) {\n                regions.push({i1, j1, mid_i, mid_j});\n                regions.push({i1, mid_j + 1, mid_i, j2});\n                regions.push({mid_i + 1, j1, i2, mid_j});\n                regions.push({mid_i + 1, mid_j + 1, i2, j2});\n            } else {\n                for (const auto& p : points) {\n                    if (operations_used < max_operations) {\n                        drill(grid, p.i, p.j);\n                        operations_used++;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (operations_used < max_operations) {\n        vector<pair<double, Point>> candidates;\n        for (int i = 0; i < grid.N; ++i) {\n            for (int j = 0; j < grid.N; ++j) {\n                if (grid.drilled_values[i][j] == -1) {\n                    candidates.emplace_back(grid.estimated_values[i][j], Point(i, j));\n                }\n            }\n        }\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        for (const auto& [_, p] : candidates) {\n            if (operations_used >= max_operations) break;\n            drill(grid, p.i, p.j);\n            operations_used++;\n        }\n    }\n}\n\nvoid infer_oil_fields(GridInfo& grid) {\n    for (const auto& field : grid.oil_fields) {\n        vector<pair<int, Point>> possible_positions;\n        \n        for (int di = 0; di <= grid.N - field.cells.back().i; ++di) {\n            for (int dj = 0; dj <= grid.N - field.cells.back().j; ++dj) {\n                int score = 0;\n                for (const auto& cell : field.cells) {\n                    int i = di + cell.i;\n                    int j = dj + cell.j;\n                    if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                        if (grid.drilled_values[i][j] > 0) {\n                            score += grid.drilled_values[i][j];\n                        } else if (grid.drilled_values[i][j] == 0) {\n                            score = -1;\n                            break;\n                        }\n                    }\n                }\n                if (score > 0) {\n                    possible_positions.emplace_back(score, Point(di, dj));\n                }\n            }\n        }\n        \n        sort(possible_positions.rbegin(), possible_positions.rend());\n        \n        for (int idx = 0; idx < min(3, (int)possible_positions.size()); ++idx) {\n            const auto& [_, pos] = possible_positions[idx];\n            double weight = idx == 0 ? 1.0 : 0.5;\n            \n            for (const auto& cell : field.cells) {\n                int i = pos.i + cell.i;\n                int j = pos.j + cell.j;\n                if (i >= 0 && i < grid.N && j >= 0 && j < grid.N) {\n                    if (grid.drilled_values[i][j] == -1) {\n                        grid.estimated_values[i][j] += weight;\n                    }\n                }\n            }\n        }\n    }\n}\n\nset<Point> determine_answer(GridInfo& grid) {\n    set<Point> answer;\n    \n    answer.insert(grid.oil_squares.begin(), grid.oil_squares.end());\n    \n    for (int i = 0; i < grid.N; ++i) {\n        for (int j = 0; j < grid.N; ++j) {\n            if (grid.drilled_values[i][j] == -1 && grid.estimated_values[i][j] > 0.5) {\n                answer.insert(Point(i, j));\n            }\n        }\n    }\n    \n    return answer;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    double epsilon;\n    cin >> N >> M >> epsilon;\n    \n    GridInfo grid(N, M, epsilon);\n    read_input(grid);\n    \n    int max_operations = 2 * N * N;\n    \n    explore_grid(grid, max_operations / 2);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations * 3 / 4);\n    \n    infer_oil_fields(grid);\n    \n    explore_grid(grid, max_operations);\n    \n    set<Point> answer = determine_answer(grid);\n    \n    bool correct = submit_answer(grid, answer);\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <chrono>\n#include <cassert>\n#include <queue>\n#include <numeric>\n\nusing namespace std;\n\nstruct Rectangle {\n    int i0, j0, i1, j1;\n    \n    Rectangle() : i0(0), j0(0), i1(0), j1(0) {}\n    Rectangle(int i0, int j0, int i1, int j1) : i0(i0), j0(j0), i1(i1), j1(j1) {}\n    \n    int area() const {\n        return (i1 - i0) * (j1 - j0);\n    }\n    \n    bool operator==(const Rectangle& other) const {\n        return i0 == other.i0 && j0 == other.j0 && i1 == other.i1 && j1 == other.j1;\n    }\n};\n\nstruct DayLayout {\n    vector<Rectangle> rectangles;\n    vector<vector<int>> horizontal_partitions;  // H_{d,i,j}\n    vector<vector<int>> vertical_partitions;    // V_{d,i,j}\n    \n    DayLayout(int W) {\n        horizontal_partitions.resize(W-1, vector<int>(W, 0));\n        vertical_partitions.resize(W, vector<int>(W-1, 0));\n    }\n    \n    void update_partitions(int W) {\n        // Reset partitions\n        for (auto& row : horizontal_partitions) fill(row.begin(), row.end(), 0);\n        for (auto& row : vertical_partitions) fill(row.begin(), row.end(), 0);\n        \n        // Set partitions based on rectangles\n        for (const auto& rect : rectangles) {\n            // Horizontal partitions (top and bottom edges)\n            if (rect.i0 > 0) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i0-1][j] = 1;\n                }\n            }\n            if (rect.i1 < W) {\n                for (int j = rect.j0; j < rect.j1; ++j) {\n                    horizontal_partitions[rect.i1-1][j] = 1;\n                }\n            }\n            \n            // Vertical partitions (left and right edges)\n            if (rect.j0 > 0) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j0-1] = 1;\n                }\n            }\n            if (rect.j1 < W) {\n                for (int i = rect.i0; i < rect.i1; ++i) {\n                    vertical_partitions[i][rect.j1-1] = 1;\n                }\n            }\n        }\n    }\n};\n\nclass EventHallOptimizer {\nprivate:\n    int W, D, N;\n    vector<vector<int>> desired_areas;\n    vector<DayLayout> layouts;\n    mt19937 rng;\n    \npublic:\n    EventHallOptimizer(int W, int D, int N, const vector<vector<int>>& areas)\n        : W(W), D(D), N(N), desired_areas(areas) {\n        // Initialize random number generator\n        rng = mt19937(chrono::steady_clock::now().time_since_epoch().count());\n        \n        layouts.reserve(D);\n        for (int d = 0; d < D; ++d) {\n            layouts.emplace_back(W);\n        }\n    }\n    \n    void solve() {\n        // Generate initial layout for day 0\n        generate_initial_layout(0);\n        layouts[0].update_partitions(W);\n        \n        // Generate layouts for subsequent days\n        for (int d = 1; d < D; ++d) {\n            // Start with previous day's layout as base\n            layouts[d] = layouts[d-1];\n            \n            // Optimize layout for day d\n            optimize_layout(d);\n            layouts[d].update_partitions(W);\n        }\n    }\n    \n    void generate_initial_layout(int day) {\n        vector<pair<int, int>> area_indices;\n        for (int k = 0; k < N; ++k) {\n            area_indices.emplace_back(desired_areas[day][k], k);\n        }\n        sort(area_indices.begin(), area_indices.end(), greater<pair<int, int>>());\n        \n        vector<Rectangle> rects(N);\n        vector<bool> used(N, false);\n        \n        // Use a space-filling curve approach\n        int current_i = 0, current_j = 0;\n        \n        for (const auto& [area, idx] : area_indices) {\n            // Find best fitting rectangle\n            Rectangle best_rect;\n            int best_score = -1;\n            \n            // Try different starting positions and sizes\n            for (int start_i = current_i; start_i < W - 1; ++start_i) {\n                for (int start_j = (start_i == current_i ? current_j : 0); start_j < W - 1; ++start_j) {\n                    // Try different aspect ratios\n                    for (int aspect = 1; aspect <= 4; ++aspect) {\n                        int height = sqrt(area * aspect);\n                        int width = area / height;\n                        if (width * height < area) width++;\n                        \n                        // Ensure rectangle fits\n                        if (start_i + height > W || start_j + width > W) continue;\n                        \n                        Rectangle rect(start_i, start_j, start_i + height, start_j + width);\n                        \n                        // Check for overlaps\n                        bool overlap = false;\n                        for (int k = 0; k < N; ++k) {\n                            if (used[k] && rectangles_overlap(rect, rects[k])) {\n                                overlap = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!overlap) {\n                            int score = rect.area();\n                            if (score > best_score) {\n                                best_score = score;\n                                best_rect = rect;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            if (best_score == -1) {\n                // Fallback: place at current position with minimum size\n                int side = ceil(sqrt(area));\n                best_rect = Rectangle(current_i, current_j, \n                                    min(current_i + side, W), \n                                    min(current_j + side, W));\n            }\n            \n            rects[idx] = best_rect;\n            used[idx] = true;\n            \n            // Update current position\n            current_j = best_rect.j1;\n            if (current_j >= W - 1) {\n                current_j = 0;\n                current_i = best_rect.i1;\n            }\n        }\n        \n        layouts[day].rectangles = rects;\n    }\n    \n    void optimize_layout(int day) {\n        const double initial_temp = 1000.0;\n        const double cooling_rate = 0.95;\n        const int iterations = 1000;\n        \n        double temp = initial_temp;\n        vector<Rectangle> current_rects = layouts[day].rectangles;\n        int current_cost = calculate_total_cost(day, current_rects);\n        \n        for (int iter = 0; iter < iterations; ++iter) {\n            // Generate neighbor solution\n            vector<Rectangle> neighbor_rects = current_rects;\n            apply_random_move(day, neighbor_rects);\n            \n            // Calculate cost\n            int neighbor_cost = calculate_total_cost(day, neighbor_rects);\n            \n            // Accept or reject\n            int delta = neighbor_cost - current_cost;\n            if (delta < 0 || exp(-delta / temp) > generate_random_double()) {\n                current_rects = neighbor_rects;\n                current_cost = neighbor_cost;\n            }\n            \n            // Cool down\n            temp *= cooling_rate;\n        }\n        \n        layouts[day].rectangles = current_rects;\n    }\n    \n    void apply_random_move(int day, vector<Rectangle>& rects) {\n        uniform_int_distribution<int> move_dist(0, 2);\n        int move_type = move_dist(rng);\n        \n        switch (move_type) {\n            case 0: // Resize rectangle\n                resize_random_rectangle(rects);\n                break;\n            case 1: // Move rectangle\n                move_random_rectangle(rects);\n                break;\n            case 2: // Swap two rectangles\n                swap_random_rectangles(rects);\n                break;\n        }\n        \n        // Ensure no overlaps\n        fix_overlaps(rects);\n    }\n    \n    void resize_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-10, 10);\n        int di0 = delta_dist(rng);\n        int dj0 = delta_dist(rng);\n        int di1 = delta_dist(rng);\n        int dj1 = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        rect.i0 = max(0, min(W-1, rect.i0 + di0));\n        rect.j0 = max(0, min(W-1, rect.j0 + dj0));\n        rect.i1 = max(rect.i0+1, min(W, rect.i1 + di1));\n        rect.j1 = max(rect.j0+1, min(W, rect.j1 + dj1));\n    }\n    \n    void move_random_rectangle(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx = rect_dist(rng);\n        \n        uniform_int_distribution<int> delta_dist(-5, 5);\n        int di = delta_dist(rng);\n        int dj = delta_dist(rng);\n        \n        Rectangle& rect = rects[idx];\n        int height = rect.i1 - rect.i0;\n        int width = rect.j1 - rect.j0;\n        \n        rect.i0 = max(0, min(W - height, rect.i0 + di));\n        rect.j0 = max(0, min(W - width, rect.j0 + dj));\n        rect.i1 = rect.i0 + height;\n        rect.j1 = rect.j0 + width;\n    }\n    \n    void swap_random_rectangles(vector<Rectangle>& rects) {\n        uniform_int_distribution<int> rect_dist(0, N-1);\n        int idx1 = rect_dist(rng);\n        int idx2 = rect_dist(rng);\n        \n        if (idx1 != idx2) {\n            swap(rects[idx1], rects[idx2]);\n        }\n    }\n    \n    void fix_overlaps(vector<Rectangle>& rects) {\n        // Simple overlap resolution: shrink overlapping rectangles\n        for (int i = 0; i < N; ++i) {\n            for (int j = i+1; j < N; ++j) {\n                if (rectangles_overlap(rects[i], rects[j])) {\n                    // Shrink the smaller rectangle\n                    if (rects[i].area() < rects[j].area()) {\n                        shrink_rectangle(rects[i], rects[j]);\n                    } else {\n                        shrink_rectangle(rects[j], rects[i]);\n                    }\n                }\n            }\n        }\n    }\n    \n    void shrink_rectangle(Rectangle& to_shrink, const Rectangle& other) {\n        // Find intersection and shrink accordingly\n        int left = max(to_shrink.j0, other.j0);\n        int right = min(to_shrink.j1, other.j1);\n        int top = max(to_shrink.i0, other.i0);\n        int bottom = min(to_shrink.i1, other.i1);\n        \n        if (left < right && top < bottom) {\n            // Calculate overlap sizes\n            int overlap_width = right - left;\n            int overlap_height = bottom - top;\n            \n            // Shrink in the direction with smaller overlap\n            if (overlap_width < overlap_height) {\n                if (other.j0 <= to_shrink.j0) {\n                    to_shrink.j0 = right;\n                } else {\n                    to_shrink.j1 = left;\n                }\n            } else {\n                if (other.i0 <= to_shrink.i0) {\n                    to_shrink.i0 = bottom;\n                } else {\n                    to_shrink.i1 = top;\n                }\n            }\n        }\n    }\n    \n    int calculate_total_cost(int day, const vector<Rectangle>& rects) {\n        int cost = 0;\n        \n        // Area penalty cost\n        for (int k = 0; k < N; ++k) {\n            int actual_area = rects[k].area();\n            if (actual_area < desired_areas[day][k]) {\n                cost += 100 * (desired_areas[day][k] - actual_area);\n            }\n        }\n        \n        // Partition change cost (except for day 0)\n        if (day > 0) {\n            // Create temporary layout to calculate partitions\n            DayLayout temp_layout(W);\n            temp_layout.rectangles = rects;\n            temp_layout.update_partitions(W);\n            \n            // Calculate partition differences\n            for (int i = 0; i < W-1; ++i) {\n                for (int j = 0; j < W; ++j) {\n                    if (layouts[day-1].horizontal_partitions[i][j] != temp_layout.horizontal_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n            \n            for (int i = 0; i < W; ++i) {\n                for (int j = 0; j < W-1; ++j) {\n                    if (layouts[day-1].vertical_partitions[i][j] != temp_layout.vertical_partitions[i][j]) {\n                        cost++;\n                    }\n                }\n            }\n        }\n        \n        return cost;\n    }\n    \n    bool rectangles_overlap(const Rectangle& r1, const Rectangle& r2) {\n        return !(r1.i1 <= r2.i0 || r2.i1 <= r1.i0 || r1.j1 <= r2.j0 || r2.j1 <= r1.j0);\n    }\n    \n    double generate_random_double() {\n        return uniform_real_distribution<double>(0.0, 1.0)(rng);\n    }\n    \n    void output_solution() {\n        for (int d = 0; d < D; ++d) {\n            for (int k = 0; k < N; ++k) {\n                const auto& rect = layouts[d].rectangles[k];\n                cout << rect.i0 << \" \" << rect.j0 << \" \" << rect.i1 << \" \" << rect.j1 << \"\\n\";\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> desired_areas(D, vector<int>(N));\n    for (int d = 0; d < D; ++d) {\n        for (int k = 0; k < N; ++k) {\n            cin >> desired_areas[d][k];\n        }\n    }\n    \n    EventHallOptimizer optimizer(W, D, N, desired_areas);\n    optimizer.solve();\n    optimizer.output_solution();\n    \n    return 0;\n}","ahc032":"#include <iostream>\n#include <vector>\n#include <algorithm>\nusing namespace std;\n\nconst int MOD = 998244353;\n\nint main() {\n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<int>> board(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<int>>> stamps(M, vector<vector<int>>(3, vector<int>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<pair<int, pair<int, int>>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_improvement = -1;\n        int best_stamp = -1;\n        int best_p = -1;\n        int best_q = -1;\n        \n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    int improvement = 0;\n                    \n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            int v = board[p + i][q + j];\n                            int x = stamps[m][i][j];\n                            \n                            // Calculate the improvement\n                            int current_mod = v % MOD;\n                            int new_mod = (v + x) % MOD;\n                            int cell_improvement = new_mod - current_mod;\n                            if (cell_improvement < 0) cell_improvement += MOD;\n                            \n                            improvement += cell_improvement;\n                        }\n                    }\n                    \n                    if (improvement > best_improvement) {\n                        best_improvement = improvement;\n                        best_stamp = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        if (best_improvement <= 0) {\n            // No improvement, stop early\n            break;\n        }\n        \n        operations.push_back({best_stamp, {best_p, best_q}});\n        \n        // Apply the stamp\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_stamp][i][j];\n            }\n        }\n    }\n    \n    cout << operations.size() << endl;\n    for (auto &op : operations) {\n        cout << op.first << \" \" << op.second.first << \" \" << op.second.second << endl;\n    }\n    \n    return 0;\n}","ahc033":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <set>\n#include <algorithm>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 5;\n\nchar move_towards(int i0, int j0, int i1, int j1, int grid[N][N], int crane_pos[N][2], int crane_id, bool is_large, int crane_carrying[N]) {\n    vector<char> dirs = {'U', 'D', 'L', 'R'};\n    vector<pair<int, int>> moves = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};\n    int current_dist = abs(i0 - i1) + abs(j0 - j1);\n    vector<char> good_moves;\n    vector<char> ok_moves;\n\n    for (int idx = 0; idx < 4; idx++) {\n        int ni = i0 + moves[idx].first;\n        int nj = j0 + moves[idx].second;\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) {\n            continue;\n        }\n\n        if (crane_carrying[crane_id] != -1 && !is_large) {\n            if (grid[ni][nj] != -1) {\n                continue;\n            }\n        }\n\n        int new_dist = abs(ni - i1) + abs(nj - j1);\n        if (new_dist < current_dist) {\n            good_moves.push_back(dirs[idx]);\n        } else if (new_dist == current_dist) {\n            ok_moves.push_back(dirs[idx]);\n        }\n    }\n\n    if (!good_moves.empty()) {\n        return good_moves[0];\n    } else if (!ok_moves.empty()) {\n        return ok_moves[0];\n    } else {\n        return '.';\n    }\n}\n\nint main() {\n    int n_val;\n    cin >> n_val;\n    int A[N][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    int grid[N][N];\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            grid[i][j] = -1;\n        }\n    }\n\n    int crane_pos[N][2];\n    for (int i = 0; i < N; i++) {\n        crane_pos[i][0] = i;\n        crane_pos[i][1] = 0;\n    }\n\n    int crane_carrying[N];\n    for (int i = 0; i < N; i++) {\n        crane_carrying[i] = -1;\n    }\n\n    int next_container_index[N] = {0};\n    int next_dispatch[N];\n    for (int i = 0; i < N; i++) {\n        next_dispatch[i] = 5 * i;\n    }\n\n    bool bombed[N] = {false};\n    vector<string> crane_actions(N);\n\n    for (int turn = 0; turn < 10000; turn++) {\n        for (int i = 0; i < N; i++) {\n            if (next_container_index[i] < N) {\n                bool crane_holding_at_gate = false;\n                for (int c = 0; c < N; c++) {\n                    if (!bombed[c] && crane_pos[c][0] == i && crane_pos[c][1] == 0 && crane_carrying[c] != -1) {\n                        crane_holding_at_gate = true;\n                        break;\n                    }\n                }\n                if (grid[i][0] == -1 && !crane_holding_at_gate) {\n                    grid[i][0] = A[i][next_container_index[i]];\n                    next_container_index[i]++;\n                }\n            }\n        }\n\n        vector<char> actions(N, '.');\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                actions[c] = '.';\n                continue;\n            }\n\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            int carrying = crane_carrying[c];\n\n            if (carrying != -1) {\n                int container_id = carrying;\n                int target_gate = container_id / N;\n\n                if (container_id == next_dispatch[target_gate]) {\n                    if (i0 == target_gate && j0 == N-1) {\n                        actions[c] = 'Q';\n                    } else {\n                        actions[c] = move_towards(i0, j0, target_gate, N-1, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (j0 >= 1 && j0 <= 3 && grid[i0][j0] == -1) {\n                        actions[c] = 'Q';\n                    } else {\n                        vector<pair<int, int>> candidates;\n                        for (int i = 0; i < N; i++) {\n                            for (int j = 1; j <= 3; j++) {\n                                if (grid[i][j] == -1) {\n                                    candidates.push_back({i, j});\n                                }\n                            }\n                        }\n                        if (!candidates.empty()) {\n                            auto best = candidates[0];\n                            int best_dist = abs(i0 - best.first) + abs(j0 - best.second);\n                            for (auto cand : candidates) {\n                                int dist = abs(i0 - cand.first) + abs(j0 - cand.second);\n                                if (dist < best_dist) {\n                                    best_dist = dist;\n                                    best = cand;\n                                }\n                            }\n                            actions[c] = move_towards(i0, j0, best.first, best.second, grid, crane_pos, c, (c==0), crane_carrying);\n                        } else {\n                            actions[c] = '.';\n                        }\n                    }\n                }\n            } else {\n                vector<tuple<int, int, int>> containers;\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        if (grid[i][j] != -1) {\n                            int cid = grid[i][j];\n                            if (cid / N == c) {\n                                containers.push_back(make_tuple(i, j, cid));\n                            }\n                        }\n                    }\n                }\n                if (!containers.empty()) {\n                    auto best = containers[0];\n                    int best_dist = abs(i0 - get<0>(best)) + abs(j0 - get<1>(best));\n                    for (auto cont : containers) {\n                        int dist = abs(i0 - get<0>(cont)) + abs(j0 - get<1>(cont));\n                        if (dist < best_dist) {\n                            best_dist = dist;\n                            best = cont;\n                        }\n                    }\n                    int ti = get<0>(best), tj = get<1>(best);\n                    if (i0 == ti && j0 == tj) {\n                        actions[c] = 'P';\n                    } else {\n                        actions[c] = move_towards(i0, j0, ti, tj, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                } else {\n                    if (i0 == c && j0 == 0) {\n                        actions[c] = '.';\n                    } else {\n                        actions[c] = move_towards(i0, j0, c, 0, grid, crane_pos, c, (c==0), crane_carrying);\n                    }\n                }\n            }\n        }\n\n        vector<pair<int, int>> next_pos(N);\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'U') {\n                next_pos[c] = {i0-1, j0};\n            } else if (act == 'D') {\n                next_pos[c] = {i0+1, j0};\n            } else if (act == 'L') {\n                next_pos[c] = {i0, j0-1};\n            } else if (act == 'R') {\n                next_pos[c] = {i0, j0+1};\n            } else {\n                next_pos[c] = {i0, j0};\n            }\n        }\n\n        set<int> involved;\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == next_pos[j]) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n        for (int i = 0; i < N; i++) {\n            for (int j = i+1; j < N; j++) {\n                if (next_pos[i] == make_pair(crane_pos[j][0], crane_pos[j][1]) && \n                    next_pos[j] == make_pair(crane_pos[i][0], crane_pos[i][1])) {\n                    involved.insert(i);\n                    involved.insert(j);\n                }\n            }\n        }\n\n        for (int c : involved) {\n            if (!bombed[c]) {\n                actions[c] = '.';\n                next_pos[c] = {crane_pos[c][0], crane_pos[c][1]};\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            if (bombed[c]) {\n                continue;\n            }\n            char act = actions[c];\n            int i0 = crane_pos[c][0];\n            int j0 = crane_pos[c][1];\n            if (act == 'P') {\n                if (crane_carrying[c] == -1 && grid[i0][j0] != -1) {\n                    crane_carrying[c] = grid[i0][j0];\n                    grid[i0][j0] = -1;\n                }\n            } else if (act == 'Q') {\n                if (crane_carrying[c] != -1 && grid[i0][j0] == -1) {\n                    grid[i0][j0] = crane_carrying[c];\n                    crane_carrying[c] = -1;\n                }\n            } else if (act == 'B') {\n                if (crane_carrying[c] == -1) {\n                    bombed[c] = true;\n                }\n            } else if (act == 'U' || act == 'D' || act == 'L' || act == 'R') {\n                crane_pos[c][0] = next_pos[c].first;\n                crane_pos[c][1] = next_pos[c].second;\n            }\n        }\n\n        for (int i = 0; i < N; i++) {\n            if (grid[i][N-1] != -1) {\n                int container_id = grid[i][N-1];\n                grid[i][N-1] = -1;\n                next_dispatch[i] = container_id + 1;\n            }\n        }\n\n        for (int c = 0; c < N; c++) {\n            crane_actions[c] += actions[c];\n        }\n\n        int total_dispatched = 0;\n        for (int i = 0; i < N; i++) {\n            total_dispatched += (next_dispatch[i] - 5*i);\n        }\n        if (total_dispatched == N*N) {\n            break;\n        }\n    }\n\n    size_t max_len = 0;\n    for (int i = 0; i < N; i++) {\n        if (crane_actions[i].size() > max_len) {\n            max_len = crane_actions[i].size();\n        }\n    }\n    for (int i = 0; i < N; i++) {\n        while (crane_actions[i].size() < max_len) {\n            crane_actions[i] += '.';\n        }\n        cout << crane_actions[i] << endl;\n    }\n\n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <climits>\n#include <tuple>\n#include <string>\nusing namespace std;\n\nvector<string> get_manhattan_path(pair<int, int> start, pair<int, int> end) {\n    vector<string> path;\n    int x1 = start.first, y1 = start.second;\n    int x2 = end.first, y2 = end.second;\n    while (x1 < x2) {\n        path.push_back(\"D\");\n        x1++;\n    }\n    while (x1 > x2) {\n        path.push_back(\"U\");\n        x1--;\n    }\n    while (y1 < y2) {\n        path.push_back(\"R\");\n        y1++;\n    }\n    while (y1 > y2) {\n        path.push_back(\"L\");\n        y1--;\n    }\n    return path;\n}\n\nint main() {\n    int N;\n    cin >> N;\n    vector<vector<int>> grid(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> grid[i][j];\n        }\n    }\n\n    long long base = 0;\n    vector<tuple<int, int, int>> sources;\n    vector<tuple<int, int, int>> sinks;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] > 0) {\n                sources.emplace_back(i, j, grid[i][j]);\n                base += grid[i][j];\n            } else if (grid[i][j] < 0) {\n                sinks.emplace_back(i, j, -grid[i][j]);\n                base += -grid[i][j];\n            }\n        }\n    }\n\n    long long total_soil = base / 2;\n\n    if (total_soil == 0) {\n        cout << endl;\n        return 0;\n    }\n\n    pair<int, int> best_hub;\n    long long best_cost = LLONG_MAX;\n\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            pair<int, int> hub = {i, j};\n\n            vector<tuple<int, int, int>> sorted_sources = sources;\n            sort(sorted_sources.begin(), sorted_sources.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            vector<tuple<int, int, int>> sorted_sinks = sinks;\n            sort(sorted_sinks.begin(), sorted_sinks.end(), \n                 [hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n                     int da = abs(get<0>(a) - hub.first) + abs(get<1>(a) - hub.second);\n                     int db = abs(get<0>(b) - hub.first) + abs(get<1>(b) - hub.second);\n                     if (da != db) return da < db;\n                     if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n                     return get<1>(a) < get<1>(b);\n                 });\n\n            long long cost_transport = 0;\n            pair<int, int> current = {0, 0};\n            long long load = 0;\n\n            if (!sorted_sources.empty()) {\n                auto first = sorted_sources[0];\n                int d = abs(current.first - get<0>(first)) + abs(current.second - get<1>(first));\n                cost_transport += d * 100;\n                current = {get<0>(first), get<1>(first)};\n                load += get<2>(first);\n\n                for (int idx = 1; idx < sorted_sources.size(); idx++) {\n                    auto src = sorted_sources[idx];\n                    d = abs(current.first - get<0>(src)) + abs(current.second - get<1>(src));\n                    cost_transport += d * (100 + load);\n                    current = {get<0>(src), get<1>(src)};\n                    load += get<2>(src);\n                }\n\n                d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * (100 + load);\n            } else {\n                int d = abs(current.first - hub.first) + abs(current.second - hub.second);\n                cost_transport += d * 100;\n            }\n\n            current = hub;\n            load = total_soil;\n\n            for (int idx = 0; idx < sorted_sinks.size(); idx++) {\n                auto sink = sorted_sinks[idx];\n                int d = abs(current.first - get<0>(sink)) + abs(current.second - get<1>(sink));\n                cost_transport += d * (100 + load);\n                current = {get<0>(sink), get<1>(sink)};\n                load -= get<2>(sink);\n            }\n\n            long long total_cost = base + cost_transport;\n            if (total_cost < best_cost) {\n                best_cost = total_cost;\n                best_hub = hub;\n            }\n        }\n    }\n\n    vector<tuple<int, int, int>> sorted_sources = sources;\n    sort(sorted_sources.begin(), sorted_sources.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<tuple<int, int, int>> sorted_sinks = sinks;\n    sort(sorted_sinks.begin(), sorted_sinks.end(), \n         [best_hub](const tuple<int, int, int>& a, const tuple<int, int, int>& b) {\n             int da = abs(get<0>(a) - best_hub.first) + abs(get<1>(a) - best_hub.second);\n             int db = abs(get<0>(b) - best_hub.first) + abs(get<1>(b) - best_hub.second);\n             if (da != db) return da < db;\n             if (get<0>(a) != get<0>(b)) return get<0>(a) < get<0>(b);\n             return get<1>(a) < get<1>(b);\n         });\n\n    vector<string> operations;\n    pair<int, int> current_pos = {0, 0};\n\n    if (!sorted_sources.empty()) {\n        auto first = sorted_sources[0];\n        pair<int, int> first_pos = {get<0>(first), get<1>(first)};\n        vector<string> path = get_manhattan_path(current_pos, first_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"+\" + to_string(get<2>(first)));\n        current_pos = first_pos;\n\n        for (int idx = 1; idx < sorted_sources.size(); idx++) {\n            auto src = sorted_sources[idx];\n            pair<int, int> src_pos = {get<0>(src), get<1>(src)};\n            vector<string> path = get_manhattan_path(current_pos, src_pos);\n            operations.insert(operations.end(), path.begin(), path.end());\n            operations.push_back(\"+\" + to_string(get<2>(src)));\n            current_pos = src_pos;\n        }\n\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    } else {\n        vector<string> path_to_hub = get_manhattan_path(current_pos, best_hub);\n        operations.insert(operations.end(), path_to_hub.begin(), path_to_hub.end());\n        current_pos = best_hub;\n    }\n\n    for (auto sink : sorted_sinks) {\n        pair<int, int> sink_pos = {get<0>(sink), get<1>(sink)};\n        vector<string> path = get_manhattan_path(current_pos, sink_pos);\n        operations.insert(operations.end(), path.begin(), path.end());\n        operations.push_back(\"-\" + to_string(get<2>(sink)));\n        current_pos = sink_pos;\n    }\n\n    for (const string& op : operations) {\n        cout << op << endl;\n    }\n\n    return 0;\n}","ahc035":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <random>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int N, M, T;\n    cin >> N >> M >> T;\n    \n    int seed_count = 2 * N * (N - 1);\n    vector<vector<int>> X(seed_count, vector<int>(M, 0));\n    \n    // Read initial seeds\n    for (int i = 0; i < seed_count; i++) {\n        for (int j = 0; j < M; j++) {\n            cin >> X[i][j];\n        }\n    }\n    \n    // For each turn\n    for (int t = 0; t < T; t++) {\n        // Calculate scores for each seed\n        vector<pair<double, int>> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            // Calculate total value\n            int total_value = accumulate(X[i].begin(), X[i].end(), 0);\n            \n            // Find maximum value in any single criterion\n            int max_criterion = *max_element(X[i].begin(), X[i].end());\n            \n            // Calculate sum of top 5 criteria\n            vector<int> sorted_criteria = X[i];\n            sort(sorted_criteria.rbegin(), sorted_criteria.rend());\n            int top5_sum = accumulate(sorted_criteria.begin(), sorted_criteria.begin() + min(5, M), 0);\n            \n            // Combined score with weights\n            double score = 0.5 * total_value + 0.3 * max_criterion + 0.2 * top5_sum;\n            seed_scores[i] = {score, i};\n        }\n        \n        // Sort seeds by score in descending order\n        sort(seed_scores.rbegin(), seed_scores.rend());\n        \n        // Select top 36 seeds\n        vector<int> selected_seeds;\n        for (int i = 0; i < N * N; i++) {\n            selected_seeds.push_back(seed_scores[i].second);\n        }\n        \n        // Create grid arrangement\n        vector<vector<int>> A(N, vector<int>(N, 0));\n        \n        // Strategy: Place seeds with complementary strengths adjacent to each other\n        // Sort selected seeds by their strongest criterion\n        vector<pair<int, int>> seeds_by_max_criterion;\n        for (int seed : selected_seeds) {\n            int max_val = *max_element(X[seed].begin(), X[seed].end());\n            seeds_by_max_criterion.push_back({max_val, seed});\n        }\n        \n        // Sort by maximum criterion value\n        sort(seeds_by_max_criterion.rbegin(), seeds_by_max_criterion.rend());\n        \n        // Place in a checkerboard pattern, alternating high and medium seeds\n        int idx = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if ((i + j) % 2 == 0) {\n                    // Place a seed with high maximum criterion\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                } else {\n                    // Place a seed with balanced criteria\n                    if (idx < selected_seeds.size()) {\n                        A[i][j] = seeds_by_max_criterion[idx++].second;\n                    }\n                }\n            }\n        }\n        \n        // Output the arrangement\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                cout << A[i][j];\n                if (j < N - 1) {\n                    cout << \" \";\n                }\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        // Read new seeds for next turn\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                cin >> X[i][j];\n            }\n        }\n    }\n    \n    return 0;\n}","ahc038":"#include <iostream>\n#include <vector>\n#include <set>\n#include <algorithm>\n#include <climits>\n#include <queue>\nusing namespace std;\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> s_grid(N);\n    vector<string> t_grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> s_grid[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> t_grid[i];\n    }\n    \n    set<pair<int, int>> S;\n    set<pair<int, int>> T;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (s_grid[i][j] == '1' && t_grid[i][j] == '0') {\n                S.insert({i, j});\n            }\n            if (t_grid[i][j] == '1' && s_grid[i][j] == '0') {\n                T.insert({i, j});\n            }\n        }\n    }\n    \n    const vector<int> dx = {0, 1, 0, -1};\n    const vector<int> dy = {1, 0, -1, 0};\n    const vector<char> move_dir = {'R', 'D', 'L', 'U'};\n    \n    int V_prime = 2;\n    cout << V_prime << '\\n';\n    cout << \"0 1\\n\";\n    int rx0 = (N-1)/2;\n    int ry0 = (N-1)/2;\n    cout << rx0 << \" \" << ry0 << '\\n';\n    cout.flush();\n    \n    int rx = rx0;\n    int ry = ry0;\n    int dir = 0;\n    \n    auto manhattan_move = [&](int x1, int y1, int x2, int y2) {\n        vector<char> moves;\n        while (x1 < x2) {\n            moves.push_back('D');\n            x1++;\n        }\n        while (x1 > x2) {\n            moves.push_back('U');\n            x1--;\n        }\n        while (y1 < y2) {\n            moves.push_back('R');\n            y1++;\n        }\n        while (y1 > y2) {\n            moves.push_back('L');\n            y1--;\n        }\n        return moves;\n    };\n    \n    while (!S.empty()) {\n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq;\n        \n        for (const auto& pos : S) {\n            int i = pos.first, j = pos.second;\n            for (int d = 0; d < 4; d++) {\n                int x = i + dx[d];\n                int y = j + dy[d];\n                if (x >= 0 && x < N && y >= 0 && y < N) {\n                    int dist = abs(rx - x) + abs(ry - y);\n                    pq.push({dist, {pos, {x, y}}});\n                }\n            }\n        }\n        \n        auto best = pq.top();\n        pq.pop();\n        pair<int, int> best_pos = best.second.first;\n        pair<int, int> best_adj = best.second.second;\n        \n        int a = best_pos.first;\n        int b = best_pos.second;\n        int x = best_adj.first;\n        int y = best_adj.second;\n        \n        vector<char> path = manhattan_move(rx, ry, x, y);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        int desired_dir = -1;\n        for (int d = 0; d < 4; d++) {\n            if (dx[d] == a - x && dy[d] == b - y) {\n                desired_dir = d;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string grab_command(2 * V_prime, '.');\n        grab_command[V_prime + 1] = 'P';\n        cout << grab_command << '\\n';\n        cout.flush();\n        S.erase({a, b});\n        \n        priority_queue<pair<int, pair<pair<int, int>, pair<int, int>>>, vector<pair<int, pair<pair<int, int>, pair<int, int>>>>, greater<pair<int, pair<pair<int, int>, pair<int, int>>>>> pq_t;\n        \n        for (const auto& target : T) {\n            int i = target.first, j = target.second;\n            for (int d = 0; d < 4; d++) {\n                int x_target = i + dx[d];\n                int y_target = j + dy[d];\n                if (x_target >= 0 && x_target < N && y_target >= 0 && y_target < N) {\n                    int dist = abs(rx - x_target) + abs(ry - y_target);\n                    pq_t.push({dist, {target, {x_target, y_target}}});\n                }\n            }\n        }\n        \n        auto best_t = pq_t.top();\n        pq_t.pop();\n        pair<int, int> best_target = best_t.second.first;\n        pair<int, int> best_adj_target = best_t.second.second;\n        \n        int c = best_target.first;\n        int d = best_target.second;\n        int x_target = best_adj_target.first;\n        int y_target = best_adj_target.second;\n        \n        path = manhattan_move(rx, ry, x_target, y_target);\n        for (char move : path) {\n            string command(2 * V_prime, '.');\n            command[0] = move;\n            cout << command << '\\n';\n            cout.flush();\n            if (move == 'R') ry++;\n            else if (move == 'L') ry--;\n            else if (move == 'U') rx--;\n            else if (move == 'D') rx++;\n        }\n        \n        desired_dir = -1;\n        for (int d_val = 0; d_val < 4; d_val++) {\n            if (dx[d_val] == c - x_target && dy[d_val] == d - y_target) {\n                desired_dir = d_val;\n                break;\n            }\n        }\n        \n        while (dir != desired_dir) {\n            int diff = (desired_dir - dir + 4) % 4;\n            char rot_cmd = (diff <= 2) ? 'R' : 'L';\n            if (rot_cmd == 'R') {\n                dir = (dir + 1) % 4;\n            } else {\n                dir = (dir + 3) % 4;\n            }\n            string command(2 * V_prime, '.');\n            command[1] = rot_cmd;\n            cout << command << '\\n';\n            cout.flush();\n        }\n        \n        string release_command(2 * V_prime, '.');\n        release_command[V_prime + 1] = 'P';\n        cout << release_command << '\\n';\n        cout.flush();\n        T.erase({c, d});\n    }\n    \n    return 0;\n}","ahc039":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <limits>\n#include <chrono>\n\nusing namespace std;\nusing namespace std::chrono;\n\nstruct Point {\n    int x, y;\n    \n    bool operator<(const Point& other) const {\n        return tie(x, y) < tie(other.x, other.y);\n    }\n    \n    bool operator==(const Point& other) const {\n        return x == other.x && y == other.y;\n    }\n};\n\nstruct Polygon {\n    vector<Point> vertices;\n    \n    void add_vertex(const Point& p) {\n        vertices.push_back(p);\n    }\n    \n    double perimeter() const {\n        double perim = 0;\n        for (int i = 0; i < vertices.size(); ++i) {\n            int j = (i + 1) % vertices.size();\n            perim += abs(vertices[i].x - vertices[j].x) + abs(vertices[i].y - vertices[j].y);\n        }\n        return perim;\n    }\n    \n    bool contains(const Point& p) const {\n        int n = vertices.size();\n        bool inside = false;\n        \n        for (int i = 0, j = n - 1; i < n; j = i++) {\n            const Point& vi = vertices[i];\n            const Point& vj = vertices[j];\n            \n            if ((vi.y == vj.y) && (p.y == vi.y) && \n                (p.x >= min(vi.x, vj.x)) && (p.x <= max(vi.x, vj.x))) {\n                return true;\n            }\n            \n            if ((vi.x == vj.x) && (p.x == vi.x) && \n                (p.y >= min(vi.y, vj.y)) && (p.y <= max(vi.y, vj.y))) {\n                return true;\n            }\n            \n            if (((vi.y > p.y) != (vj.y > p.y)) &&\n                (p.x < (vj.x - vi.x) * (p.y - vi.y) / (vj.y - vi.y) + vi.x)) {\n                inside = !inside;\n            }\n        }\n        \n        return inside;\n    }\n    \n    bool is_simple() const {\n        int n = vertices.size();\n        if (n < 3) return false;\n        \n        for (int i = 0; i < n; ++i) {\n            int j = (i + 1) % n;\n            const Point& a = vertices[i];\n            const Point& b = vertices[j];\n            \n            for (int k = i + 1; k < n; ++k) {\n                int l = (k + 1) % n;\n                if (k == j || l == i || k == i) continue;\n                \n                const Point& c = vertices[k];\n                const Point& d = vertices[l];\n                \n                if (segments_intersect(a, b, c, d)) {\n                    return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \nprivate:\n    bool segments_intersect(const Point& a, const Point& b, const Point& c, const Point& d) const {\n        if (max(a.x, b.x) < min(c.x, d.x) || max(c.x, d.x) < min(a.x, b.x)) return false;\n        if (max(a.y, b.y) < min(c.y, d.y) || max(c.y, d.y) < min(a.y, b.y)) return false;\n        \n        long long cross1 = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n        long long cross2 = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);\n        long long cross3 = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);\n        long long cross4 = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);\n        \n        if ((cross1 * cross2 < 0) && (cross3 * cross4 < 0)) return true;\n        \n        if (cross1 == 0 && on_segment(a, b, c)) return true;\n        if (cross2 == 0 && on_segment(a, b, d)) return true;\n        if (cross3 == 0 && on_segment(c, d, a)) return true;\n        if (cross4 == 0 && on_segment(c, d, b)) return true;\n        \n        return false;\n    }\n    \n    bool on_segment(const Point& a, const Point& b, const Point& c) const {\n        return c.x >= min(a.x, b.x) && c.x <= max(a.x, b.x) &&\n               c.y >= min(a.y, b.y) && c.y <= max(a.y, b.y);\n    }\n};\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N;\n    cin >> N;\n    \n    vector<Point> mackerels(N);\n    vector<Point> sardines(N);\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> mackerels[i].x >> mackerels[i].y;\n    }\n    \n    for (int i = 0; i < N; ++i) {\n        cin >> sardines[i].x >> sardines[i].y;\n    }\n    \n    const int cluster_size = 50;\n    vector<vector<Point>> mackerel_clusters;\n    vector<bool> used(N, false);\n    \n    for (int i = 0; i < N; ++i) {\n        if (!used[i]) {\n            vector<Point> cluster;\n            cluster.push_back(mackerels[i]);\n            used[i] = true;\n            \n            for (int j = i + 1; j < N && cluster.size() < cluster_size; ++j) {\n                if (!used[j]) {\n                    int dx = mackerels[i].x - mackerels[j].x;\n                    int dy = mackerels[i].y - mackerels[j].y;\n                    if (dx * dx + dy * dy < 10000 * 10000) {\n                        cluster.push_back(mackerels[j]);\n                        used[j] = true;\n                    }\n                }\n            }\n            \n            if (cluster.size() >= 10) {\n                mackerel_clusters.push_back(cluster);\n            }\n        }\n    }\n    \n    sort(mackerel_clusters.begin(), mackerel_clusters.end(), \n         [](const vector<Point>& a, const vector<Point>& b) {\n             return a.size() > b.size();\n         });\n    \n    vector<tuple<int, int, int, int>> cluster_boxes;\n    for (const auto& cluster : mackerel_clusters) {\n        int min_x = 100000, max_x = 0;\n        int min_y = 100000, max_y = 0;\n        \n        for (const auto& p : cluster) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        cluster_boxes.emplace_back(min_x, min_y, max_x, max_y);\n    }\n    \n    Polygon best_polygon;\n    int best_score = 0;\n    \n    auto calculate_score = [](const Polygon& poly, const vector<Point>& macks, const vector<Point>& sards) {\n        int a = 0, b = 0;\n        for (const auto& p : macks) {\n            if (poly.contains(p)) {\n                a++;\n            }\n        }\n        for (const auto& p : sards) {\n            if (poly.contains(p)) {\n                b++;\n            }\n        }\n        return max(0, a - b + 1);\n    };\n    \n    for (size_t i = 0; i < min(mackerel_clusters.size(), size_t(10)); ++i) {\n        const auto& box = cluster_boxes[i];\n        int min_x = get<0>(box);\n        int min_y = get<1>(box);\n        int max_x = get<2>(box);\n        int max_y = get<3>(box);\n        \n        Polygon polygon;\n        polygon.add_vertex({min_x, min_y});\n        polygon.add_vertex({max_x, min_y});\n        polygon.add_vertex({max_x, max_y});\n        polygon.add_vertex({min_x, max_y});\n        \n        const int max_expansions = 10;\n        for (int expansion = 0; expansion < max_expansions; ++expansion) {\n            vector<Polygon> expansions;\n            \n            if (polygon.vertices[0].x > 0) {\n                Polygon left_poly = polygon;\n                left_poly.vertices[0].x = max(0, left_poly.vertices[0].x - 1000);\n                left_poly.vertices[3].x = left_poly.vertices[0].x;\n                if (left_poly.is_simple()) {\n                    expansions.push_back(left_poly);\n                }\n            }\n            \n            if (polygon.vertices[1].x < 100000) {\n                Polygon right_poly = polygon;\n                right_poly.vertices[1].x = min(100000, right_poly.vertices[1].x + 1000);\n                right_poly.vertices[2].x = right_poly.vertices[1].x;\n                if (right_poly.is_simple()) {\n                    expansions.push_back(right_poly);\n                }\n            }\n            \n            if (polygon.vertices[0].y > 0) {\n                Polygon down_poly = polygon;\n                down_poly.vertices[0].y = max(0, down_poly.vertices[0].y - 1000);\n                down_poly.vertices[1].y = down_poly.vertices[0].y;\n                if (down_poly.is_simple()) {\n                    expansions.push_back(down_poly);\n                }\n            }\n            \n            if (polygon.vertices[2].y < 100000) {\n                Polygon up_poly = polygon;\n                up_poly.vertices[2].y = min(100000, up_poly.vertices[2].y + 1000);\n                up_poly.vertices[3].y = up_poly.vertices[2].y;\n                if (up_poly.is_simple()) {\n                    expansions.push_back(up_poly);\n                }\n            }\n            \n            Polygon best_expansion = polygon;\n            int best_expansion_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& exp : expansions) {\n                if (exp.perimeter() <= 400000) {\n                    int score = calculate_score(exp, mackerels, sardines);\n                    if (score > best_expansion_score) {\n                        best_expansion = exp;\n                        best_expansion_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_expansion;\n        }\n        \n        vector<Point> inside_sardines;\n        for (const auto& p : sardines) {\n            if (polygon.contains(p)) {\n                inside_sardines.push_back(p);\n            }\n        }\n        \n        if (!inside_sardines.empty()) {\n            uniform_int_distribution<int> dist(0, inside_sardines.size() - 1);\n            Point target = inside_sardines[dist(rng)];\n            \n            vector<Polygon> adjusted_polygons;\n            \n            // Try shrinking from each direction\n            if (target.x < polygon.vertices[0].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].x = max(0, new_poly.vertices[0].x - 1000);\n                new_poly.vertices[3].x = new_poly.vertices[0].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.x > polygon.vertices[1].x) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[1].x = min(100000, new_poly.vertices[1].x + 1000);\n                new_poly.vertices[2].x = new_poly.vertices[1].x;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y < polygon.vertices[0].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[0].y = max(0, new_poly.vertices[0].y - 1000);\n                new_poly.vertices[1].y = new_poly.vertices[0].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            if (target.y > polygon.vertices[2].y) {\n                Polygon new_poly = polygon;\n                new_poly.vertices[2].y = min(100000, new_poly.vertices[2].y + 1000);\n                new_poly.vertices[3].y = new_poly.vertices[2].y;\n                if (new_poly.is_simple()) {\n                    adjusted_polygons.push_back(new_poly);\n                }\n            }\n            \n            Polygon best_adjusted = polygon;\n            int best_adjusted_score = calculate_score(polygon, mackerels, sardines);\n            \n            for (const auto& adj : adjusted_polygons) {\n                if (adj.perimeter() <= 400000) {\n                    int score = calculate_score(adj, mackerels, sardines);\n                    if (score > best_adjusted_score) {\n                        best_adjusted = adj;\n                        best_adjusted_score = score;\n                    }\n                }\n            }\n            \n            polygon = best_adjusted;\n        }\n        \n        int score = calculate_score(polygon, mackerels, sardines);\n        if (score > best_score) {\n            best_score = score;\n            best_polygon = polygon;\n        }\n    }\n    \n    if (best_polygon.vertices.empty()) {\n        best_polygon.add_vertex({0, 0});\n        best_polygon.add_vertex({100000, 0});\n        best_polygon.add_vertex({100000, 100000});\n        best_polygon.add_vertex({0, 100000});\n    }\n    \n    cout << best_polygon.vertices.size() << \"\\n\";\n    for (const auto& p : best_polygon.vertices) {\n        cout << p.x << \" \" << p.y << \"\\n\";\n    }\n    \n    return 0;\n}","ahc040":"#include <iostream>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <iomanip>\n#include <cctype>\n\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n\n    int N, T, sigma;\n    cin >> N >> T >> sigma;\n\n    vector<double> w_est(N), h_est(N);\n    for (int i = 0; i < N; i++) {\n        cin >> w_est[i] >> h_est[i];\n    }\n\n    for (int turn = 0; turn < T; turn++) {\n        vector<tuple<double, double, double, double, int>> placed_rectangles;\n        double current_width = 0.0;\n        double current_height = 0.0;\n        double penalty = 0.0;\n        vector<tuple<int, int, char, int>> sequence;\n\n        for (int i = 0; i < N; i++) {\n            tuple<int, int, char, int, double, double, double, double> best_option;\n            double best_cost = 1e18;\n            bool found = false;\n\n            double cost_skip = current_width + current_height + penalty + (w_est[i] + h_est[i]);\n\n            for (int rotation : {0, 1}) {\n                double w_i = (rotation == 0) ? w_est[i] : h_est[i];\n                double h_i = (rotation == 0) ? h_est[i] : w_est[i];\n\n                for (char direction : {'U', 'L'}) {\n                    vector<int> refs = {-1};\n                    for (const auto& rect : placed_rectangles) {\n                        refs.push_back(get<4>(rect));\n                    }\n\n                    for (int ref : refs) {\n                        double x0, y0;\n                        if (direction == 'U') {\n                            if (ref == -1) {\n                                x0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                x0 = get<0>(*it) + get<2>(*it);\n                            }\n                            y0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_x, x0) < min(r_x + r_w, x0 + w_i)) {\n                                    double candidate = r_y + r_h;\n                                    if (candidate > y0) {\n                                        y0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        } else {\n                            if (ref == -1) {\n                                y0 = 0.0;\n                            } else {\n                                auto it = find_if(placed_rectangles.begin(), placed_rectangles.end(), \n                                    [ref](const tuple<double, double, double, double, int>& r) {\n                                        return get<4>(r) == ref;\n                                    });\n                                if (it == placed_rectangles.end()) continue;\n                                y0 = get<1>(*it) + get<3>(*it);\n                            }\n                            x0 = 0.0;\n                            for (const auto& rect : placed_rectangles) {\n                                double r_x = get<0>(rect), r_y = get<1>(rect), r_w = get<2>(rect), r_h = get<3>(rect);\n                                if (max(r_y, y0) < min(r_y + r_h, y0 + h_i)) {\n                                    double candidate = r_x + r_w;\n                                    if (candidate > x0) {\n                                        x0 = candidate;\n                                    }\n                                }\n                            }\n                            double new_width = max(current_width, x0 + w_i);\n                            double new_height = max(current_height, y0 + h_i);\n                            double cost_place = new_width + new_height + penalty;\n                            if (cost_place < best_cost) {\n                                best_cost = cost_place;\n                                best_option = make_tuple(i, rotation, direction, ref, x0, y0, w_i, h_i);\n                                found = true;\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (found && best_cost < cost_skip) {\n                auto [i_opt, rot_opt, dir_opt, ref_opt, x0_opt, y0_opt, w_i_opt, h_i_opt] = best_option;\n                current_width = max(current_width, x0_opt + w_i_opt);\n                current_height = max(current_height, y0_opt + h_i_opt);\n                placed_rectangles.emplace_back(x0_opt, y0_opt, w_i_opt, h_i_opt, i_opt);\n                sequence.emplace_back(i_opt, rot_opt, dir_opt, ref_opt);\n            } else {\n                penalty += (w_est[i] + h_est[i]);\n            }\n        }\n\n        cout << sequence.size() << '\\n';\n        for (const auto& [i, rot, dir, ref] : sequence) {\n            cout << i << ' ' << rot << ' ' << dir << ' ' << ref << '\\n';\n        }\n        cout << flush;\n\n        if (turn < T - 1) {\n            int W_prime, H_prime;\n            cin >> W_prime >> H_prime;\n\n            double width_factor = 1.0;\n            if (current_width > 0) {\n                width_factor = static_cast<double>(W_prime) / current_width;\n            }\n            double height_factor = 1.0;\n            if (current_height > 0) {\n                height_factor = static_cast<double>(H_prime) / current_height;\n            }\n\n            double alpha = 0.2;\n            width_factor = 1.0 + alpha * (width_factor - 1.0);\n            height_factor = 1.0 + alpha * (height_factor - 1.0);\n\n            for (const auto& rect : placed_rectangles) {\n                int idx = get<4>(rect);\n                w_est[idx] *= width_factor;\n                h_est[idx] *= height_factor;\n                w_est[idx] = max(1.0, min(1e9, w_est[idx]));\n                h_est[idx] = max(1.0, min(1e9, h_est[idx]));\n            }\n        }\n    }\n\n    return 0;\n}","ahc041":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <random>\n#include <cmath>\n#include <unordered_set>\n\nusing namespace std;\n\nstruct Vertex {\n    int id;\n    int x, y;\n    int beauty;\n    vector<int> neighbors;\n    int parent;\n    int height;\n    int root;\n};\n\nint H;  // Global height limit\nvector<vector<bool>> is_adjacent;  // Adjacency matrix for O(1) edge checks\n\n// Function to calculate attractiveness of a solution\nlong long calculate_attractiveness(const vector<Vertex>& vertices) {\n    long long attractiveness = 0;\n    for (const auto& v : vertices) {\n        attractiveness += (long long)(v.height + 1) * v.beauty;\n    }\n    return attractiveness;\n}\n\n// Function to update heights after changing a parent\nvoid update_heights(vector<Vertex>& vertices, int v) {\n    if (vertices[v].parent == -1) {\n        vertices[v].height = 0;\n        vertices[v].root = v;\n    } else {\n        vertices[v].height = vertices[vertices[v].parent].height + 1;\n        vertices[v].root = vertices[vertices[v].parent].root;\n    }\n    \n    // Recursively update children\n    for (int u : vertices[v].neighbors) {\n        if (vertices[u].parent == v) {\n            update_heights(vertices, u);\n        }\n    }\n}\n\n// Function to check if a parent assignment is valid (height <= H and edge exists)\nbool is_valid_parent(const vector<Vertex>& vertices, int v, int parent) {\n    if (parent == -1) return true;\n    if (vertices[parent].height >= H) return false;\n    return is_adjacent[v][parent];\n}\n\n// Function to check if u is a descendant of v\nbool is_descendant(const vector<Vertex>& vertices, int u, int v) {\n    int current = u;\n    while (current != -1) {\n        if (current == v) {\n            return true;\n        }\n        current = vertices[current].parent;\n    }\n    return false;\n}\n\n// Function to calculate Euclidean distance between two vertices\ndouble distance(const Vertex& a, const Vertex& b) {\n    double dx = a.x - b.x;\n    double dy = a.y - b.y;\n    return sqrt(dx * dx + dy * dy);\n}\n\n// Function to find the best parent for a vertex\nint find_best_parent(const vector<Vertex>& vertices, int v, const vector<bool>& is_root) {\n    int best_parent = -1;\n    long long best_gain = 0;\n    \n    // Consider neighbors that are roots or from different trees\n    for (int u : vertices[v].neighbors) {\n        if (is_root[u] || vertices[u].root != vertices[v].root) {\n            if (is_valid_parent(vertices, v, u)) {\n                // Calculate the gain in attractiveness if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                // Prefer parents that allow for deeper nesting in the future\n                if (new_height < H) {\n                    gain += vertices[v].beauty / 2;  // Bonus for potential future gains\n                }\n                \n                // Add a spatial component: prefer closer parents\n                double dist = distance(vertices[v], vertices[u]);\n                double spatial_factor = 1.0 / (1.0 + dist / 100.0);  // Normalize distance\n                gain = (long long)(gain * spatial_factor);\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n    }\n    \n    return best_parent;\n}\n\n// Function to perform local search\nvoid local_search(vector<Vertex>& vertices, const vector<vector<int>>& adj, int max_iterations) {\n    random_device rd;\n    mt19937 gen(rd());\n    uniform_int_distribution<int> vertex_dist(0, vertices.size() - 1);\n    \n    long long current_attractiveness = calculate_attractiveness(vertices);\n    vector<bool> is_root(vertices.size(), false);\n    for (const auto& v : vertices) {\n        if (v.parent == -1) {\n            is_root[v.id] = true;\n        }\n    }\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        int v = vertex_dist(gen);\n        \n        // Try to find a better parent for v\n        int current_parent = vertices[v].parent;\n        int best_parent = current_parent;\n        long long best_gain = 0;\n        \n        for (int u : adj[v]) {\n            if (u != current_parent && vertices[u].parent != v && \n                !is_descendant(vertices, u, v) &&  // Avoid creating cycles\n                is_valid_parent(vertices, v, u)) {\n                \n                // Calculate the gain if v becomes a child of u\n                int new_height = vertices[u].height + 1;\n                long long gain = (long long)(new_height + 1) * vertices[v].beauty - \n                                (long long)(vertices[v].height + 1) * vertices[v].beauty;\n                \n                if (gain > best_gain) {\n                    best_gain = gain;\n                    best_parent = u;\n                }\n            }\n        }\n        \n        // If we found a better parent, update the solution\n        if (best_parent != current_parent && best_gain > 0) {\n            // Remove v from its current parent's children\n            if (current_parent != -1) {\n                // No need to explicitly remove, just update parent pointer\n            }\n            \n            // Add v to its new parent\n            vertices[v].parent = best_parent;\n            update_heights(vertices, v);\n            \n            // Update root status\n            if (current_parent == -1) {\n                is_root[v] = false;\n            }\n            if (best_parent == -1) {\n                is_root[v] = true;\n            }\n            \n            current_attractiveness += best_gain;\n        }\n        \n        // Occasionally try to make a vertex a root\n        if (iter % 100 == 0 && vertices[v].parent != -1) {\n            // Check if all children of v are actually adjacent to v\n            bool all_children_adjacent = true;\n            for (int u : adj[v]) {\n                if (vertices[u].parent == v && !is_adjacent[v][u]) {\n                    all_children_adjacent = false;\n                    break;\n                }\n            }\n            \n            if (all_children_adjacent) {\n                int old_parent = vertices[v].parent;\n                vertices[v].parent = -1;\n                update_heights(vertices, v);\n                \n                long long new_attractiveness = calculate_attractiveness(vertices);\n                if (new_attractiveness > current_attractiveness) {\n                    current_attractiveness = new_attractiveness;\n                    is_root[v] = true;\n                } else {\n                    // Revert the change\n                    vertices[v].parent = old_parent;\n                    update_heights(vertices, v);\n                }\n            }\n        }\n    }\n}\n\n// Function to validate the solution\nbool validate_solution(const vector<Vertex>& vertices, const vector<vector<int>>& adj) {\n    // Check that all parent-child relationships correspond to edges in the graph\n    for (const auto& v : vertices) {\n        if (v.parent != -1) {\n            if (!is_adjacent[v.id][v.parent]) {\n                return false;\n            }\n        }\n    }\n    \n    // Check that there are no cycles\n    for (const auto& v : vertices) {\n        unordered_set<int> visited;\n        int current = v.id;\n        while (current != -1) {\n            if (visited.count(current)) {\n                return false;  // Cycle detected\n            }\n            visited.insert(current);\n            current = vertices[current].parent;\n        }\n    }\n    \n    // Check height constraints\n    for (const auto& v : vertices) {\n        if (v.height > H) {\n            return false;\n        }\n    }\n    \n    return true;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M >> H;\n    \n    is_adjacent.assign(N, vector<bool>(N, false));\n    \n    vector<Vertex> vertices(N);\n    for (int i = 0; i < N; i++) {\n        vertices[i].id = i;\n        cin >> vertices[i].beauty;\n    }\n    \n    vector<vector<int>> adj(N);\n    for (int i = 0; i < M; i++) {\n        int u, v;\n        cin >> u >> v;\n        adj[u].push_back(v);\n        adj[v].push_back(u);\n        vertices[u].neighbors.push_back(v);\n        vertices[v].neighbors.push_back(u);\n        is_adjacent[u][v] = true;\n        is_adjacent[v][u] = true;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].x >> vertices[i].y;\n    }\n    \n    // Initialize with each vertex as its own tree\n    for (auto& v : vertices) {\n        v.parent = -1;\n        v.height = 0;\n        v.root = v.id;\n    }\n    \n    // Sort vertices by beauty (higher beauty first) to prioritize them\n    vector<int> vertex_ids(N);\n    for (int i = 0; i < N; i++) {\n        vertex_ids[i] = i;\n    }\n    sort(vertex_ids.begin(), vertex_ids.end(), [&](int a, int b) {\n        return vertices[a].beauty > vertices[b].beauty;\n    });\n    \n    // Greedily assign parents\n    vector<bool> is_root(N, true);\n    for (int v : vertex_ids) {\n        // Only try to assign parents to vertices that can gain from having a parent\n        if (vertices[v].beauty > 20) {  // Lower threshold for more assignments\n            int best_parent = find_best_parent(vertices, v, is_root);\n            if (best_parent != -1) {\n                vertices[v].parent = best_parent;\n                is_root[v] = false;\n                update_heights(vertices, v);\n            }\n        }\n    }\n    \n    // Perform local search with more iterations\n    local_search(vertices, adj, 50000);  // Increased iterations for better results\n    \n    // Final validation\n    if (!validate_solution(vertices, adj)) {\n        // If validation fails, reset to a safe solution (each vertex as root)\n        for (auto& v : vertices) {\n            v.parent = -1;\n            v.height = 0;\n            v.root = v.id;\n        }\n    }\n    \n    // Output the solution\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertices[i].parent;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc042":"#include <iostream>\n#include <vector>\n#include <string>\n#include <climits>\n\nusing namespace std;\n\nconst int N = 20;\n\nint main() {\n    vector<string> grid(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n\n    vector<pair<char, int>> moves;\n    int top = 0, bottom = N - 1;\n    int left = 0, right = N - 1;\n\n    while (top <= bottom && left <= right) {\n        // Process top row\n        bool has_fuku = false;\n        for (int j = left; j <= right; j++) {\n            if (grid[top][j] == 'o') {\n                has_fuku = true;\n                break;\n            }\n        }\n        if (!has_fuku) {\n            int rightmost_x = -1;\n            for (int j = left; j <= right; j++) {\n                if (grid[top][j] == 'x') {\n                    rightmost_x = max(rightmost_x, j);\n                }\n            }\n            if (rightmost_x != -1) {\n                int shifts = rightmost_x + 1;\n                for (int s = 0; s < shifts; s++) {\n                    moves.push_back({'L', top});\n                    for (int j = left; j < right; j++) {\n                        grid[top][j] = grid[top][j + 1];\n                    }\n                    grid[top][right] = '.';\n                }\n            }\n        } else {\n            for (int j = left; j <= right; j++) {\n                if (grid[top][j] == 'x') {\n                    moves.push_back({'U', j});\n                    for (int i = top; i < bottom; i++) {\n                        grid[i][j] = grid[i + 1][j];\n                    }\n                    grid[bottom][j] = '.';\n                }\n            }\n        }\n        top++;\n\n        // Process bottom row\n        has_fuku = false;\n        for (int j = left; j <= right; j++) {\n            if (grid[bottom][j] == 'o') {\n                has_fuku = true;\n                break;\n            }\n        }\n        if (!has_fuku) {\n            int leftmost_x = N;\n            for (int j = left; j <= right; j++) {\n                if (grid[bottom][j] == 'x') {\n                    leftmost_x = min(leftmost_x, j);\n                }\n            }\n            if (leftmost_x != N) {\n                int shifts = N - leftmost_x;\n                for (int s = 0; s < shifts; s++) {\n                    moves.push_back({'R', bottom});\n                    for (int j = right; j > left; j--) {\n                        grid[bottom][j] = grid[bottom][j - 1];\n                    }\n                    grid[bottom][left] = '.';\n                }\n            }\n        } else {\n            for (int j = left; j <= right; j++) {\n                if (grid[bottom][j] == 'x') {\n                    moves.push_back({'D', j});\n                    for (int i = bottom; i > top; i--) {\n                        grid[i][j] = grid[i - 1][j];\n                    }\n                    grid[top][j] = '.';\n                }\n            }\n        }\n        bottom--;\n\n        // Process left column\n        has_fuku = false;\n        for (int i = top; i <= bottom; i++) {\n            if (grid[i][left] == 'o') {\n                has_fuku = true;\n                break;\n            }\n        }\n        if (!has_fuku) {\n            int bottommost_x = -1;\n            for (int i = top; i <= bottom; i++) {\n                if (grid[i][left] == 'x') {\n                    bottommost_x = max(bottommost_x, i);\n                }\n            }\n            if (bottommost_x != -1) {\n                int shifts = bottommost_x + 1;\n                for (int s = 0; s < shifts; s++) {\n                    moves.push_back({'U', left});\n                    for (int i = top; i < bottom; i++) {\n                        grid[i][left] = grid[i + 1][left];\n                    }\n                    grid[bottom][left] = '.';\n                }\n            }\n        } else {\n            for (int i = top; i <= bottom; i++) {\n                if (grid[i][left] == 'x') {\n                    moves.push_back({'L', i});\n                    for (int j = left; j < right; j++) {\n                        grid[i][j] = grid[i][j + 1];\n                    }\n                    grid[i][right] = '.';\n                }\n            }\n        }\n        left++;\n\n        // Process right column\n        has_fuku = false;\n        for (int i = top; i <= bottom; i++) {\n            if (grid[i][right] == 'o') {\n                has_fuku = true;\n                break;\n            }\n        }\n        if (!has_fuku) {\n            int topmost_x = N;\n            for (int i = top; i <= bottom; i++) {\n                if (grid[i][right] == 'x') {\n                    topmost_x = min(topmost_x, i);\n                }\n            }\n            if (topmost_x != N) {\n                int shifts = N - topmost_x;\n                for (int s = 0; s < shifts; s++) {\n                    moves.push_back({'D', right});\n                    for (int i = bottom; i > top; i--) {\n                        grid[i][right] = grid[i - 1][right];\n                    }\n                    grid[top][right] = '.';\n                }\n            }\n        } else {\n            for (int i = top; i <= bottom; i++) {\n                if (grid[i][right] == 'x') {\n                    moves.push_back({'R', i});\n                    for (int j = right; j > left; j--) {\n                        grid[i][j] = grid[i][j - 1];\n                    }\n                    grid[i][left] = '.';\n                }\n            }\n        }\n        right--;\n    }\n\n    for (auto move : moves) {\n        cout << move.first << \" \" << move.second << endl;\n    }\n\n    return 0;\n}","ahc044":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cstdlib>\n#include <cmath>\n#include <ctime>\n#include <random>\n\nusing namespace std;\n\nint main() {\n    srand(0);\n    int N = 100;\n    int L = 500000;\n    vector<long long> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n\n    vector<int> a(N), b(N);\n    for (int i = 0; i < N; i++) {\n        vector<pair<long long, int>> candidates;\n        for (int j = 0; j < N; j++) {\n            if (j == i) continue;\n            candidates.push_back({T[j], j});\n        }\n        sort(candidates.begin(), candidates.end(), greater<pair<long long, int>>());\n        if (candidates.size() >= 2) {\n            a[i] = candidates[0].second;\n            b[i] = candidates[1].second;\n        } else if (candidates.size() == 1) {\n            a[i] = candidates[0].second;\n            b[i] = i;\n        } else {\n            a[i] = i;\n            b[i] = i;\n        }\n    }\n\n    auto simulate = [&](const vector<int>& a_vec, const vector<int>& b_vec) {\n        vector<long long> count(N, 0);\n        int current = 0;\n        count[0] = 1;\n        for (int week = 1; week < L; week++) {\n            int next;\n            if (count[current] & 1) {\n                next = a_vec[current];\n            } else {\n                next = b_vec[current];\n            }\n            count[next]++;\n            current = next;\n        }\n        long long error = 0;\n        for (int i = 0; i < N; i++) {\n            error += abs(count[i] - T[i]);\n        }\n        return error;\n    };\n\n    long long best_error = simulate(a, b);\n    vector<int> best_a = a;\n    vector<int> best_b = b;\n\n    for (int iter = 0; iter < 100; iter++) {\n        int i = rand() % N;\n        int old_a = a[i];\n        int old_b = b[i];\n\n        a[i] = rand() % N;\n        b[i] = rand() % N;\n\n        long long new_error = simulate(a, b);\n        if (new_error < best_error) {\n            best_error = new_error;\n            best_a = a;\n            best_b = b;\n        } else {\n            a[i] = old_a;\n            b[i] = old_b;\n        }\n    }\n\n    for (int i = 0; i < N; i++) {\n        cout << best_a[i] << \" \" << best_b[i] << endl;\n    }\n\n    return 0;\n}","ahc045":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <set>\n#include <map>\n#include <queue>\n#include <tuple>\n#include <random>\n#include <chrono>\n#include <iomanip>\n#include <sstream>\n#include <cassert>\n#include <numeric>\n\nusing namespace std;\n\nstruct City {\n    int id;\n    double cx, cy;  // estimated center coordinates\n    int lx, rx, ly, ry;  // given rectangle bounds\n    double uncertainty;  // size of the rectangle, representing uncertainty\n};\n\nstruct Edge {\n    int u, v;\n    int weight;  // estimated or actual weight\n    double estimated_dist;  // estimated distance based on center coordinates\n    \n    bool operator<(const Edge& other) const {\n        if (weight != other.weight) return weight < other.weight;\n        if (u != other.u) return u < other.u;\n        return v < other.v;\n    }\n};\n\nstruct QueryResult {\n    vector<pair<int, int>> edges;  // edges in the MST\n};\n\nclass Solution {\npublic:\n    int N, M, Q, L, W;\n    vector<int> G;\n    vector<City> cities;\n    vector<vector<int>> groups;\n    vector<vector<Edge>> group_edges;\n    int query_count = 0;\n    \n    void read_input() {\n        cin >> N >> M >> Q >> L >> W;\n        G.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> G[i];\n        }\n        \n        cities.resize(N);\n        for (int i = 0; i < N; i++) {\n            cities[i].id = i;\n            cin >> cities[i].lx >> cities[i].rx >> cities[i].ly >> cities[i].ry;\n            cities[i].cx = (cities[i].lx + cities[i].rx) / 2.0;\n            cities[i].cy = (cities[i].ly + cities[i].ry) / 2.0;\n            // Calculate uncertainty as the diagonal of the rectangle\n            cities[i].uncertainty = sqrt(pow(cities[i].rx - cities[i].lx, 2) + \n                                        pow(cities[i].ry - cities[i].ly, 2));\n        }\n    }\n    \n    double estimated_distance(int i, int j) {\n        double dx = cities[i].cx - cities[j].cx;\n        double dy = cities[i].cy - cities[j].cy;\n        return sqrt(dx * dx + dy * dy);\n    }\n    \n    void group_cities() {\n        // Sort cities by their estimated center coordinates\n        vector<int> city_ids(N);\n        for (int i = 0; i < N; i++) {\n            city_ids[i] = i;\n        }\n        \n        // We'll use a simple approach: divide the sorted list into groups of the required sizes\n        sort(city_ids.begin(), city_ids.end(), [this](int a, int b) {\n            if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n            return cities[a].cy < cities[b].cy;\n        });\n        \n        // Divide into groups of specified sizes\n        groups.resize(M);\n        int start_idx = 0;\n        for (int i = 0; i < M; i++) {\n            groups[i].resize(G[i]);\n            for (int j = 0; j < G[i]; j++) {\n                groups[i][j] = city_ids[start_idx + j];\n            }\n            start_idx += G[i];\n        }\n    }\n    \n    QueryResult query_mst(const vector<int>& city_subset) {\n        assert(city_subset.size() >= 2 && city_subset.size() <= L);\n        assert(query_count < Q);\n        \n        cout << \"? \" << city_subset.size();\n        for (int city : city_subset) {\n            cout << \" \" << city;\n        }\n        cout << endl;\n        cout.flush();\n        \n        QueryResult result;\n        result.edges.resize(city_subset.size() - 1);\n        for (int i = 0; i < city_subset.size() - 1; i++) {\n            cin >> result.edges[i].first >> result.edges[i].second;\n            if (result.edges[i].first > result.edges[i].second) {\n                swap(result.edges[i].first, result.edges[i].second);\n            }\n        }\n        \n        query_count++;\n        return result;\n    }\n    \n    void gather_mst_info() {\n        group_edges.resize(M);\n        \n        for (int i = 0; i < M; i++) {\n            // For each group, perform queries to gather MST information\n            int group_size = G[i];\n            \n            // If the group is small enough, query the entire group at once\n            if (group_size <= L) {\n                vector<int> subset = groups[i];\n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n                continue;\n            }\n            \n            // For larger groups, we'll use a more sophisticated approach\n            // First, sort cities within the group by their estimated positions\n            vector<int> sorted_group = groups[i];\n            sort(sorted_group.begin(), sorted_group.end(), [this](int a, int b) {\n                if (cities[a].cx != cities[b].cx) return cities[a].cx < cities[b].cx;\n                return cities[a].cy < cities[b].cy;\n            });\n            \n            // We'll create a list of potential edges, sorted by estimated distance\n            vector<pair<double, pair<int, int>>> potential_edges;\n            for (int u = 0; u < group_size; u++) {\n                for (int v = u + 1; v < group_size; v++) {\n                    double dist = estimated_distance(sorted_group[u], sorted_group[v]);\n                    potential_edges.emplace_back(dist, make_pair(u, v));\n                }\n            }\n            \n            sort(potential_edges.begin(), potential_edges.end());\n            \n            // We'll select subsets for querying based on the shortest potential edges\n            set<int> selected_cities;\n            vector<vector<int>> subsets;\n            \n            // Start with the cities connected by the shortest edges\n            for (const auto& [dist, edge] : potential_edges) {\n                if (query_count >= Q) break;\n                \n                int u = edge.first;\n                int v = edge.second;\n                \n                // If both cities are already in a subset, skip\n                if (selected_cities.count(u) && selected_cities.count(v)) continue;\n                \n                // Create a new subset containing these cities and some nearby ones\n                vector<int> subset;\n                subset.push_back(sorted_group[u]);\n                subset.push_back(sorted_group[v]);\n                selected_cities.insert(u);\n                selected_cities.insert(v);\n                \n                // Add nearby cities until we reach the maximum subset size\n                for (const auto& [dist2, edge2] : potential_edges) {\n                    if (subset.size() >= L) break;\n                    \n                    int u2 = edge2.first;\n                    int v2 = edge2.second;\n                    \n                    if (u2 == u || u2 == v || v2 == u || v2 == v) {\n                        int new_city = (selected_cities.count(u2) == 0) ? u2 : v2;\n                        if (selected_cities.count(new_city) == 0) {\n                            subset.push_back(sorted_group[new_city]);\n                            selected_cities.insert(new_city);\n                        }\n                    }\n                }\n                \n                subsets.push_back(subset);\n                \n                // If we've selected all cities, we're done\n                if (selected_cities.size() >= group_size) break;\n            }\n            \n            // If we haven't selected all cities, add the remaining ones\n            for (int j = 0; j < group_size; j++) {\n                if (selected_cities.count(j) == 0) {\n                    // Create a subset with this city and some nearby ones\n                    vector<int> subset;\n                    subset.push_back(sorted_group[j]);\n                    selected_cities.insert(j);\n                    \n                    // Add the closest cities\n                    for (const auto& [dist, edge] : potential_edges) {\n                        if (subset.size() >= L) break;\n                        \n                        int u = edge.first;\n                        int v = edge.second;\n                        \n                        if (u == j || v == j) {\n                            int other = (u == j) ? v : u;\n                            if (selected_cities.count(other) == 0) {\n                                subset.push_back(sorted_group[other]);\n                                selected_cities.insert(other);\n                            }\n                        }\n                    }\n                    \n                    subsets.push_back(subset);\n                }\n            }\n            \n            // Query each subset\n            for (const auto& subset : subsets) {\n                if (query_count >= Q) break;\n                if (subset.size() < 2) continue;\n                \n                QueryResult result = query_mst(subset);\n                \n                // Add the edges to our collection\n                for (const auto& edge : result.edges) {\n                    Edge e;\n                    e.u = edge.first;\n                    e.v = edge.second;\n                    e.weight = 0;\n                    e.estimated_dist = estimated_distance(e.u, e.v);\n                    group_edges[i].push_back(e);\n                }\n            }\n            \n            if (query_count >= Q) break;  // We've used all our queries\n        }\n    }\n    \n    void construct_final_msts() {\n        // For each group, we'll use the edges we've gathered to construct a connected graph\n        // If we don't have enough edges to form a spanning tree, we'll add more\n        \n        for (int i = 0; i < M; i++) {\n            // We need G[i] - 1 edges to connect G[i] cities\n            \n            // First, let's create a graph from the edges we've gathered\n            vector<vector<int>> graph(G[i]);\n            map<pair<int, int>, int> edge_to_index;\n            \n            for (int j = 0; j < group_edges[i].size(); j++) {\n                const Edge& e = group_edges[i][j];\n                int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                \n                graph[u_idx].push_back(v_idx);\n                graph[v_idx].push_back(u_idx);\n                \n                edge_to_index[{min(u_idx, v_idx), max(u_idx, v_idx)}] = j;\n            }\n            \n            // Check if the graph is connected\n            vector<bool> visited(G[i], false);\n            queue<int> q;\n            q.push(0);\n            visited[0] = true;\n            int visited_count = 1;\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                for (int v : graph[u]) {\n                    if (!visited[v]) {\n                        visited[v] = true;\n                        visited_count++;\n                        q.push(v);\n                    }\n                }\n            }\n            \n            if (visited_count == G[i]) {\n                // The graph is already connected, so we can use a subset of the edges\n                // We'll use Kruskal's algorithm to find the MST\n                vector<Edge> mst_edges;\n                vector<int> parent(G[i]);\n                for (int j = 0; j < G[i]; j++) {\n                    parent[j] = j;\n                }\n                \n                function<int(int)> find = [&](int x) {\n                    if (parent[x] != x) {\n                        parent[x] = find(parent[x]);\n                    }\n                    return parent[x];\n                };\n                \n                auto unite = [&](int x, int y) {\n                    x = find(x);\n                    y = find(y);\n                    if (x != y) {\n                        parent[x] = y;\n                        return true;\n                    }\n                    return false;\n                };\n                \n                // Sort edges by estimated distance\n                sort(group_edges[i].begin(), group_edges[i].end(), \n                    [](const Edge& a, const Edge& b) {\n                        return a.estimated_dist < b.estimated_dist;\n                    });\n                \n                for (const Edge& e : group_edges[i]) {\n                    int u_idx = find(groups[i].begin(), groups[i].end(), e.u) - groups[i].begin();\n                    int v_idx = find(groups[i].begin(), groups[i].end(), e.v) - groups[i].begin();\n                    \n                    if (unite(u_idx, v_idx)) {\n                        mst_edges.push_back(e);\n                        if (mst_edges.size() == G[i] - 1) break;\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            } else {\n                // The graph is not connected, so we need to add more edges\n                // We'll use Prim's algorithm starting from the visited component\n                \n                // First, let's create a complete graph with estimated distances\n                vector<vector<pair<int, double>>> complete_graph(G[i]);\n                for (int u = 0; u < G[i]; u++) {\n                    for (int v = u + 1; v < G[i]; v++) {\n                        double dist = estimated_distance(groups[i][u], groups[i][v]);\n                        complete_graph[u].emplace_back(v, dist);\n                        complete_graph[v].emplace_back(u, dist);\n                    }\n                }\n                \n                // Use Prim's algorithm to find the MST\n                vector<bool> in_mst(G[i], false);\n                vector<Edge> mst_edges;\n                priority_queue<pair<double, pair<int, int>>, \n                              vector<pair<double, pair<int, int>>>, \n                              greater<pair<double, pair<int, int>>>> pq;\n                \n                // Start with the visited component\n                for (int u = 0; u < G[i]; u++) {\n                    if (visited[u]) {\n                        in_mst[u] = true;\n                        for (const auto& [v, dist] : complete_graph[u]) {\n                            if (!in_mst[v]) {\n                                pq.emplace(dist, make_pair(u, v));\n                            }\n                        }\n                    }\n                }\n                \n                while (!pq.empty() && mst_edges.size() < G[i] - 1) {\n                    auto [dist, edge] = pq.top();\n                    pq.pop();\n                    int u = edge.first;\n                    int v = edge.second;\n                    \n                    if (!in_mst[v]) {\n                        in_mst[v] = true;\n                        Edge e;\n                        e.u = groups[i][u];\n                        e.v = groups[i][v];\n                        e.weight = 0;\n                        e.estimated_dist = dist;\n                        mst_edges.push_back(e);\n                        \n                        for (const auto& [next_v, next_dist] : complete_graph[v]) {\n                            if (!in_mst[next_v]) {\n                                pq.emplace(next_dist, make_pair(v, next_v));\n                            }\n                        }\n                    }\n                }\n                \n                group_edges[i] = mst_edges;\n            }\n        }\n    }\n    \n    void output_solution() {\n        cout << \"!\" << endl;\n        \n        for (int i = 0; i < M; i++) {\n            // Output the cities in the group\n            for (int j = 0; j < G[i]; j++) {\n                if (j > 0) cout << \" \";\n                cout << groups[i][j];\n            }\n            cout << endl;\n            \n            // Output the edges\n            for (const auto& edge : group_edges[i]) {\n                cout << edge.u << \" \" << edge.v << endl;\n            }\n        }\n        cout.flush();\n    }\n    \n    void solve() {\n        read_input();\n        group_cities();\n        gather_mst_info();\n        construct_final_msts();\n        output_solution();\n    }\n};\n\nint main() {\n    Solution solution;\n    solution.solve();\n    return 0;\n}","ahc046":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <array>\n#include <string>\n#include <utility>\n#include <atcoder/all>\n\nusing namespace std;\nusing namespace atcoder;\n\nconst int N = 20;\nconst int M = 40;\nconst int MAX_ACTIONS = 2 * N * M;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dir_chars[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    vector<vector<bool>> blocks;\n    vector<string> actions;\n    int remaining_actions;\n    \n    State(int i, int j, int budget = MAX_ACTIONS) : i(i), j(j), blocks(N, vector<bool>(N, false)), remaining_actions(budget) {}\n    \n    bool is_valid(int ni, int nj) const {\n        return ni >= 0 && ni < N && nj >= 0 && nj < N;\n    }\n    \n    bool can_move(int dir) const {\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        return is_valid(ni, nj) && !blocks[ni][nj];\n    }\n    \n    State move(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        new_state.i += di[dir];\n        new_state.j += dj[dir];\n        new_state.actions.push_back(string(1, 'M') + dir_chars[dir]);\n        new_state.remaining_actions--;\n        return new_state;\n    }\n    \n    pair<State, int> slide(int dir) const {\n        if (remaining_actions <= 0) return {*this, 0};\n        State new_state = *this;\n        int ni = i, nj = j;\n        int steps = 0;\n        \n        while (true) {\n            int nni = ni + di[dir];\n            int nnj = nj + dj[dir];\n            \n            if (!is_valid(nni, nnj) || blocks[nni][nnj]) {\n                break;\n            }\n            \n            ni = nni;\n            nj = nnj;\n            steps++;\n        }\n        \n        if (steps > 0) {\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.actions.push_back(string(1, 'S') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return {new_state, steps};\n    }\n    \n    State alter(int dir) const {\n        if (remaining_actions <= 0) return *this;\n        State new_state = *this;\n        int ni = i + di[dir];\n        int nj = j + dj[dir];\n        \n        if (is_valid(ni, nj)) {\n            new_state.blocks[ni][nj] = !blocks[ni][nj];\n            new_state.actions.push_back(string(1, 'A') + dir_chars[dir]);\n            new_state.remaining_actions--;\n        }\n        \n        return new_state;\n    }\n    \n    int manhattan_distance(int ti, int tj) const {\n        return abs(i - ti) + abs(j - tj);\n    }\n    \n    vector<string> find_path(int target_i, int target_j) const {\n        if (remaining_actions <= 0) return vector<string>();\n        \n        queue<tuple<int, int, vector<string>>> q;\n        vector<vector<bool>> visited(N, vector<bool>(N, false));\n        vector<vector<pair<int, int>>> parent(N, vector<pair<int, int>>(N, {-1, -1}));\n        \n        q.push({i, j, vector<string>()});\n        visited[i][j] = true;\n        \n        while (!q.empty()) {\n            auto [ci, cj, path] = q.front();\n            q.pop();\n            \n            if (ci == target_i && cj == target_j) {\n                vector<string> result;\n                while (ci != i || cj != j) {\n                    auto [pi, pj] = parent[ci][cj];\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (pi + di[dir] == ci && pj + dj[dir] == cj) {\n                            result.push_back(string(1, 'M') + dir_chars[dir]);\n                            break;\n                        }\n                    }\n                    ci = pi;\n                    cj = pj;\n                }\n                reverse(result.begin(), result.end());\n                return result;\n            }\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int ni = ci + di[dir];\n                int nj = cj + dj[dir];\n                \n                if (ni >= 0 && ni < N && nj >= 0 && nj < N && !visited[ni][nj] && !blocks[ni][nj]) {\n                    visited[ni][nj] = true;\n                    parent[ni][nj] = {ci, cj};\n                    vector<string> new_path = path;\n                    new_path.push_back(string(1, 'M') + dir_chars[dir]);\n                    q.push({ni, nj, new_path});\n                }\n            }\n        }\n        \n        return vector<string>();\n    }\n    \n    bool try_slide_to_target(int target_i, int target_j) {\n        if (remaining_actions < 10) return false; // Not enough actions for sliding\n        \n        int initial_manhattan = manhattan_distance(target_i, target_j);\n        vector<pair<int, int>> directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\n        \n        // Try all directions as primary\n        for (int primary_dir = 0; primary_dir < 4; primary_dir++) {\n            State temp_state = *this;\n            \n            // Slide in primary direction\n            auto [slide_state, slide_steps] = temp_state.slide(primary_dir);\n            temp_state = slide_state;\n            \n            if (temp_state.manhattan_distance(target_i, target_j) >= initial_manhattan) {\n                continue; // No improvement\n            }\n            \n            // Try to place a block to stop at target\n            for (int stop_dir = 0; stop_dir < 4; stop_dir++) {\n                if (stop_dir == primary_dir || stop_dir == (primary_dir ^ 1)) {\n                    continue; // Same or opposite direction\n                }\n                \n                State temp_state2 = temp_state;\n                \n                // Calculate where to place the stopping block\n                int stop_i = target_i + di[stop_dir];\n                int stop_j = target_j + dj[stop_dir];\n                \n                if (temp_state2.is_valid(stop_i, stop_j)) {\n                    // Try to place block if not already there\n                    if (!temp_state2.blocks[stop_i][stop_j]) {\n                        temp_state2 = temp_state2.alter(stop_dir);\n                        \n                        // Try sliding to target\n                        auto [slide_result, steps] = temp_state2.slide(stop_dir);\n                        if (slide_result.i == target_i && slide_result.j == target_j) {\n                            *this = slide_result;\n                            return true;\n                        }\n                        \n                        // If slide didn't reach target, try moving from there\n                        auto path = slide_result.find_path(target_i, target_j);\n                        if (!path.empty() && path.size() <= 5) {\n                            for (const auto& action : path) {\n                                for (int dir = 0; dir < 4; dir++) {\n                                    if (action[1] == dir_chars[dir]) {\n                                        slide_result = slide_result.move(dir);\n                                        break;\n                                    }\n                                }\n                            }\n                            \n                            if (slide_result.i == target_i && slide_result.j == target_j) {\n                                *this = slide_result;\n                                return true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        return false;\n    }\n    \n    void remove_unnecessary_blocks(const vector<pair<int, int>>& future_targets) {\n        // Remove blocks that are not needed for future targets\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (blocks[i][j]) {\n                    bool needed = false;\n                    \n                    // Check if block is near any future target\n                    for (const auto& target : future_targets) {\n                        if (abs(i - target.first) <= 2 && abs(j - target.second) <= 2) {\n                            needed = true;\n                            break;\n                        }\n                    }\n                    \n                    if (!needed) {\n                        // Remove the block\n                        for (int dir = 0; dir < 4; dir++) {\n                            if (i - di[dir] == this->i && j - dj[dir] == this->j) {\n                                *this = alter(dir);\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    void optimize_blocks(const vector<pair<int, int>>& targets, int current_target_idx) {\n        // Only optimize if we have enough actions\n        if (remaining_actions < 50) return;\n        \n        vector<pair<int, int>> future_targets(targets.begin() + current_target_idx + 1, \n                                            targets.begin() + min(current_target_idx + 6, (int)targets.size()));\n        \n        // Remove unnecessary blocks first\n        remove_unnecessary_blocks(future_targets);\n        \n        // Place blocks for future targets only if beneficial\n        for (const auto& target : future_targets) {\n            int target_i = target.first;\n            int target_j = target.second;\n            \n            // Only place blocks if we're far from the target\n            if (manhattan_distance(target_i, target_j) > 5) {\n                // Try to place a block that will help slide to this target\n                for (int dir = 0; dir < 4; dir++) {\n                    int block_i = target_i + di[dir];\n                    int block_j = target_j + dj[dir];\n                    \n                    if (is_valid(block_i, block_j) && !blocks[block_i][block_j]) {\n                        // Check if placing this block would create a good sliding opportunity\n                        int path_cost = manhattan_distance(block_i, block_j) + 2; // Move to adjacent + alter\n                        if (path_cost < manhattan_distance(target_i, target_j) * 0.7) {\n                            auto path = find_path(block_i, block_j);\n                            if (!path.empty() && path.size() <= 5) {\n                                for (const auto& action : path) {\n                                    for (int d = 0; d < 4; d++) {\n                                        if (action[1] == dir_chars[d]) {\n                                            *this = move(d);\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                *this = alter(dir);\n                                break; // Only place one block per target\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int n, m;\n    cin >> n >> m;\n    \n    vector<pair<int, int>> targets(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].first >> targets[i].second;\n    }\n    \n    State current(targets[0].first, targets[0].second);\n    \n    for (int k = 1; k < m; k++) {\n        int target_i = targets[k].first;\n        int target_j = targets[k].second;\n        \n        // If we're running low on actions, use BFS only\n        if (current.remaining_actions < 100) {\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n            continue;\n        }\n        \n        int manhattan = current.manhattan_distance(target_i, target_j);\n        \n        // Try sliding for medium to long distances\n        if (manhattan > 3 && current.try_slide_to_target(target_i, target_j)) {\n            // Sliding succeeded, continue\n        } else {\n            // Use BFS for short distances or when sliding fails\n            auto path = current.find_path(target_i, target_j);\n            for (const auto& action : path) {\n                for (int dir = 0; dir < 4; dir++) {\n                    if (action[1] == dir_chars[dir]) {\n                        current = current.move(dir);\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Optimize blocks for future targets\n        current.optimize_blocks(targets, k);\n    }\n    \n    for (const auto& action : current.actions) {\n        cout << action[0] << \" \" << action[1] << '\\n';\n    }\n    \n    return 0;\n}"}}}