{"model_name":"claude-4.1-opus","codes":{"1":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <set>\n\nusing namespace std;\n\nstruct Company {\n    int id;\n    int x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d;\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(double px, double py) const {\n        return a < px && px < c && b < py && py < 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\nclass Solver {\nprivate:\n    int n;\n    vector<Company> companies;\n    vector<Rectangle> solution;\n    mt19937 rng;\n    \n    double calculate_satisfaction(int i) {\n        const auto& comp = companies[i];\n        const auto& rect = solution[i];\n        \n        if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) {\n            return 0.0;\n        }\n        \n        int s = rect.area();\n        if (s == 0) return 0.0;\n        \n        double ratio = min(comp.r, s) / (double)max(comp.r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool check_overlaps(const Rectangle& rect, int exclude_id = -1) {\n        for (int i = 0; i < n; i++) {\n            if (i == exclude_id) continue;\n            if (solution[i].area() > 0 && solution[i].overlaps(rect)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    Rectangle find_best_rectangle(int idx, int max_attempts = 100) {\n        const auto& comp = companies[idx];\n        int target_area = comp.r;\n        \n        Rectangle best_rect = {comp.x, comp.y, min(10000, comp.x + 1), min(10000, comp.y + 1)};\n        double best_score = 0;\n        \n        // Try to find rectangle with area close to target\n        int sqrt_area = sqrt(target_area);\n        \n        for (int attempt = 0; attempt < max_attempts; attempt++) {\n            int w, h;\n            \n            if (attempt < max_attempts / 2) {\n                // Try systematic sizes\n                double aspect_ratio = 1.0 + (attempt % 10) * 0.2;\n                w = sqrt(target_area * aspect_ratio);\n                h = target_area / max(1, w);\n            } else {\n                // Try random sizes\n                w = max(1, min(10000, (int)(sqrt_area * (0.5 + (rng() % 100) / 50.0))));\n                h = target_area / max(1, w);\n            }\n            \n            w = max(1, min(10000, w));\n            h = max(1, min(10000, h));\n            \n            // Try different positions that include the required point\n            for (int dx = 0; dx <= min(w - 1, comp.x); dx++) {\n                for (int dy = 0; dy <= min(h - 1, comp.y); dy++) {\n                    int a = comp.x - dx;\n                    int b = comp.y - dy;\n                    int c = min(10000, a + w);\n                    int d = min(10000, b + h);\n                    \n                    Rectangle rect = {a, b, c, d};\n                    \n                    if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) continue;\n                    if (check_overlaps(rect, idx)) continue;\n                    \n                    int area = rect.area();\n                    double ratio = min(target_area, area) / (double)max(target_area, area);\n                    double score = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_rect = rect;\n                        if (score > 0.99) return best_rect;  // Good enough\n                    }\n                }\n            }\n        }\n        \n        return best_rect;\n    }\n    \n    void greedy_placement() {\n        // Sort companies by area (largest first)\n        vector<int> order(n);\n        for (int i = 0; i < n; i++) order[i] = i;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return companies[i].r > companies[j].r;\n        });\n        \n        // Initialize all rectangles to empty\n        for (int i = 0; i < n; i++) {\n            solution[i] = {0, 0, 0, 0};\n        }\n        \n        // Place rectangles greedily\n        for (int idx : order) {\n            solution[idx] = find_best_rectangle(idx);\n        }\n    }\n    \n    void local_optimization(int iterations) {\n        double total_score = 0;\n        for (int i = 0; i < n; i++) {\n            total_score += calculate_satisfaction(i);\n        }\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            int idx = rng() % n;\n            Rectangle old_rect = solution[idx];\n            \n            // Try to adjust the rectangle\n            Rectangle new_rect = old_rect;\n            int type = rng() % 8;\n            \n            switch(type) {\n                case 0: if (new_rect.a > 0) new_rect.a--; break;\n                case 1: if (new_rect.b > 0) new_rect.b--; break;\n                case 2: if (new_rect.c < 10000) new_rect.c++; break;\n                case 3: if (new_rect.d < 10000) new_rect.d++; break;\n                case 4: if (new_rect.a < new_rect.c - 1 && new_rect.a < companies[idx].x) new_rect.a++; break;\n                case 5: if (new_rect.b < new_rect.d - 1 && new_rect.b < companies[idx].y) new_rect.b++; break;\n                case 6: if (new_rect.c > new_rect.a + 1 && new_rect.c > companies[idx].x + 1) new_rect.c--; break;\n                case 7: if (new_rect.d > new_rect.b + 1 && new_rect.d > companies[idx].y + 1) new_rect.d--; break;\n            }\n            \n            // Check validity\n            if (!new_rect.contains(companies[idx].x + 0.5, companies[idx].y + 0.5)) continue;\n            if (check_overlaps(new_rect, idx)) continue;\n            \n            // Calculate score change\n            solution[idx] = new_rect;\n            double new_total = 0;\n            for (int i = 0; i < n; i++) {\n                new_total += calculate_satisfaction(i);\n            }\n            \n            if (new_total > total_score) {\n                total_score = new_total;\n            } else {\n                solution[idx] = old_rect;\n            }\n        }\n    }\n    \npublic:\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void solve() {\n        cin >> n;\n        companies.resize(n);\n        solution.resize(n);\n        \n        for (int i = 0; i < n; i++) {\n            companies[i].id = i;\n            cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        }\n        \n        greedy_placement();\n        \n        // Local optimization with time limit\n        auto start_time = chrono::steady_clock::now();\n        const auto time_limit = chrono::milliseconds(4500);\n        \n        while (chrono::steady_clock::now() - start_time < time_limit) {\n            local_optimization(100);\n        }\n    }\n    \n    void output() {\n        for (const auto& rect : solution) {\n            cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    solver.output();\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500;\n\nint si, sj;\nint tile[N][N];\nint points[N][N];\nvector<pair<int,int>> tile_squares[MAX_TILES];\nint tile_value[MAX_TILES];\nset<int> tile_neighbors[MAX_TILES];\nint num_tiles;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n};\n\nvoid preprocess() {\n    num_tiles = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n            tile_squares[tile[i][j]].push_back({i, j});\n        }\n    }\n    \n    // Calculate tile values\n    for (int t = 0; t < num_tiles; t++) {\n        tile_value[t] = 0;\n        for (auto [i, j] : tile_squares[t]) {\n            tile_value[t] += points[i][j];\n        }\n    }\n    \n    // Find neighboring tiles\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int curr = tile[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int next = tile[ni][nj];\n                    if (next != curr) {\n                        tile_neighbors[curr].insert(next);\n                    }\n                }\n            }\n        }\n    }\n}\n\nState greedy_walk(double randomness = 0.0) {\n    State state;\n    state.i = si;\n    state.j = sj;\n    state.score = points[si][sj];\n    state.visited[tile[si][sj]] = true;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    while (true) {\n        vector<tuple<int, int, int, int>> candidates; // score, ni, nj, dir\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            int score = tile_value[next_tile];\n            \n            // Add lookahead bonus\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!state.visited[neighbor]) {\n                    score += tile_value[neighbor] / 4;\n                }\n            }\n            \n            candidates.push_back({score, ni, nj, d});\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Choose with some randomness\n        int choice = 0;\n        if (randomness > 0 && dis(gen) < randomness && candidates.size() > 1) {\n            choice = min(1, (int)candidates.size() - 1);\n        }\n        \n        auto [score, ni, nj, dir] = candidates[choice];\n        \n        state.i = ni;\n        state.j = nj;\n        state.path += dir_char[dir];\n        state.score += points[ni][nj];\n        state.visited[tile[ni][nj]] = true;\n    }\n    \n    return state;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess();\n    \n    State best;\n    best.score = 0;\n    \n    // Try multiple strategies\n    auto start = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count();\n        if (elapsed > 1900) break;\n        \n        // Pure greedy\n        State s1 = greedy_walk(0.0);\n        if (s1.score > best.score) best = s1;\n        \n        // With some randomness\n        State s2 = greedy_walk(0.3);\n        if (s2.score > best.score) best = s2;\n        \n        State s3 = greedy_walk(0.5);\n        if (s3.score > best.score) best = s3;\n    }\n    \n    cout << best.path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int QUERIES = 1000;\nconst double INF = 1e9;\n\ndouble h_weight[N][N-1]; // horizontal edges\ndouble v_weight[N-1][N]; // vertical edges\nint h_count[N][N-1];\nint v_count[N-1][N];\n\nstruct State {\n    double dist;\n    int i, j;\n    bool operator<(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\nstruct EdgeInfo {\n    int type; // 0 for vertical, 1 for horizontal\n    int i, j;\n};\n\npair<string, vector<EdgeInfo>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<State> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, si, sj});\n    \n    while (!pq.empty()) {\n        State cur = pq.top();\n        pq.pop();\n        \n        int i = cur.i, j = cur.j;\n        double d = cur.dist;\n        \n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        // Try all 4 directions\n        // Up\n        if (i > 0) {\n            double nd = dist[i][j] + v_weight[i-1][j];\n            if (nd < dist[i-1][j]) {\n                dist[i-1][j] = nd;\n                parent[i-1][j] = {i, j};\n                pq.push({nd, i-1, j});\n            }\n        }\n        // Down\n        if (i < N-1) {\n            double nd = dist[i][j] + v_weight[i][j];\n            if (nd < dist[i+1][j]) {\n                dist[i+1][j] = nd;\n                parent[i+1][j] = {i, j};\n                pq.push({nd, i+1, j});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double nd = dist[i][j] + h_weight[i][j-1];\n            if (nd < dist[i][j-1]) {\n                dist[i][j-1] = nd;\n                parent[i][j-1] = {i, j};\n                pq.push({nd, i, j-1});\n            }\n        }\n        // Right\n        if (j < N-1) {\n            double nd = dist[i][j] + h_weight[i][j];\n            if (nd < dist[i][j+1]) {\n                dist[i][j+1] = nd;\n                parent[i][j+1] = {i, j};\n                pq.push({nd, i, j+1});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<EdgeInfo> edges;\n    string path = \"\";\n    int ci = ti, cj = tj;\n    \n    while (!(ci == si && cj == sj)) {\n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (pi == ci - 1) {\n            path += 'D';\n            edges.push_back({0, ci-1, cj});\n        } else if (pi == ci + 1) {\n            path += 'U';\n            edges.push_back({0, ci, cj});\n        } else if (pj == cj - 1) {\n            path += 'R';\n            edges.push_back({1, ci, cj-1});\n        } else if (pj == cj + 1) {\n            path += 'L';\n            edges.push_back({1, ci, cj});\n        }\n        ci = pi;\n        cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(edges.begin(), edges.end());\n    \n    return {path, edges};\n}\n\nvoid update_weights(const vector<EdgeInfo>& edges, int actual_length) {\n    if (edges.empty()) return;\n    \n    double total_estimated = 0;\n    for (const auto& e : edges) {\n        if (e.type == 0) {\n            total_estimated += v_weight[e.i][e.j];\n        } else {\n            total_estimated += h_weight[e.i][e.j];\n        }\n    }\n    \n    if (total_estimated <= 0) return;\n    \n    double ratio = (double)actual_length / total_estimated;\n    \n    // Update each edge weight with adaptive learning rate\n    for (const auto& e : edges) {\n        if (e.type == 0) {\n            int cnt = v_count[e.i][e.j];\n            double lr = 0.3 / (1.0 + cnt * 0.1);\n            v_weight[e.i][e.j] = v_weight[e.i][e.j] * (1 - lr) + v_weight[e.i][e.j] * ratio * lr;\n            v_count[e.i][e.j]++;\n        } else {\n            int cnt = h_count[e.i][e.j];\n            double lr = 0.3 / (1.0 + cnt * 0.1);\n            h_weight[e.i][e.j] = h_weight[e.i][e.j] * (1 - lr) + h_weight[e.i][e.j] * ratio * lr;\n            h_count[e.i][e.j]++;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Initialize weights to expected average\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N-1; j++) {\n            h_weight[i][j] = 5000;\n            h_count[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N-1; i++) {\n        for (int j = 0; j < N; j++) {\n            v_weight[i][j] = 5000;\n            v_count[i][j] = 0;\n        }\n    }\n    \n    for (int k = 0; k < QUERIES; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto result = dijkstra(si, sj, ti, tj);\n        string path = result.first;\n        vector<EdgeInfo> edges = result.second;\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int actual_length;\n        cin >> actual_length;\n        \n        update_weights(edges, actual_length);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\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<string> strings(m);\n    for (int i = 0; i < m; i++) {\n        cin >> strings[i];\n    }\n    \n    // Grid with possible characters for each cell\n    vector<vector<set<char>>> possible(n, vector<set<char>>(n));\n    vector<vector<char>> grid(n, vector<char>(n, '.'));\n    \n    // Initialize all cells with all possible characters\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            for (char c = 'A'; c <= 'H'; c++) {\n                possible[i][j].insert(c);\n            }\n        }\n    }\n    \n    // Function to check if string matches at position (horizontal)\n    auto matchesHorizontal = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int col = (c + i) % n;\n            if (grid[r][col] != '.' && grid[r][col] != s[i]) {\n                return false;\n            }\n            if (!possible[r][col].count(s[i])) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    // Function to check if string matches at position (vertical)\n    auto matchesVertical = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int row = (r + i) % n;\n            if (grid[row][c] != '.' && grid[row][c] != s[i]) {\n                return false;\n            }\n            if (!possible[row][c].count(s[i])) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    // Apply constraints from a string\n    auto applyHorizontal = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int col = (c + i) % n;\n            possible[r][col].clear();\n            possible[r][col].insert(s[i]);\n            grid[r][col] = s[i];\n        }\n    };\n    \n    auto applyVertical = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int row = (r + i) % n;\n            possible[row][c].clear();\n            possible[row][c].insert(s[i]);\n            grid[row][c] = s[i];\n        }\n    };\n    \n    // Count how many positions a string can be placed\n    auto countPlacements = [&](const string& s) {\n        int cnt = 0;\n        for (int r = 0; r < n; r++) {\n            for (int c = 0; c < n; c++) {\n                if (matchesHorizontal(r, c, s)) cnt++;\n                if (matchesVertical(r, c, s)) cnt++;\n            }\n        }\n        return cnt;\n    };\n    \n    // Process strings iteratively\n    vector<bool> placed(m, false);\n    bool changed = true;\n    \n    while (changed) {\n        changed = false;\n        \n        // Find strings with unique or few placements\n        for (int idx = 0; idx < m; idx++) {\n            if (placed[idx]) continue;\n            \n            const string& s = strings[idx];\n            vector<tuple<int, int, int>> validPositions; // r, c, dir (0=h, 1=v)\n            \n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (matchesHorizontal(r, c, s)) {\n                        validPositions.push_back({r, c, 0});\n                    }\n                    if (matchesVertical(r, c, s)) {\n                        validPositions.push_back({r, c, 1});\n                    }\n                }\n            }\n            \n            // If only one valid position, place it\n            if (validPositions.size() == 1) {\n                auto [r, c, dir] = validPositions[0];\n                if (dir == 0) {\n                    applyHorizontal(r, c, s);\n                } else {\n                    applyVertical(r, c, s);\n                }\n                placed[idx] = true;\n                changed = true;\n            }\n            // If few positions, try to place without conflicts\n            else if (validPositions.size() > 0 && validPositions.size() <= 3) {\n                auto [r, c, dir] = validPositions[0];\n                if (dir == 0) {\n                    applyHorizontal(r, c, s);\n                } else {\n                    applyVertical(r, c, s);\n                }\n                placed[idx] = true;\n                changed = true;\n            }\n        }\n    }\n    \n    // Place remaining strings greedily\n    for (int idx = 0; idx < m; idx++) {\n        if (placed[idx]) continue;\n        \n        const string& s = strings[idx];\n        \n        // Try to find a good position\n        for (int r = 0; r < n; r++) {\n            for (int c = 0; c < n; c++) {\n                if (matchesHorizontal(r, c, s)) {\n                    applyHorizontal(r, c, s);\n                    placed[idx] = true;\n                    goto next_string;\n                }\n                if (matchesVertical(r, c, s)) {\n                    applyVertical(r, c, s);\n                    placed[idx] = true;\n                    goto next_string;\n                }\n            }\n        }\n        next_string:;\n    }\n    \n    // For any remaining dots, choose the most constrained value\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (grid[i][j] == '.') {\n                if (possible[i][j].size() == 1) {\n                    grid[i][j] = *possible[i][j].begin();\n                } else if (!possible[i][j].empty()) {\n                    // Choose most frequent character in strings\n                    map<char, int> freq;\n                    for (const auto& s : strings) {\n                        for (char c : s) {\n                            freq[c]++;\n                        }\n                    }\n                    char best = 'A';\n                    int maxFreq = 0;\n                    for (char c : possible[i][j]) {\n                        if (freq[c] > maxFreq) {\n                            maxFreq = freq[c];\n                            best = c;\n                        }\n                    }\n                    grid[i][j] = best;\n                } else {\n                    grid[i][j] = 'A';\n                }\n            }\n        }\n    }\n    \n    // Output the grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nset<pair<int,int>> compute_visible(int i, int j) {\n    set<pair<int,int>> visible;\n    if (!is_road(i, j)) return visible;\n    \n    visible.insert({i, j});\n    \n    // Horizontal\n    for (int jj = j - 1; jj >= 0 && is_road(i, jj); jj--) {\n        visible.insert({i, jj});\n    }\n    for (int jj = j + 1; jj < N && is_road(i, jj); jj++) {\n        visible.insert({i, jj});\n    }\n    \n    // Vertical\n    for (int ii = i - 1; ii >= 0 && is_road(ii, j); ii--) {\n        visible.insert({ii, j});\n    }\n    for (int ii = i + 1; ii < N && is_road(ii, j); ii++) {\n        visible.insert({ii, j});\n    }\n    \n    return visible;\n}\n\npair<int, string> dijkstra(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return {0, \"\"};\n    \n    priority_queue<tuple<int, int, int, string>, vector<tuple<int, int, int, string>>, greater<>> pq;\n    map<pair<int,int>, int> dist;\n    \n    pq.push({0, si, sj, \"\"});\n    dist[{si, sj}] = 0;\n    \n    int di[] = {-1, 1, 0, 0};\n    int dj[] = {0, 0, -1, 1};\n    char dir[] = {'U', 'D', 'L', 'R'};\n    \n    while (!pq.empty()) {\n        auto [d, i, j, path] = pq.top();\n        pq.pop();\n        \n        if (i == ei && j == ej) return {d, path};\n        \n        if (dist.count({i, j}) && dist[{i, j}] < d) continue;\n        \n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k];\n            int nj = j + dj[k];\n            \n            if (is_road(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (!dist.count({ni, nj}) || dist[{ni, nj}] > nd) {\n                    dist[{ni, nj}] = nd;\n                    pq.push({nd, ni, nj, path + dir[k]});\n                }\n            }\n        }\n    }\n    \n    return {1e9, \"\"};\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    set<pair<int,int>> all_roads;\n    map<pair<int,int>, set<pair<int,int>>> visibility;\n    \n    // Find all roads and precompute visibility\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j)) {\n                all_roads.insert({i, j});\n                visibility[{i, j}] = compute_visible(i, j);\n            }\n        }\n    }\n    \n    // Build route using greedy approach\n    string route = \"\";\n    int ci = si, cj = sj;\n    set<pair<int,int>> covered;\n    \n    // Mark initially visible squares\n    for (auto p : visibility[{ci, cj}]) {\n        covered.insert(p);\n    }\n    \n    // Key positions to consider (subset for efficiency)\n    vector<pair<int,int>> candidates;\n    for (int i = 0; i < N; i += 2) {\n        for (int j = 0; j < N; j += 2) {\n            if (is_road(i, j)) {\n                candidates.push_back({i, j});\n            }\n        }\n    }\n    \n    while (covered.size() < all_roads.size()) {\n        int best_i = -1, best_j = -1;\n        double best_score = -1;\n        string best_path;\n        int best_dist = 1e9;\n        \n        for (auto [i, j] : candidates) {\n            if (i == ci && j == cj) continue;\n            \n            int new_vis = 0;\n            for (auto p : visibility[{i, j}]) {\n                if (!covered.count(p)) new_vis++;\n            }\n            \n            if (new_vis == 0) continue;\n            \n            auto [dist, path] = dijkstra(ci, cj, i, j);\n            if (dist >= 1e9) continue;\n            \n            double score = (double)new_vis / (dist + 1);\n            \n            if (score > best_score) {\n                best_score = score;\n                best_i = i;\n                best_j = j;\n                best_path = path;\n                best_dist = dist;\n            }\n        }\n        \n        if (best_i == -1) {\n            // Try all roads if candidates didn't work\n            for (auto [i, j] : all_roads) {\n                if (i == ci && j == cj) continue;\n                \n                int new_vis = 0;\n                for (auto p : visibility[{i, j}]) {\n                    if (!covered.count(p)) new_vis++;\n                }\n                \n                if (new_vis == 0) continue;\n                \n                auto [dist, path] = dijkstra(ci, cj, i, j);\n                if (dist >= 1e9) continue;\n                \n                if (best_i == -1 || dist < best_dist) {\n                    best_i = i;\n                    best_j = j;\n                    best_path = path;\n                    best_dist = dist;\n                }\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        route += best_path;\n        ci = best_i;\n        cj = best_j;\n        \n        for (auto p : visibility[{ci, cj}]) {\n            covered.insert(p);\n        }\n    }\n    \n    // Return to start\n    auto [dist, path] = dijkstra(ci, cj, si, sj);\n    route += path;\n    \n    cout << route << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, 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>> dependents(N);\n    vector<vector<int>> dependencies(N);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        dependents[u].push_back(v);\n        dependencies[v].push_back(u);\n    }\n    \n    // Calculate how many tasks each task blocks (transitively)\n    vector<int> blocking_score(N, 0);\n    vector<bool> visited(N, false);\n    function<int(int)> dfs = [&](int task) -> int {\n        if (visited[task]) return blocking_score[task];\n        visited[task] = true;\n        int score = dependents[task].size();\n        for (int dep : dependents[task]) {\n            score += dfs(dep);\n        }\n        blocking_score[task] = score;\n        return score;\n    };\n    \n    for (int i = 0; i < N; i++) {\n        if (!visited[i]) dfs(i);\n    }\n    \n    // Initialize skill estimates (optimistic start)\n    vector<vector<double>> skill_est(M, vector<double>(K, 35.0));\n    vector<int> completed_count(M, 0);\n    \n    vector<int> task_state(N, -1);  // -1: not started, 0: in progress, 1: done\n    vector<int> member_task(M, -1); // -1: idle, else task ID\n    vector<int> start_day(M, 0);\n    \n    int day = 0;\n    int completed = 0;\n    \n    while (completed < N && day < 2000) {\n        day++;\n        \n        // Find available tasks\n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (task_state[i] == -1) {\n                bool ready = true;\n                for (int dep : dependencies[i]) {\n                    if (task_state[dep] != 1) {\n                        ready = false;\n                        break;\n                    }\n                }\n                if (ready) available.push_back(i);\n            }\n        }\n        \n        // Sort by priority (blocking score + difficulty)\n        sort(available.begin(), available.end(), [&](int a, int b) {\n            int sum_a = accumulate(d[a].begin(), d[a].end(), 0);\n            int sum_b = accumulate(d[b].begin(), d[b].end(), 0);\n            double priority_a = blocking_score[a] * 10.0 + sum_a;\n            double priority_b = blocking_score[b] * 10.0 + sum_b;\n            return priority_a > priority_b;\n        });\n        \n        // Assign tasks to idle members\n        vector<pair<int, int>> assignments;\n        set<int> used_members;\n        \n        for (int task : available) {\n            if (assignments.size() >= M) break;\n            \n            // Find best member for this task\n            int best_member = -1;\n            double best_score = 1e9;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1 || used_members.count(m)) continue;\n                \n                // Calculate expected w\n                double w = 0;\n                for (int k = 0; k < K; k++) {\n                    w += max(0.0, d[task][k] - skill_est[m][k]);\n                }\n                \n                // Add exploration bonus for less-known members\n                double score = w;\n                if (completed_count[m] < 10) {\n                    score -= (10 - completed_count[m]) * 2;\n                }\n                \n                if (best_member == -1 || score < best_score) {\n                    best_member = m;\n                    best_score = score;\n                }\n            }\n            \n            if (best_member != -1) {\n                assignments.push_back({best_member, task});\n                used_members.insert(best_member);\n                member_task[best_member] = task;\n                start_day[best_member] = day;\n                task_state[task] = 0;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [m, t] : assignments) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        // Read completions\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) break;\n        \n        for (int i = 0; i < n_completed; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int task = member_task[m];\n            if (task != -1) {\n                task_state[task] = 1;\n                completed++;\n                \n                int actual_days = day - start_day[m] + 1;\n                \n                // Update skill estimates\n                double lr = 0.5 / (1 + completed_count[m] * 0.05);\n                \n                if (actual_days == 1) {\n                    // w = 0, so skills >= requirements\n                    for (int k = 0; k < K; k++) {\n                        skill_est[m][k] = max(skill_est[m][k], (double)d[task][k]);\n                    }\n                } else {\n                    // w \u2248 actual_days (with \u00b13 noise)\n                    double estimated_w = actual_days;\n                    double current_w = 0;\n                    for (int k = 0; k < K; k++) {\n                        current_w += max(0.0, d[task][k] - skill_est[m][k]);\n                    }\n                    \n                    if (current_w > 0) {\n                        double ratio = estimated_w / current_w;\n                        for (int k = 0; k < K; k++) {\n                            double gap = max(0.0, d[task][k] - skill_est[m][k]);\n                            if (gap > 0) {\n                                skill_est[m][k] += (1 - ratio) * gap * lr;\n                                skill_est[m][k] = max(0.0, skill_est[m][k]);\n                            }\n                        }\n                    }\n                }\n                \n                completed_count[m]++;\n                member_task[m] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n    double score;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    vector<Order> orders(1000);\n    \n    // Read all orders\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        orders[i].id = i + 1;\n        \n        // Score based on proximity to center and delivery distance\n        int dist_from_center_pickup = manhattan(400, 400, orders[i].ax, orders[i].ay);\n        int dist_from_center_delivery = manhattan(400, 400, orders[i].cx, orders[i].cy);\n        int delivery_dist = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n        \n        // Prefer orders close to center with reasonable delivery distances\n        orders[i].score = dist_from_center_pickup + dist_from_center_delivery + delivery_dist * 0.3;\n    }\n    \n    // Sort orders by score (lower is better)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    \n    // Select the best 50 orders\n    vector<int> selected_ids;\n    vector<pair<int, int>> pickups, deliveries;\n    \n    for (int i = 0; i < 50; i++) {\n        selected_ids.push_back(orders[i].id);\n        pickups.push_back({orders[i].ax, orders[i].ay});\n        deliveries.push_back({orders[i].cx, orders[i].cy});\n    }\n    \n    // Build route using greedy approach with preference for clearing deliveries\n    vector<pair<int, int>> route;\n    route.push_back({400, 400});\n    \n    vector<bool> picked(50, false);\n    vector<bool> delivered(50, false);\n    int num_delivered = 0;\n    \n    while (num_delivered < 50) {\n        int cur_x = route.back().first;\n        int cur_y = route.back().second;\n        \n        int best_dist = INT_MAX;\n        int best_idx = -1;\n        bool best_is_pickup = false;\n        \n        // Count how many items we're currently carrying\n        int carrying = 0;\n        for (int i = 0; i < 50; i++) {\n            if (picked[i] && !delivered[i]) carrying++;\n        }\n        \n        // If carrying many items, prioritize deliveries\n        double delivery_weight = (carrying > 10) ? 0.7 : 1.0;\n        \n        // Consider pickups\n        for (int i = 0; i < 50; i++) {\n            if (picked[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, pickups[i].first, pickups[i].second);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = i;\n                best_is_pickup = true;\n            }\n        }\n        \n        // Consider deliveries for items we're carrying\n        for (int i = 0; i < 50; i++) {\n            if (!picked[i] || delivered[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, deliveries[i].first, deliveries[i].second);\n            int weighted_dist = dist * delivery_weight;\n            \n            if (weighted_dist < best_dist) {\n                best_dist = weighted_dist;\n                best_idx = i;\n                best_is_pickup = false;\n            }\n        }\n        \n        if (best_is_pickup) {\n            route.push_back(pickups[best_idx]);\n            picked[best_idx] = true;\n        } else {\n            route.push_back(deliveries[best_idx]);\n            delivered[best_idx] = true;\n            num_delivered++;\n        }\n    }\n    \n    // Return to office\n    route.push_back({400, 400});\n    \n    // Output\n    cout << \"50\";\n    for (int id : selected_ids) {\n        cout << \" \" << id;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        \n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n    \n    int getComponents() {\n        return components;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const 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<pair<int, int>> edges(M);\n    vector<int> distances(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n        int dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        int dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        distances[i] = round(sqrt(dx * dx + dy * dy));\n    }\n    \n    UnionFind uf(N);\n    \n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n        \n        int u = edges[i].first;\n        int v = edges[i].second;\n        int d_i = distances[i];\n        \n        int decision = 0;\n        \n        if (!uf.connected(u, v)) {\n            // Edge connects different components\n            // Be selective based on edge quality and progress\n            double ratio = (double)l_i / d_i;\n            double progress = (double)i / M;\n            \n            // Start selective, become less selective as we progress\n            double threshold = 1.8 + progress * 0.7;\n            \n            if (ratio <= threshold) {\n                decision = 1;\n                uf.unite(u, v);\n            } else if (i > M * 0.85 && uf.getComponents() > 1) {\n                // Near the end - accept to ensure connectivity\n                decision = 1;\n                uf.unite(u, v);\n            }\n        }\n        // Reject edges that would create cycles\n        \n        cout << decision << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <cmath>\n#include <random>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Position& other) const {\n        return x < other.x || (x == other.x && y < other.y);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> walls;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dirChar[4] = {'U', 'D', 'L', 'R'};\n    const char blockChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) const {\n        return x >= 1 && x <= GRID_SIZE && y >= 1 && y <= GRID_SIZE;\n    }\n    \n    bool canMakeWall(int x, int y) const {\n        if (!isValid(x, y) || walls[x][y]) return false;\n        \n        // Check no pets or humans at this position\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return false;\n        }\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        // Check no pets adjacent to this position\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny)) {\n                for (const auto& p : petPos) {\n                    if (p.x == nx && p.y == ny) return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    double distanceToNearestPet(int x, int y) const {\n        double minDist = 1e9;\n        for (const auto& p : petPos) {\n            double dist = abs(p.x - x) + abs(p.y - y);\n            minDist = min(minDist, dist);\n        }\n        return minDist;\n    }\n    \n    Position findCenterTarget() const {\n        // Find a good target position for humans to gather\n        // Try to find a corner or edge area away from pets\n        \n        Position best = {15, 15};\n        double bestScore = -1e9;\n        \n        // Check corners and edges\n        vector<Position> candidates = {\n            {5, 5}, {5, 25}, {25, 5}, {25, 25},\n            {15, 5}, {15, 25}, {5, 15}, {25, 15},\n            {15, 15}\n        };\n        \n        for (const auto& pos : candidates) {\n            double score = 0;\n            // Prefer positions far from pets\n            for (const auto& p : petPos) {\n                score += abs(p.x - pos.x) + abs(p.y - pos.y);\n            }\n            // Prefer positions close to humans\n            for (const auto& h : humanPos) {\n                score -= 0.5 * (abs(h.x - pos.x) + abs(h.y - pos.y));\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                best = pos;\n            }\n        }\n        \n        return best;\n    }\n    \npublic:\n    void solve() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n        }\n        \n        walls.assign(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        \n        for (int turn = 0; turn < MAX_TURNS; turn++) {\n            string actions(M, '.');\n            Position target = findCenterTarget();\n            \n            for (int i = 0; i < M; i++) {\n                Position& human = humanPos[i];\n                \n                // Phase 1: Early game - gather humans\n                if (turn < 80) {\n                    // Move towards target if far\n                    int dist = abs(human.x - target.x) + abs(human.y - target.y);\n                    if (dist > 5) {\n                        int bestDir = -1;\n                        int minDist = dist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                int newDist = abs(nx - target.x) + abs(ny - target.y);\n                                if (newDist < minDist) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                            continue;\n                        }\n                    }\n                }\n                \n                // Phase 2: Build walls\n                // Try to build walls between humans and pets\n                int bestWallDir = -1;\n                double bestWallScore = -1e9;\n                \n                for (int d = 0; d < 4; d++) {\n                    int wx = human.x + dx[d];\n                    int wy = human.y + dy[d];\n                    \n                    if (canMakeWall(wx, wy)) {\n                        double score = 0;\n                        \n                        // Prefer walls that separate from pets\n                        double petDist = distanceToNearestPet(wx, wy);\n                        score += petDist;\n                        \n                        // Prefer walls on the perimeter of human area\n                        int humansNearby = 0;\n                        for (const auto& h : humanPos) {\n                            if (abs(h.x - wx) + abs(h.y - wy) <= 3) {\n                                humansNearby++;\n                            }\n                        }\n                        score -= humansNearby * 2;\n                        \n                        // Build connected walls\n                        int wallsNearby = 0;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nwx = wx + dx[dd];\n                            int nwy = wy + dy[dd];\n                            if (isValid(nwx, nwy) && walls[nwx][nwy]) {\n                                wallsNearby++;\n                            }\n                        }\n                        score += wallsNearby * 5;\n                        \n                        if (score > bestWallScore) {\n                            bestWallScore = score;\n                            bestWallDir = d;\n                        }\n                    }\n                }\n                \n                if (bestWallDir != -1 && bestWallScore > 0) {\n                    actions[i] = blockChar[bestWallDir];\n                } else if (turn >= 80) {\n                    // Late game: try to move away from pets if too close\n                    double minPetDist = distanceToNearestPet(human.x, human.y);\n                    if (minPetDist < 4) {\n                        int bestDir = -1;\n                        double maxDist = minPetDist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                double newDist = distanceToNearestPet(nx, ny);\n                                if (newDist > maxDist) {\n                                    maxDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                        }\n                    }\n                }\n            }\n            \n            cout << actions << endl;\n            cout.flush();\n            \n            // Apply human actions\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                Position& human = humanPos[i];\n                \n                if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    // Movement\n                    for (int d = 0; d < 4; d++) {\n                        if (dirChar[d] == action) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                human.x = nx;\n                                human.y = ny;\n                            }\n                            break;\n                        }\n                    }\n                } else if (action != '.') {\n                    // Wall building\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            if (canMakeWall(wx, wy)) {\n                                walls[wx][wy] = true;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Read pet movements\n            for (int i = 0; i < N; i++) {\n                string petMove;\n                cin >> petMove;\n                \n                for (char c : petMove) {\n                    if (c != '.') {\n                        for (int d = 0; d < 4; d++) {\n                            if (dirChar[d] == c) {\n                                petPos[i].x += dx[d];\n                                petPos[i].y += dy[d];\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    // Build wall information\n    vector<vector<bool>> canGoRight(20, vector<bool>(20, false));\n    vector<vector<bool>> canGoDown(20, vector<bool>(20, false));\n    \n    for (int i = 0; i < 20; i++) {\n        for (int j = 0; j < 19; j++) {\n            if (h[i][j] == '0') {\n                canGoRight[i][j] = true;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 19; i++) {\n        for (int j = 0; j < 20; j++) {\n            if (v[i][j] == '0') {\n                canGoDown[i][j] = true;\n            }\n        }\n    }\n    \n    // BFS to find shortest path\n    queue<pair<int,int>> q;\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> parent(20, vector<pair<int,int>>(20, {-1, -1}));\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        // Check all 4 directions\n        if (j < 19 && canGoRight[i][j] && dist[i][j+1] == -1) {\n            dist[i][j+1] = dist[i][j] + 1;\n            parent[i][j+1] = {i, j};\n            q.push({i, j+1});\n        }\n        if (j > 0 && canGoRight[i][j-1] && dist[i][j-1] == -1) {\n            dist[i][j-1] = dist[i][j] + 1;\n            parent[i][j-1] = {i, j};\n            q.push({i, j-1});\n        }\n        if (i < 19 && canGoDown[i][j] && dist[i+1][j] == -1) {\n            dist[i+1][j] = dist[i][j] + 1;\n            parent[i+1][j] = {i, j};\n            q.push({i+1, j});\n        }\n        if (i > 0 && canGoDown[i-1][j] && dist[i-1][j] == -1) {\n            dist[i-1][j] = dist[i][j] + 1;\n            parent[i-1][j] = {i, j};\n            q.push({i-1, j});\n        }\n    }\n    \n    // Reconstruct shortest path\n    string shortestPath;\n    int ci = ti, cj = tj;\n    vector<pair<int,int>> pathCoords;\n    \n    while (ci != si || cj != sj) {\n        pathCoords.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        \n        // Determine the move\n        if (ci - pi == 1) shortestPath = \"D\" + shortestPath;\n        else if (ci - pi == -1) shortestPath = \"U\" + shortestPath;\n        else if (cj - pj == 1) shortestPath = \"R\" + shortestPath;\n        else if (cj - pj == -1) shortestPath = \"L\" + shortestPath;\n        \n        ci = pi;\n        cj = pj;\n    }\n    \n    // Strategy: repeat each move based on p value to ensure robustness\n    string result;\n    int baseRepeat = 1;\n    \n    // Adjust repetition based on p\n    if (p >= 0.4) baseRepeat = 3;\n    else if (p >= 0.3) baseRepeat = 2;\n    else if (p >= 0.2) baseRepeat = 2;\n    else baseRepeat = 1;\n    \n    // First, add the path with repetitions for each move\n    for (char move : shortestPath) {\n        for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n            result += move;\n        }\n    }\n    \n    // If we have space left, repeat the entire path for extra robustness\n    int pathLen = shortestPath.length() * baseRepeat;\n    while (result.length() + pathLen <= 200) {\n        for (char move : shortestPath) {\n            for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n                result += move;\n            }\n        }\n    }\n    \n    // Fill remaining space with the shortest path\n    int idx = 0;\n    while (result.length() < 200 && result.length() < 200) {\n        result += shortestPath[idx % shortestPath.length()];\n        idx++;\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint rotations[N][N];\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nint rotate_tile(int tile) {\n    if (tile <= 3) return (tile + 1) % 4;\n    if (tile == 4) return 5;\n    if (tile == 5) return 4;\n    if (tile == 6) return 7;\n    return 6;\n}\n\nint get_tile_state(int i, int j) {\n    int t = tiles[i][j];\n    for (int r = 0; r < rotations[i][j]; r++) {\n        t = rotate_tile(t);\n    }\n    return t;\n}\n\nint find_loop_length(int si, int sj, int sd, vector<vector<vector<bool>>>& visited) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    while (true) {\n        if (visited[i][j][d]) {\n            if (i == si && j == sj && d == sd) return length;\n            return 0;\n        }\n        \n        int tile_state = get_tile_state(i, j);\n        int d2 = to[tile_state][d];\n        if (d2 == -1) return 0;\n        \n        int ni = i + di[d2];\n        int nj = j + dj[d2];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return 0;\n        \n        i = ni;\n        j = nj;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (length > N * N * 2) return 0;\n    }\n}\n\npair<int, int> calculate_top2_loops() {\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    vector<int> loops;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = find_loop_length(i, j, d, visited);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    int ci = i, cj = j, cd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ci][cj][cd] = true;\n                        int tile_state = get_tile_state(ci, cj);\n                        int d2 = to[tile_state][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (loops.size() < 2) return {0, 0};\n    sort(loops.rbegin(), loops.rend());\n    return {loops[0], loops[1]};\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rot_dist(0, 3);\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    // Initialize with random rotations\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            rotations[i][j] = rot_dist(rng);\n        }\n    }\n    \n    auto [l1, l2] = calculate_top2_loops();\n    int best_score = l1 * l2;\n    int best_rotations[N][N];\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    // Simulated annealing\n    double temp = 50.0;\n    double cooling_rate = 0.9995;\n    auto start_time = chrono::steady_clock::now();\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1800) {\n        int i = pos_dist(rng);\n        int j = pos_dist(rng);\n        int old_rot = rotations[i][j];\n        int new_rot = rot_dist(rng);\n        \n        if (new_rot == old_rot) continue;\n        \n        rotations[i][j] = new_rot;\n        auto [new_l1, new_l2] = calculate_top2_loops();\n        int new_score = new_l1 * new_l2;\n        \n        int delta = new_score - best_score;\n        \n        if (delta > 0 || prob_dist(rng) < exp(delta / temp)) {\n            if (new_score > best_score) {\n                best_score = new_score;\n                memcpy(best_rotations, rotations, sizeof(rotations));\n            }\n        } else {\n            rotations[i][j] = old_rot;\n        }\n        \n        temp *= cooling_rate;\n        if (temp < 0.01) temp = 0.01;\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\npair<int, int> empty_pos;\nvector<char> answer;\nmt19937 rng(42);\n\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n                return;\n            }\n        }\n    }\n}\n\nvoid make_move(int dir) {\n    int nx = empty_pos.first + dx[dir];\n    int ny = empty_pos.second + dy[dir];\n    if (in_bounds(nx, ny)) {\n        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        empty_pos = {nx, ny};\n        answer.push_back(dir_char[dir]);\n    }\n}\n\nint get_tree_size() {\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    int max_tree = 0;\n    \n    for (int si = 0; si < N; si++) {\n        for (int sj = 0; sj < N; sj++) {\n            if (board[si][sj] == 0 || visited[si][sj]) continue;\n            \n            // BFS to find connected component\n            queue<pair<int,int>> q;\n            vector<pair<int,int>> component;\n            q.push({si, sj});\n            visited[si][sj] = true;\n            component.push_back({si, sj});\n            \n            int edges = 0;\n            set<pair<pair<int,int>,pair<int,int>>> edge_set;\n            \n            while (!q.empty()) {\n                auto [i, j] = q.front();\n                q.pop();\n                \n                // Check all 4 directions\n                if (i > 0 && board[i-1][j] != 0 && !visited[i-1][j]) {\n                    if ((board[i][j] & UP) && (board[i-1][j] & DOWN)) {\n                        visited[i-1][j] = true;\n                        q.push({i-1, j});\n                        component.push_back({i-1, j});\n                        edge_set.insert({{min(i,i-1), j}, {max(i,i-1), j}});\n                    }\n                }\n                if (i < N-1 && board[i+1][j] != 0 && !visited[i+1][j]) {\n                    if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                        visited[i+1][j] = true;\n                        q.push({i+1, j});\n                        component.push_back({i+1, j});\n                        edge_set.insert({{min(i,i+1), j}, {max(i,i+1), j}});\n                    }\n                }\n                if (j > 0 && board[i][j-1] != 0 && !visited[i][j-1]) {\n                    if ((board[i][j] & LEFT) && (board[i][j-1] & RIGHT)) {\n                        visited[i][j-1] = true;\n                        q.push({i, j-1});\n                        component.push_back({i, j-1});\n                        edge_set.insert({{i, min(j,j-1)}, {i, max(j,j-1)}});\n                    }\n                }\n                if (j < N-1 && board[i][j+1] != 0 && !visited[i][j+1]) {\n                    if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                        visited[i][j+1] = true;\n                        q.push({i, j+1});\n                        component.push_back({i, j+1});\n                        edge_set.insert({{i, min(j,j+1)}, {i, max(j,j+1)}});\n                    }\n                }\n            }\n            \n            edges = edge_set.size();\n            \n            // Check if it's a tree\n            if (edges == (int)component.size() - 1) {\n                max_tree = max(max_tree, (int)component.size());\n            }\n        }\n    }\n    \n    return max_tree;\n}\n\nvoid solve() {\n    int best_score = get_tree_size();\n    int moves_without_improvement = 0;\n    \n    while (answer.size() < T && best_score < N * N - 1) {\n        if (moves_without_improvement > 100) {\n            // Random restart\n            for (int i = 0; i < 20 && answer.size() < T; i++) {\n                int dir = rng() % 4;\n                if (in_bounds(empty_pos.first + dx[dir], empty_pos.second + dy[dir])) {\n                    make_move(dir);\n                }\n            }\n            moves_without_improvement = 0;\n        }\n        \n        // Try all 4 directions\n        int best_dir = -1;\n        int best_new_score = best_score;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = empty_pos.first + dx[dir];\n            int ny = empty_pos.second + dy[dir];\n            if (!in_bounds(nx, ny)) continue;\n            \n            // Make temporary move\n            swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n            auto old_empty = empty_pos;\n            empty_pos = {nx, ny};\n            \n            int new_score = get_tree_size();\n            \n            // Simulated annealing acceptance\n            double temp = 1.0 * (T - answer.size()) / T;\n            if (new_score > best_new_score || \n                (new_score == best_new_score && (rng() % 100) < temp * 30)) {\n                best_new_score = new_score;\n                best_dir = dir;\n            }\n            \n            // Undo move\n            empty_pos = old_empty;\n            swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        }\n        \n        if (best_dir != -1) {\n            make_move(best_dir);\n            if (best_new_score > best_score) {\n                best_score = best_new_score;\n                moves_without_improvement = 0;\n            } else {\n                moves_without_improvement++;\n            }\n        } else {\n            moves_without_improvement++;\n        }\n    }\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            if (line[j] >= '0' && line[j] <= '9') {\n                board[i][j] = line[j] - '0';\n            } else {\n                board[i][j] = line[j] - 'a' + 10;\n            }\n        }\n    }\n    \n    find_empty();\n    solve();\n    \n    for (char c : answer) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst double RADIUS = 10000.0;\nconst double EPS = 1e-9;\nconst int MAX_COORD = 1000000000;\n\nstruct Point {\n    double x, y;\n    Point(double x = 0, double y = 0) : x(x), y(y) {}\n    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }\n    double cross(const Point& p) const { return x * p.y - y * p.x; }\n};\n\nstruct Line {\n    int px, py, qx, qy;\n    Line(int px = 0, int py = 0, int qx = 0, int qy = 0) : px(px), py(py), qx(qx), qy(qy) {}\n    \n    int side(const Point& p) const {\n        double dx1 = qx - px;\n        double dy1 = qy - py;\n        double dx2 = p.x - px;\n        double dy2 = p.y - py;\n        double v = dx1 * dy2 - dy1 * dx2;\n        if (v > EPS) return 1;\n        if (v < -EPS) return -1;\n        return 0;\n    }\n};\n\nint N, K;\nvector<int> a(11);\nvector<Point> strawberries;\nvector<Line> lines;\nvector<Line> bestLines;\nint bestScore = 0;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool insideCircle(const Point& p) {\n    return p.x * p.x + p.y * p.y < RADIUS * RADIUS - EPS;\n}\n\nvector<int> getRegions() {\n    vector<int> region(N);\n    \n    for (int i = 0; i < N; i++) {\n        if (!insideCircle(strawberries[i])) {\n            region[i] = -1;\n            continue;\n        }\n        \n        bool onLine = false;\n        int code = 0;\n        for (int j = 0; j < (int)lines.size(); j++) {\n            int s = lines[j].side(strawberries[i]);\n            if (s == 0) {\n                onLine = true;\n                break;\n            }\n            if (s > 0) code |= (1 << j);\n        }\n        region[i] = onLine ? -1 : code;\n    }\n    \n    return region;\n}\n\nint calculateScore() {\n    vector<int> region = getRegions();\n    map<int, int> regionCount;\n    \n    for (int r : region) {\n        if (r >= 0) regionCount[r]++;\n    }\n    \n    vector<int> b(11, 0);\n    for (auto& [r, cnt] : regionCount) {\n        if (cnt <= 10) b[cnt]++;\n    }\n    \n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(a[d], b[d]);\n    }\n    \n    return score;\n}\n\nLine randomLine() {\n    uniform_int_distribution<int> dist(-20000, 20000);\n    int px = dist(rng);\n    int py = dist(rng);\n    int qx = dist(rng);\n    int qy = dist(rng);\n    \n    while (px == qx && py == qy) {\n        qx = dist(rng);\n        qy = dist(rng);\n    }\n    \n    return Line(px, py, qx, qy);\n}\n\nLine targetedLine() {\n    // Try to create lines that pass near strawberries to create good partitions\n    int i = rng() % N;\n    int j = rng() % N;\n    while (i == j) j = rng() % N;\n    \n    double dx = strawberries[j].x - strawberries[i].x;\n    double dy = strawberries[j].y - strawberries[i].y;\n    \n    // Create a perpendicular or parallel line with some offset\n    uniform_real_distribution<double> offset_dist(-1000, 1000);\n    uniform_real_distribution<double> angle_dist(-0.3, 0.3);\n    \n    double angle = atan2(dy, dx) + angle_dist(rng);\n    double offset = offset_dist(rng);\n    \n    int px = (int)(strawberries[i].x + offset * cos(angle));\n    int py = (int)(strawberries[i].y + offset * sin(angle));\n    int qx = px + (int)(10000 * cos(angle + M_PI/2));\n    int qy = py + (int)(10000 * sin(angle + M_PI/2));\n    \n    return Line(px, py, qx, qy);\n}\n\nvoid solve() {\n    lines.clear();\n    \n    // Start with some targeted lines\n    for (int iter = 0; iter < min(20, K); iter++) {\n        Line bestLine = targetedLine();\n        int bestImprovement = -1;\n        int currentScore = calculateScore();\n        \n        for (int trial = 0; trial < 50; trial++) {\n            Line candidate = (trial < 25) ? targetedLine() : randomLine();\n            lines.push_back(candidate);\n            int newScore = calculateScore();\n            lines.pop_back();\n            \n            if (newScore - currentScore > bestImprovement) {\n                bestImprovement = newScore - currentScore;\n                bestLine = candidate;\n            }\n        }\n        \n        if (bestImprovement >= 0) {\n            lines.push_back(bestLine);\n        }\n    }\n    \n    // Simulated annealing\n    double startTime = clock();\n    double timeLimit = 2.8 * CLOCKS_PER_SEC;\n    \n    int currentScore = calculateScore();\n    bestLines = lines;\n    bestScore = currentScore;\n    \n    double temp = 10.0;\n    int iter = 0;\n    \n    while (clock() - startTime < timeLimit) {\n        iter++;\n        \n        if (iter % 1000 == 0) {\n            double elapsed = (clock() - startTime) / CLOCKS_PER_SEC;\n            temp = 10.0 * (1.0 - elapsed / 2.8);\n        }\n        \n        int op = rng() % 100;\n        \n        if (op < 30 && lines.size() < K) {\n            // Add a line\n            Line newLine = (rng() % 2) ? targetedLine() : randomLine();\n            lines.push_back(newLine);\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.pop_back();\n            }\n        } else if (op < 50 && lines.size() > 5) {\n            // Remove a line\n            int idx = rng() % lines.size();\n            Line removed = lines[idx];\n            lines.erase(lines.begin() + idx);\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.insert(lines.begin() + idx, removed);\n            }\n        } else if (lines.size() > 0) {\n            // Modify a line\n            int idx = rng() % lines.size();\n            Line old = lines[idx];\n            lines[idx] = (rng() % 2) ? targetedLine() : randomLine();\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines[idx] = old;\n            }\n        }\n    }\n    \n    lines = bestLines;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    \n    solve();\n    \n    cout << lines.size() << \"\\n\";\n    for (const Line& line : lines) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x != p.x ? x < p.x : y < p.y;\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\nstruct Rectangle {\n    Point p1, p2, p3, p4;\n    Rectangle(Point a, Point b, Point c, Point d) : p1(a), p2(b), p3(c), p4(d) {}\n};\n\nint N, M;\nset<Point> dots;\nvector<Rectangle> rectangles;\nset<pair<Point, Point>> usedSegments;\n\nint weight(int x, int y) {\n    int c = (N - 1) / 2;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\nbool isValidPoint(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool isRectangle(Point p1, Point p2, Point p3, Point p4, bool& isAxis) {\n    // Check if 4 points form a rectangle (axis-aligned or 45\u00b0 rotated)\n    vector<Point> pts = {p1, p2, p3, p4};\n    sort(pts.begin(), pts.end());\n    \n    // Check axis-aligned rectangle\n    if (pts[0].x == pts[1].x && pts[2].x == pts[3].x && \n        pts[0].y == pts[2].y && pts[1].y == pts[3].y) {\n        isAxis = true;\n        return true;\n    }\n    \n    // Check 45\u00b0 rotated rectangle\n    int cx = (pts[0].x + pts[1].x + pts[2].x + pts[3].x) / 4;\n    int cy = (pts[0].y + pts[1].y + pts[2].y + pts[3].y) / 4;\n    \n    vector<pair<int, int>> dists;\n    for (auto& p : pts) {\n        int dx = p.x - cx;\n        int dy = p.y - cy;\n        dists.push_back({dx * dx + dy * dy, dx * 1000 + dy});\n    }\n    sort(dists.begin(), dists.end());\n    \n    if (dists[0].first == dists[1].first && dists[1].first == dists[2].first && \n        dists[2].first == dists[3].first) {\n        isAxis = false;\n        return true;\n    }\n    \n    return false;\n}\n\nvector<Point> getPerimeter(Point p1, Point p2, Point p3, Point p4) {\n    vector<Point> perimeter;\n    \n    // Find the correct order of points\n    vector<Point> pts = {p2, p3, p4};\n    sort(pts.begin(), pts.end(), [&](Point a, Point b) {\n        int d1 = abs(a.x - p1.x) + abs(a.y - p1.y);\n        int d2 = abs(b.x - p1.x) + abs(b.y - p1.y);\n        return d1 < d2;\n    });\n    \n    Point a = p1, b = pts[0], c = pts[2], d = pts[1];\n    \n    // Generate all points on perimeter\n    auto addLine = [&](Point from, Point to) {\n        int dx = (to.x > from.x) ? 1 : (to.x < from.x) ? -1 : 0;\n        int dy = (to.y > from.y) ? 1 : (to.y < from.y) ? -1 : 0;\n        Point curr = from;\n        while (curr.x != to.x || curr.y != to.y) {\n            perimeter.push_back(curr);\n            curr.x += dx;\n            curr.y += dy;\n        }\n    };\n    \n    addLine(a, b);\n    addLine(b, c);\n    addLine(c, d);\n    addLine(d, a);\n    \n    return perimeter;\n}\n\nbool canPlaceRectangle(Point newDot, Point p2, Point p3, Point p4) {\n    if (dots.count(newDot)) return false;\n    \n    bool isAxis;\n    if (!isRectangle(newDot, p2, p3, p4, isAxis)) return false;\n    \n    vector<Point> perimeter = getPerimeter(newDot, p2, p3, p4);\n    \n    // Check no other dots on perimeter\n    for (auto& p : perimeter) {\n        if (p == newDot || p == p2 || p == p3 || p == p4) continue;\n        if (dots.count(p)) return false;\n    }\n    \n    // Check segments don't overlap with existing rectangles\n    for (int i = 0; i < perimeter.size(); i++) {\n        Point a = perimeter[i];\n        Point b = perimeter[(i + 1) % perimeter.size()];\n        if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n        if (usedSegments.count({a, b})) return false;\n    }\n    \n    return true;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert(Point(x, y));\n    }\n    \n    vector<vector<int>> result;\n    \n    // Try to add dots and rectangles\n    for (int iter = 0; iter < 1000; iter++) {\n        Point bestNew;\n        vector<Point> bestRect;\n        int bestWeight = -1;\n        \n        // Try all combinations of 3 existing dots\n        vector<Point> dotVec(dots.begin(), dots.end());\n        int n = dotVec.size();\n        \n        for (int i = 0; i < min(n, 50); i++) {\n            for (int j = i + 1; j < min(n, 50); j++) {\n                for (int k = j + 1; k < min(n, 50); k++) {\n                    Point p2 = dotVec[i], p3 = dotVec[j], p4 = dotVec[k];\n                    \n                    // Try different positions for new dot\n                    for (int x = 0; x < N; x++) {\n                        for (int y = 0; y < N; y++) {\n                            Point newDot(x, y);\n                            if (canPlaceRectangle(newDot, p2, p3, p4)) {\n                                int w = weight(x, y);\n                                if (w > bestWeight) {\n                                    bestWeight = w;\n                                    bestNew = newDot;\n                                    bestRect = {newDot, p2, p3, p4};\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (bestWeight == -1) break;\n        \n        // Add the new dot and rectangle\n        dots.insert(bestNew);\n        result.push_back({bestNew.x, bestNew.y, bestRect[1].x, bestRect[1].y, \n                         bestRect[2].x, bestRect[2].y, bestRect[3].x, bestRect[3].y});\n        \n        // Mark used segments\n        vector<Point> perimeter = getPerimeter(bestRect[0], bestRect[1], bestRect[2], bestRect[3]);\n        for (int i = 0; i < perimeter.size(); i++) {\n            Point a = perimeter[i];\n            Point b = perimeter[(i + 1) % perimeter.size()];\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            usedSegments.insert({a, b});\n        }\n    }\n    \n    cout << result.size() << endl;\n    for (auto& r : result) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << \" \";\n            cout << r[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int TOTAL = 100;\n\nstruct Board {\n    int grid[N][N]; // 0 = empty, 1-3 = candy flavors\n    \n    Board() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void place(int pos, int flavor) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tiltForward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = 0;\n            for (int i = 0; i < N; i++) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltBackward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = N-1;\n            for (int i = N-1; i >= 0; i--) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tiltLeft() {\n        for (int i = 0; i < N; i++) {\n            int writePos = 0;\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltRight() {\n        for (int i = 0; i < N; i++) {\n            int writePos = N-1;\n            for (int j = N-1; j >= 0; j--) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') tiltForward();\n        else if (dir == 'B') tiltBackward();\n        else if (dir == 'L') tiltLeft();\n        else if (dir == 'R') tiltRight();\n    }\n    \n    // Evaluate board quality based on connected components\n    double evaluate() {\n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        \n        double score = 0;\n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int flavor = grid[i][j];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    score += size * size;\n                }\n            }\n        }\n        return score;\n    }\n    \n    // Simple heuristic: count adjacent same-flavor pairs\n    int countAdjacentPairs() {\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (i + 1 < N && grid[i+1][j] == grid[i][j]) count++;\n                    if (j + 1 < N && grid[i][j+1] == grid[i][j]) count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(TOTAL);\n    for (int i = 0; i < TOTAL; i++) {\n        cin >> flavors[i];\n    }\n    \n    Board board;\n    \n    for (int t = 0; t < TOTAL; t++) {\n        int pos;\n        cin >> pos;\n        \n        board.place(pos, flavors[t]);\n        \n        if (t == TOTAL - 1) break; // No need to tilt after last candy\n        \n        // Try all 4 directions and choose the best\n        char dirs[] = {'F', 'B', 'L', 'R'};\n        char bestDir = 'F';\n        double bestScore = -1;\n        \n        // Use simpler metric early, full evaluation later\n        if (t < 30) {\n            // Early game: maximize adjacent pairs\n            for (char dir : dirs) {\n                Board tempBoard = board;\n                tempBoard.tilt(dir);\n                int score = tempBoard.countAdjacentPairs();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestDir = dir;\n                }\n            }\n        } else {\n            // Mid to late game: maximize component sizes\n            for (char dir : dirs) {\n                Board tempBoard = board;\n                tempBoard.tilt(dir);\n                double score = tempBoard.evaluate();\n                if (score > bestScore) {\n                    bestScore = score;\n                    bestDir = dir;\n                }\n            }\n        }\n        \n        board.tilt(bestDir);\n        cout << bestDir << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass Graph {\n    int N;\n    vector<vector<int>> adj;\n    \npublic:\n    Graph(int n) : N(n), adj(n, vector<int>(n, 0)) {}\n    \n    void setEdge(int i, int j, int val) {\n        adj[i][j] = adj[j][i] = val;\n    }\n    \n    string toString() const {\n        string s;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void fromString(const string& s) {\n        int idx = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1' ? 1 : 0);\n            }\n        }\n    }\n    \n    vector<double> getInvariants() const {\n        vector<double> inv;\n        \n        // Edge count\n        int edges = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                edges += adj[i][j];\n            }\n        }\n        inv.push_back(edges);\n        \n        // Degree sequence\n        vector<int> degrees(N);\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        \n        // Add degree distribution stats\n        for(int i = 0; i < min(5, N); i++) {\n            inv.push_back(degrees[i]);\n            inv.push_back(degrees[N-1-i]);\n        }\n        \n        // Triangle count\n        int triangles = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                for(int k = j + 1; k < N; k++) {\n                    triangles += adj[i][j] * adj[j][k] * adj[k][i];\n                }\n            }\n        }\n        inv.push_back(triangles);\n        \n        // Degree correlation\n        double deg_corr = 0;\n        int edge_count = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(adj[i][j]) {\n                    deg_corr += degrees[i] * degrees[j];\n                    edge_count++;\n                }\n            }\n        }\n        if(edge_count > 0) deg_corr /= edge_count;\n        inv.push_back(deg_corr);\n        \n        return inv;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Choose N based on M and error rate\n    int N = 20;\n    if(eps <= 0.15) {\n        N = min(100, 15 + M/4);\n    } else if(eps <= 0.25) {\n        N = min(100, 20 + M/3);\n    } else {\n        N = min(100, 25 + M/2);\n    }\n    \n    vector<Graph> graphs;\n    mt19937 rng(42);\n    \n    // Generate M maximally different graphs\n    for(int idx = 0; idx < M; idx++) {\n        Graph g(N);\n        \n        // Create graphs with different edge densities\n        double target_density = (double)idx / (M - 1);\n        int target_edges = (int)(target_density * N * (N - 1) / 2);\n        \n        // Add edges with structured patterns for better distinguishability\n        set<pair<int,int>> edges;\n        \n        // Create different structural patterns based on index\n        if(idx % 4 == 0) {\n            // Path-like structure plus random edges\n            for(int i = 0; i < min(N-1, target_edges); i++) {\n                edges.insert({i, i+1});\n            }\n        } else if(idx % 4 == 1) {\n            // Star-like structure\n            for(int i = 1; i < min(N, target_edges+1); i++) {\n                edges.insert({0, i});\n            }\n        } else if(idx % 4 == 2) {\n            // Cycle plus chords\n            for(int i = 0; i < N && edges.size() < target_edges; i++) {\n                edges.insert({i, (i+1)%N});\n            }\n        }\n        \n        // Fill remaining edges randomly but deterministically\n        uniform_int_distribution<int> dist(0, N-1);\n        while(edges.size() < target_edges) {\n            int u = dist(rng);\n            int v = dist(rng);\n            if(u > v) swap(u, v);\n            if(u != v) edges.insert({u, v});\n        }\n        \n        for(auto [u, v] : edges) {\n            g.setEdge(u, v, 1);\n        }\n        \n        graphs.push_back(g);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for(const auto& g : graphs) {\n        cout << g.toString() << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute invariants\n    vector<vector<double>> invariants;\n    for(const auto& g : graphs) {\n        invariants.push_back(g.getInvariants());\n    }\n    \n    // Process queries\n    for(int q = 0; q < 100; q++) {\n        string h_str;\n        cin >> h_str;\n        \n        Graph h(N);\n        h.fromString(h_str);\n        auto h_inv = h.getInvariants();\n        \n        // Find closest match using weighted distance\n        int best = 0;\n        double best_dist = 1e18;\n        \n        for(int i = 0; i < M; i++) {\n            double dist = 0;\n            for(int j = 0; j < h_inv.size(); j++) {\n                double weight = (j == 0) ? 2.0 : 1.0;  // Weight edge count more\n                dist += weight * abs(h_inv[j] - invariants[i][j]);\n            }\n            \n            if(dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<int> assignment;\n\nconst int INF = 1000000000;\n\n// Dijkstra with edge mask\nvector<int> dijkstra(int s, const vector<bool>& usable, const vector<vector<pair<int, int>>>& graph) {\n    vector<int> dist(N, INF);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            if (!usable[eid]) continue;\n            int w = edges[eid].w;\n            \n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    return dist;\n}\n\ndouble evaluateFrustration(const vector<vector<int>>& original_dist) {\n    double total = 0;\n    \n    vector<vector<int>> day_edges(D + 1);\n    for (int i = 0; i < M; i++) {\n        day_edges[assignment[i]].push_back(i);\n    }\n    \n    // Build adjacency list with edge indices\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    for (int day = 1; day <= D; day++) {\n        vector<bool> usable(M, true);\n        for (int e : day_edges[day]) {\n            usable[e] = false;\n        }\n        \n        double day_frustration = 0;\n        \n        // Sample vertices for faster evaluation\n        int samples = min(30, N);\n        for (int i = 0; i < samples; i++) {\n            int s = (i * N) / samples;\n            auto dist = dijkstra(s, usable, graph);\n            \n            for (int t = 0; t < N; t++) {\n                if (s != t) {\n                    day_frustration += (dist[t] - original_dist[s][t]) * (double)N / samples;\n                }\n            }\n        }\n        \n        total += day_frustration / (N * (N - 1));\n    }\n    \n    return total / D;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build graph for original distances\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    // Compute original distances for sampled vertices\n    vector<bool> all_usable(M, true);\n    vector<vector<int>> original_dist(N);\n    \n    int samples = min(30, N);\n    for (int i = 0; i < samples; i++) {\n        int s = (i * N) / samples;\n        original_dist[s] = dijkstra(s, all_usable, graph);\n    }\n    \n    // Initial assignment using K-means on edge midpoints\n    assignment.resize(M);\n    \n    vector<pair<double, double>> midpoints(M);\n    for (int i = 0; i < M; i++) {\n        midpoints[i] = {\n            (coords[edges[i].u].first + coords[edges[i].v].first) / 2.0,\n            (coords[edges[i].u].second + coords[edges[i].v].second) / 2.0\n        };\n    }\n    \n    // Simple K-means\n    mt19937 rng(42);\n    vector<pair<double, double>> centers(D);\n    \n    for (int i = 0; i < D; i++) {\n        centers[i] = midpoints[rng() % M];\n    }\n    \n    for (int iter = 0; iter < 10; iter++) {\n        vector<vector<int>> clusters(D);\n        \n        for (int i = 0; i < M; i++) {\n            double min_dist = 1e18;\n            int best = 0;\n            \n            for (int j = 0; j < D; j++) {\n                double dx = midpoints[i].first - centers[j].first;\n                double dy = midpoints[i].second - centers[j].second;\n                double d = dx * dx + dy * dy;\n                \n                if (d < min_dist) {\n                    min_dist = d;\n                    best = j;\n                }\n            }\n            \n            if (clusters[best].size() < K) {\n                clusters[best].push_back(i);\n                assignment[i] = best + 1;\n            } else {\n                // Find another cluster with space\n                for (int j = 0; j < D; j++) {\n                    if (clusters[j].size() < K) {\n                        clusters[j].push_back(i);\n                        assignment[i] = j + 1;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Update centers\n        for (int j = 0; j < D; j++) {\n            if (!clusters[j].empty()) {\n                double sx = 0, sy = 0;\n                for (int i : clusters[j]) {\n                    sx += midpoints[i].first;\n                    sy += midpoints[i].second;\n                }\n                centers[j] = {sx / clusters[j].size(), sy / clusters[j].size()};\n            }\n        }\n    }\n    \n    // Simulated annealing\n    double current_score = evaluateFrustration(original_dist);\n    double best_score = current_score;\n    vector<int> best_assignment = assignment;\n    \n    double T = 10.0;\n    uniform_real_distribution<double> prob(0, 1);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        if (elapsed > 5500) break;\n        \n        // Try swapping two random edges\n        int e1 = rng() % M;\n        int e2 = rng() % M;\n        if (e1 == e2 || assignment[e1] == assignment[e2]) continue;\n        \n        swap(assignment[e1], assignment[e2]);\n        \n        double new_score = evaluateFrustration(original_dist);\n        double delta = new_score - current_score;\n        \n        if (delta < 0 || prob(rng) < exp(-delta / T)) {\n            current_score = new_score;\n            if (current_score < best_score) {\n                best_score = current_score;\n                best_assignment = assignment;\n            }\n        } else {\n            swap(assignment[e1], assignment[e2]);\n        }\n        \n        T *= 0.9995;\n    }\n    \n    assignment = best_assignment;\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\nvector<vector<vector<int>>> obj1, obj2;\nvector<vector<pair<int,int>>> blocks;\nmap<pair<int,int>, int> coord_to_block;\n\nvoid read_input() {\n    cin >> D;\n    f1.resize(D); r1.resize(D);\n    f2.resize(D); r2.resize(D);\n    \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\nvector<vector<vector<int>>> construct_object(vector<string>& f, vector<string>& r) {\n    vector<vector<vector<int>>> obj(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    // Use AND strategy: place cube at (x,y,z) if both f[z][x] and r[z][y] are 1\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(f[z][x] == '1' && r[z][y] == '1') {\n                    obj[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    return obj;\n}\n\nvoid create_blocks() {\n    int block_id = 0;\n    set<pair<int,int>> used_coords;\n    \n    // Try to find common regions first\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] && obj2[x][y][z]) {\n                    int key = x * D * D + y * D + z;\n                    if(used_coords.find({1, key}) == used_coords.end() && \n                       used_coords.find({2, key}) == used_coords.end()) {\n                        block_id++;\n                        blocks.push_back({{1, key}, {2, key}});\n                        used_coords.insert({1, key});\n                        used_coords.insert({2, key});\n                        coord_to_block[{1, key}] = block_id;\n                        coord_to_block[{2, key}] = block_id;\n                        \n                        // Try to expand this block\n                        queue<tuple<int,int,int,int>> q;\n                        q.push({1, x, y, z});\n                        q.push({2, x, y, z});\n                        set<tuple<int,int,int,int>> visited;\n                        visited.insert({1, x, y, z});\n                        visited.insert({2, x, y, z});\n                        \n                        while(!q.empty() && blocks.back().size() < 8) {\n                            auto [oid, cx, cy, cz] = q.front();\n                            q.pop();\n                            \n                            int dx[] = {1,-1,0,0,0,0};\n                            int dy[] = {0,0,1,-1,0,0};\n                            int dz[] = {0,0,0,0,1,-1};\n                            \n                            for(int d = 0; d < 6; d++) {\n                                int nx = cx + dx[d];\n                                int ny = cy + dy[d];\n                                int nz = cz + dz[d];\n                                \n                                if(nx >= 0 && nx < D && ny >= 0 && ny < D && \n                                   nz >= 0 && nz < D && visited.find({oid, nx, ny, nz}) == visited.end()) {\n                                    \n                                    auto& curr_obj = (oid == 1) ? obj1 : obj2;\n                                    if(curr_obj[nx][ny][nz]) {\n                                        int nkey = nx * D * D + ny * D + nz;\n                                        if(used_coords.find({oid, nkey}) == used_coords.end()) {\n                                            blocks.back().push_back({oid, nkey});\n                                            used_coords.insert({oid, nkey});\n                                            coord_to_block[{oid, nkey}] = block_id;\n                                            visited.insert({oid, nx, ny, nz});\n                                            q.push({oid, nx, ny, nz});\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Fill remaining cells with individual blocks\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                int key = x * D * D + y * D + z;\n                \n                if(obj1[x][y][z] && used_coords.find({1, key}) == used_coords.end()) {\n                    block_id++;\n                    blocks.push_back({{1, key}});\n                    used_coords.insert({1, key});\n                    coord_to_block[{1, key}] = block_id;\n                }\n                \n                if(obj2[x][y][z] && used_coords.find({2, key}) == used_coords.end()) {\n                    block_id++;\n                    blocks.push_back({{2, key}});\n                    used_coords.insert({2, key});\n                    coord_to_block[{2, key}] = block_id;\n                }\n            }\n        }\n    }\n}\n\nvoid output_solution() {\n    int n = blocks.size();\n    cout << n << endl;\n    \n    vector<int> b1(D * D * D, 0), b2(D * D * D, 0);\n    \n    for(int i = 0; i < blocks.size(); i++) {\n        int block_num = i + 1;\n        for(auto& p : blocks[i]) {\n            if(p.first == 1) {\n                b1[p.second] = block_num;\n            } else {\n                b2[p.second] = block_num;\n            }\n        }\n    }\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b1[i];\n    }\n    cout << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b2[i];\n    }\n    cout << endl;\n}\n\nint main() {\n    read_input();\n    obj1 = construct_object(f1, r1);\n    obj2 = construct_object(f2, r2);\n    create_blocks();\n    output_solution();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<pair<int, int>> vertices(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int, pair<int, long long>>>> 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--; edges[i].v--;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, {i, edges[i].w}});\n        adj[edges[i].v].push_back({edges[i].u, {i, edges[i].w}});\n    }\n    \n    vector<pair<int, int>> residents(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n    \n    // Calculate distance from each resident to each vertex\n    vector<vector<int>> resident_to_vertex_dist(K, vector<int>(N));\n    for (int r = 0; r < K; r++) {\n        for (int v = 0; v < N; v++) {\n            long long dx = residents[r].first - vertices[v].first;\n            long long dy = residents[r].second - vertices[v].second;\n            long long dist_sq = dx * dx + dy * dy;\n            resident_to_vertex_dist[r][v] = (int)ceil(sqrt(dist_sq));\n        }\n    }\n    \n    // Greedy approach: cover residents with minimum cost increase\n    vector<int> vertex_power(N, 0);\n    vector<bool> resident_covered(K, false);\n    vector<bool> vertex_needed(N, false);\n    vertex_needed[0] = true; // Always need vertex 0\n    \n    // Cover all residents greedily\n    while (true) {\n        int uncovered = 0;\n        for (int r = 0; r < K; r++) {\n            if (!resident_covered[r]) uncovered++;\n        }\n        if (uncovered == 0) break;\n        \n        // Find best vertex to activate or power to increase\n        long long best_cost_increase = LLONG_MAX;\n        int best_vertex = -1;\n        int best_new_power = 0;\n        \n        for (int v = 0; v < N; v++) {\n            int max_power_needed = vertex_power[v];\n            int new_residents = 0;\n            \n            for (int r = 0; r < K; r++) {\n                if (!resident_covered[r] && resident_to_vertex_dist[r][v] <= 5000) {\n                    max_power_needed = max(max_power_needed, resident_to_vertex_dist[r][v]);\n                    new_residents++;\n                }\n            }\n            \n            if (new_residents > 0 && max_power_needed <= 5000) {\n                long long cost_increase = (long long)max_power_needed * max_power_needed - \n                                         (long long)vertex_power[v] * vertex_power[v];\n                \n                if (cost_increase / (double)new_residents < best_cost_increase / (double)max(1, new_residents)) {\n                    best_cost_increase = cost_increase;\n                    best_vertex = v;\n                    best_new_power = max_power_needed;\n                }\n            }\n        }\n        \n        if (best_vertex == -1) break;\n        \n        vertex_needed[best_vertex] = true;\n        vertex_power[best_vertex] = best_new_power;\n        \n        for (int r = 0; r < K; r++) {\n            if (resident_to_vertex_dist[r][best_vertex] <= best_new_power) {\n                resident_covered[r] = true;\n            }\n        }\n    }\n    \n    // Build MST connecting needed vertices using Dijkstra-like approach\n    vector<int> edge_used(M, 0);\n    vector<bool> vertex_connected(N, false);\n    priority_queue<tuple<long long, int, int>, vector<tuple<long long, int, int>>, greater<>> pq;\n    \n    vertex_connected[0] = true;\n    for (auto [v, info] : adj[0]) {\n        pq.push({info.second, v, info.first});\n    }\n    \n    while (!pq.empty()) {\n        auto [cost, v, edge_id] = pq.top();\n        pq.pop();\n        \n        if (vertex_connected[v]) continue;\n        \n        vertex_connected[v] = true;\n        edge_used[edge_id] = 1;\n        \n        for (auto [u, info] : adj[v]) {\n            if (!vertex_connected[u]) {\n                pq.push({info.second, u, info.first});\n            }\n        }\n    }\n    \n    // Clear power for unconnected vertices\n    for (int v = 0; v < N; v++) {\n        if (!vertex_connected[v]) {\n            vertex_power[v] = 0;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        if (i > 0) cout << \" \";\n        cout << vertex_power[i];\n    }\n    cout << \"\\n\";\n    \n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << edge_used[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nvector<vector<int>> pyramid(N);\nvector<tuple<int,int,int,int>> moves;\n\nvoid swapBalls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    moves.push_back({x1, y1, x2, y2});\n}\n\nbool isAdjacent(int x1, int y1, int x2, int y2) {\n    if (x1 == x2 - 1 && y1 == y2 - 1) return true;\n    if (x1 == x2 - 1 && y1 == y2) return true;\n    if (x1 == x2 && y1 == y2 - 1) return true;\n    if (x1 == x2 && y1 == y2 + 1) return true;\n    if (x1 == x2 + 1 && y1 == y2) return true;\n    if (x1 == x2 + 1 && y1 == y2 + 1) return true;\n    return false;\n}\n\nint countViolations() {\n    int violations = 0;\n    for (int x = 0; x < N - 1; 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\nint main() {\n    // Read input\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x + 1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Iteratively fix violations using bubble sort approach\n    int maxIter = 10000;\n    for (int iter = 0; iter < maxIter && moves.size() < 9500; iter++) {\n        int violations = countViolations();\n        if (violations == 0) break;\n        \n        bool improved = false;\n        \n        // Scan from top to bottom and fix violations\n        for (int x = 0; x < N - 1; x++) {\n            for (int y = 0; y <= x; y++) {\n                // Check and fix left child violation\n                if (pyramid[x][y] > pyramid[x + 1][y]) {\n                    swapBalls(x, y, x + 1, y);\n                    improved = true;\n                }\n                // Check and fix right child violation  \n                if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                    swapBalls(x, y, x + 1, y + 1);\n                    improved = true;\n                }\n            }\n        }\n        \n        // Also scan from bottom to top to help propagate small values upward\n        if (iter % 2 == 1) {\n            for (int x = N - 2; x >= 0; x--) {\n                for (int y = 0; y <= x; y++) {\n                    if (pyramid[x][y] > pyramid[x + 1][y]) {\n                        swapBalls(x, y, x + 1, y);\n                        improved = true;\n                    }\n                    if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                        swapBalls(x, y, x + 1, y + 1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    // Output\n    cout << moves.size() << endl;\n    for (auto [x1, y1, x2, y2] : moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {-1, 0, 1, 0};\nconst int dy[] = {0, 1, 0, -1};\n\nstruct Container {\n    int number;\n    int x, y;\n};\n\nclass Warehouse {\n    int D, N;\n    int entrance_x, entrance_y;\n    vector<vector<int>> grid; // -1: obstacle, -2: empty, >=0: container number\n    vector<Container> containers;\n    vector<pair<int,int>> obstacles;\n    \npublic:\n    Warehouse() {\n        cin >> D >> N;\n        entrance_x = 0;\n        entrance_y = (D - 1) / 2;\n        \n        grid.resize(D, vector<int>(D, -2));\n        \n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n            grid[x][y] = -1;\n            obstacles.push_back({x, y});\n        }\n    }\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < D && y >= 0 && y < D;\n    }\n    \n    bool isReachable(int tx, int ty) {\n        if (!isValid(tx, ty) || grid[tx][ty] == -1) return false;\n        if (tx == entrance_x && ty == entrance_y) return true;\n        \n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        q.push({entrance_x, entrance_y});\n        visited[entrance_x][entrance_y] = true;\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                if (!isValid(nx, ny) || visited[nx][ny]) continue;\n                if (grid[nx][ny] != -2 && !(nx == tx && ny == ty)) continue;\n                \n                if (nx == tx && ny == ty) return true;\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return false;\n    }\n    \n    int getDistance(int x, int y) {\n        if (!isReachable(x, y)) return INT_MAX;\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n        q.push({entrance_x, entrance_y});\n        dist[entrance_x][entrance_y] = 0;\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front();\n            q.pop();\n            \n            if (cx == x && cy == y) return dist[x][y];\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = cx + dx[dir];\n                int ny = cy + dy[dir];\n                \n                if (!isValid(nx, ny) || grid[nx][ny] != -2) continue;\n                if (dist[nx][ny] != INT_MAX) continue;\n                \n                dist[nx][ny] = dist[cx][cy] + 1;\n                q.push({nx, ny});\n            }\n        }\n        \n        return INT_MAX;\n    }\n    \n    pair<int,int> placeContainer(int container_num) {\n        // Find all reachable empty positions\n        vector<pair<int, pair<int,int>>> candidates;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == entrance_x && j == entrance_y) continue;\n                if (grid[i][j] != -2) continue;\n                \n                int dist = getDistance(i, j);\n                if (dist != INT_MAX) {\n                    candidates.push_back({dist, {i, j}});\n                }\n            }\n        }\n        \n        if (candidates.empty()) {\n            // Should not happen in valid test cases\n            return {0, 0};\n        }\n        \n        // Sort by distance\n        sort(candidates.begin(), candidates.end());\n        \n        // Place based on container number relative to total containers\n        int total_containers = D * D - 1 - N;\n        int idx = (container_num * candidates.size()) / total_containers;\n        idx = min(idx, (int)candidates.size() - 1);\n        \n        // Try to place at the calculated index, but also consider nearby positions\n        // to avoid blocking\n        int best_idx = idx;\n        int range = min(5, (int)candidates.size());\n        \n        for (int offset = 0; offset < range; offset++) {\n            for (int sign : {1, -1}) {\n                int test_idx = idx + sign * offset;\n                if (test_idx >= 0 && test_idx < candidates.size()) {\n                    auto [x, y] = candidates[test_idx].second;\n                    \n                    // Check if this placement would block fewer cells\n                    int blocked_count = 0;\n                    grid[x][y] = container_num; // Temporarily place\n                    \n                    for (int i = 0; i < D; i++) {\n                        for (int j = 0; j < D; j++) {\n                            if (grid[i][j] == -2 && !isReachable(i, j)) {\n                                blocked_count++;\n                            }\n                        }\n                    }\n                    \n                    grid[x][y] = -2; // Remove temporary placement\n                    \n                    if (blocked_count <= 2) { // Acceptable blocking\n                        best_idx = test_idx;\n                        goto found;\n                    }\n                }\n            }\n        }\n        \n        found:\n        auto [px, py] = candidates[best_idx].second;\n        grid[px][py] = container_num;\n        containers.push_back({container_num, px, py});\n        \n        return {px, py};\n    }\n    \n    vector<pair<int,int>> getRetrievalOrder() {\n        vector<pair<int,int>> result;\n        vector<bool> retrieved(containers.size(), false);\n        \n        while (result.size() < containers.size()) {\n            int best_idx = -1;\n            int best_number = INT_MAX;\n            \n            // Find the smallest numbered container that's accessible\n            for (int i = 0; i < containers.size(); i++) {\n                if (retrieved[i]) continue;\n                \n                if (isReachable(containers[i].x, containers[i].y)) {\n                    if (containers[i].number < best_number) {\n                        best_number = containers[i].number;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx == -1) {\n                // Should not happen, but fallback to any accessible container\n                for (int i = 0; i < containers.size(); i++) {\n                    if (retrieved[i]) continue;\n                    if (isReachable(containers[i].x, containers[i].y)) {\n                        best_idx = i;\n                        break;\n                    }\n                }\n            }\n            \n            retrieved[best_idx] = true;\n            grid[containers[best_idx].x][containers[best_idx].y] = -2;\n            result.push_back({containers[best_idx].x, containers[best_idx].y});\n        }\n        \n        return result;\n    }\n    \n    void run() {\n        int total_containers = D * D - 1 - N;\n        \n        // Place containers as they arrive\n        for (int i = 0; i < total_containers; i++) {\n            int container_num;\n            cin >> container_num;\n            \n            auto [x, y] = placeContainer(container_num);\n            cout << x << \" \" << y << endl;\n            cout.flush();\n        }\n        \n        // Determine retrieval order\n        auto retrieval_order = getRetrievalOrder();\n        for (auto [x, y] : retrieval_order) {\n            cout << x << \" \" << y << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Warehouse warehouse;\n    warehouse.run();\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\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    // Extract adjacency information\n    set<pair<int, int>> adjacencies;\n    \n    // Check internal adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            // Check right neighbor\n            if (j + 1 < n && grid[i][j] != grid[i][j+1]) {\n                int c1 = min(grid[i][j], grid[i][j+1]);\n                int c2 = max(grid[i][j], grid[i][j+1]);\n                adjacencies.insert({c1, c2});\n            }\n            \n            // Check bottom neighbor\n            if (i + 1 < n && grid[i][j] != grid[i+1][j]) {\n                int c1 = min(grid[i][j], grid[i+1][j]);\n                int c2 = max(grid[i][j], grid[i+1][j]);\n                adjacencies.insert({c1, c2});\n            }\n        }\n    }\n    \n    // Check boundary adjacencies (with color 0)\n    set<int> boundaryWards;\n    for (int i = 0; i < n; i++) {\n        boundaryWards.insert(grid[0][i]);\n        boundaryWards.insert(grid[n-1][i]);\n        boundaryWards.insert(grid[i][0]);\n        boundaryWards.insert(grid[i][n-1]);\n    }\n    \n    for (int ward : boundaryWards) {\n        adjacencies.insert({0, ward});\n    }\n    \n    // Build adjacency list\n    vector<vector<int>> adj(m + 1);\n    for (auto [c1, c2] : adjacencies) {\n        adj[c1].push_back(c2);\n        adj[c2].push_back(c1);\n    }\n    \n    // Create a compact grid representation\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    vector<bool> placed(m + 1, false);\n    placed[0] = true; // Color 0 is implicitly placed\n    \n    // Direction vectors\n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    // Start with boundary wards\n    queue<int> toPlace;\n    for (int ward : boundaryWards) {\n        toPlace.push(ward);\n        placed[ward] = true;\n    }\n    \n    // Place boundary wards near edges\n    int idx = 0;\n    for (int ward : boundaryWards) {\n        if (idx < n/4) {\n            result[1][2 + idx * 2] = ward;\n        } else if (idx < n/2) {\n            result[2 + (idx - n/4) * 2][n-2] = ward;\n        } else if (idx < 3*n/4) {\n            result[n-2][n-3 - (idx - n/2) * 2] = ward;\n        } else {\n            result[n-3 - (idx - 3*n/4) * 2][1] = ward;\n        }\n        idx++;\n        if (idx * 2 >= n) break;\n    }\n    \n    // BFS to place remaining wards based on adjacencies\n    while (!toPlace.empty()) {\n        int ward = toPlace.front();\n        toPlace.pop();\n        \n        for (int neighbor : adj[ward]) {\n            if (!placed[neighbor] && neighbor != 0) {\n                // Find a position adjacent to ward's position\n                bool found = false;\n                for (int i = 0; i < n && !found; i++) {\n                    for (int j = 0; j < n && !found; j++) {\n                        if (result[i][j] == ward) {\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 && result[ni][nj] == 0) {\n                                    result[ni][nj] = neighbor;\n                                    placed[neighbor] = true;\n                                    toPlace.push(neighbor);\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place any remaining wards\n    for (int ward = 1; ward <= m; ward++) {\n        if (!placed[ward]) {\n            // Find empty position, preferably near its neighbors\n            bool found = false;\n            for (int i = 1; i < n-1 && !found; i++) {\n                for (int j = 1; j < n-1 && !found; j++) {\n                    if (result[i][j] == 0) {\n                        result[i][j] = ward;\n                        placed[ward] = true;\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Ensure all required adjacencies exist by expanding regions if needed\n    for (auto [c1, c2] : adjacencies) {\n        if (c1 == 0) continue; // Boundary adjacencies handled by placement\n        \n        // Check if adjacency exists\n        bool adjacent = false;\n        for (int i = 0; i < n && !adjacent; i++) {\n            for (int j = 0; j < n && !adjacent; j++) {\n                if (result[i][j] == c1) {\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 && result[ni][nj] == c2) {\n                            adjacent = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If not adjacent, try to make them adjacent\n        if (!adjacent) {\n            // Find positions of c1 and c2 and try to grow one toward the other\n            vector<pair<int,int>> pos1, pos2;\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (result[i][j] == c1) pos1.push_back({i, j});\n                    if (result[i][j] == c2) pos2.push_back({i, j});\n                }\n            }\n            \n            if (!pos1.empty() && !pos2.empty()) {\n                // Try to extend c1 toward c2\n                int minDist = n * n;\n                int bestX = -1, bestY = -1;\n                for (auto [x1, y1] : pos1) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x1 + dx[d];\n                        int ny = y1 + dy[d];\n                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                            for (auto [x2, y2] : pos2) {\n                                int dist = abs(nx - x2) + abs(ny - y2);\n                                if (dist < minDist) {\n                                    minDist = dist;\n                                    bestX = nx;\n                                    bestY = ny;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (bestX != -1) {\n                    result[bestX][bestY] = c1;\n                }\n            }\n        }\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<double> weight_estimate;\nvector<vector<int>> comparison_result; // -1: i<j, 0: unknown/equal, 1: i>j\n\nchar query(vector<int> left, vector<int> right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid update_weights(const vector<int>& left, const vector<int>& right, char result) {\n    double left_sum = 0, right_sum = 0;\n    for (int i : left) left_sum += weight_estimate[i];\n    for (int i : right) right_sum += weight_estimate[i];\n    \n    if (result == '<') {\n        double ratio = 0.95;\n        for (int i : left) weight_estimate[i] *= ratio;\n        for (int i : right) weight_estimate[i] /= ratio;\n    } else if (result == '>') {\n        double ratio = 0.95;\n        for (int i : left) weight_estimate[i] /= ratio;\n        for (int i : right) weight_estimate[i] *= ratio;\n    }\n}\n\nvoid solve() {\n    cin >> N >> D >> Q;\n    \n    weight_estimate.resize(N, 1000.0);\n    comparison_result.resize(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Phase 1: Compare individual items (use ~60% of queries)\n    int phase1_limit = min(Q * 3 / 5, N * (N - 1) / 2);\n    \n    // Random sampling for large N\n    vector<pair<int, int>> pairs;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            pairs.push_back({i, j});\n        }\n    }\n    \n    random_device rd;\n    mt19937 gen(rd());\n    shuffle(pairs.begin(), pairs.end(), gen);\n    \n    for (auto [i, j] : pairs) {\n        if (queries_used >= phase1_limit) break;\n        \n        char result = query({i}, {j});\n        queries_used++;\n        \n        if (result == '<') {\n            comparison_result[i][j] = -1;\n            comparison_result[j][i] = 1;\n            weight_estimate[i] *= 0.9;\n            weight_estimate[j] *= 1.1;\n        } else if (result == '>') {\n            comparison_result[i][j] = 1;\n            comparison_result[j][i] = -1;\n            weight_estimate[i] *= 1.1;\n            weight_estimate[j] *= 0.9;\n        }\n    }\n    \n    // Phase 2: Group comparisons to refine estimates\n    while (queries_used < Q) {\n        vector<pair<double, int>> sorted_items;\n        for (int i = 0; i < N; i++) {\n            sorted_items.push_back({weight_estimate[i], i});\n        }\n        sort(sorted_items.begin(), sorted_items.end());\n        \n        // Compare quartiles\n        int quarter = N / 4;\n        if (quarter < 1) quarter = 1;\n        \n        vector<int> light, heavy;\n        for (int i = 0; i < min(quarter, (N + 1) / 2); i++) {\n            light.push_back(sorted_items[i].second);\n            heavy.push_back(sorted_items[N - 1 - i].second);\n        }\n        \n        if (!light.empty() && !heavy.empty()) {\n            char result = query(light, heavy);\n            queries_used++;\n            update_weights(light, heavy, result);\n        }\n        \n        // Also try middle groups\n        if (queries_used < Q && N > 8) {\n            vector<int> mid_low, mid_high;\n            int mid = N / 2;\n            for (int i = mid - quarter / 2; i < mid && i >= 0; i++) {\n                mid_low.push_back(sorted_items[i].second);\n            }\n            for (int i = mid; i < mid + quarter / 2 && i < N; i++) {\n                mid_high.push_back(sorted_items[i].second);\n            }\n            \n            if (!mid_low.empty() && !mid_high.empty()) {\n                char result = query(mid_low, mid_high);\n                queries_used++;\n                update_weights(mid_low, mid_high, result);\n            }\n        }\n    }\n    \n    // Final partitioning using greedy approach\n    vector<pair<double, int>> final_sorted;\n    for (int i = 0; i < N; i++) {\n        final_sorted.push_back({weight_estimate[i], i});\n    }\n    sort(final_sorted.begin(), final_sorted.end(), greater<pair<double, int>>());\n    \n    vector<double> group_sums(D, 0);\n    vector<int> assignment(N);\n    \n    // Assign heaviest items first to balance groups\n    for (auto [weight, item] : final_sorted) {\n        // Find group with minimum current sum\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < group_sums[min_group]) {\n                min_group = g;\n            }\n        }\n        \n        assignment[item] = min_group;\n        group_sums[min_group] += weight;\n    }\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}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    // Read initial configuration\n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        int stack_size = n / m;\n        for (int j = 0; j < stack_size; j++) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    // Process boxes in ascending order\n    for (int target = 1; target <= n; target++) {\n        // Find current position of target box\n        int target_stack = -1;\n        int target_pos = -1;\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    target_stack = i;\n                    target_pos = j;\n                    break;\n                }\n            }\n            if (target_stack != -1) break;\n        }\n        \n        // If target is not at the top, move boxes above it\n        if (target_pos < (int)stacks[target_stack].size() - 1) {\n            // Find best destination stack (prefer empty or smaller stacks)\n            int best_dest = -1;\n            int min_size = INT_MAX;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == target_stack) continue;\n                if ((int)stacks[i].size() < min_size) {\n                    min_size = stacks[i].size();\n                    best_dest = i;\n                }\n            }\n            \n            // Move the box directly above target and all boxes above it\n            int box_to_move = stacks[target_stack][target_pos + 1];\n            \n            // Record the move operation\n            operations.push_back({box_to_move, best_dest + 1}); // +1 for 1-indexed\n            \n            // Update stacks - move boxes from target_pos+1 to end\n            vector<int> moved_boxes;\n            for (int j = target_pos + 1; j < (int)stacks[target_stack].size(); j++) {\n                moved_boxes.push_back(stacks[target_stack][j]);\n            }\n            \n            stacks[target_stack].resize(target_pos + 1);\n            \n            for (int box : moved_boxes) {\n                stacks[best_dest].push_back(box);\n            }\n        }\n        \n        // Now target is at the top, carry it out\n        operations.push_back({target, 0});\n        stacks[target_stack].pop_back();\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nconst int MAX_LENGTH = 100000;\nconst int DIJ[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\nconst char DIR[4] = {'R', 'D', 'L', 'U'};\n\nbool canMove(int i, int j, int dir) {\n    int di = DIJ[dir][0], dj = DIJ[dir][1];\n    int i2 = i + di, j2 = j + dj;\n    \n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    \n    if (di == 0) {\n        return v[i][min(j, j2)] == '0';\n    } else {\n        return h[min(i, i2)][j] == '0';\n    }\n}\n\n// BFS to find shortest path\nvector<int> findPath(int si, int sj, int ei, int ej) {\n    queue<tuple<int, int, vector<int>>> q;\n    set<pair<int, int>> vis;\n    q.push({si, sj, {}});\n    vis.insert({si, sj});\n    \n    while (!q.empty()) {\n        auto [ci, cj, path] = q.front();\n        q.pop();\n        \n        if (ci == ei && cj == ej) {\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            if (vis.count({ni, nj})) continue;\n            vis.insert({ni, nj});\n            auto newPath = path;\n            newPath.push_back(dir);\n            q.push({ni, nj, newPath});\n        }\n    }\n    return {};\n}\n\nint main() {\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    d.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N - 1; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\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    // Create base route visiting all squares using DFS\n    vector<int> route;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            int di = DIJ[dir][0], dj = DIJ[dir][1];\n            int i2 = i + di, j2 = j + dj;\n            \n            if (i2 >= 0 && i2 < N && j2 >= 0 && j2 < N && !visited[i2][j2] && canMove(i, j, dir)) {\n                route.push_back(dir);\n                dfs(i2, j2);\n                route.push_back((dir + 2) % 4);\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Use remaining moves to revisit high-dirt squares\n    if (route.size() < MAX_LENGTH) {\n        // Create priority queue of squares by dirt value\n        priority_queue<tuple<int, int, int>> pq;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != 0 || j != 0) { // Don't add origin\n                    pq.push({d[i][j], i, j});\n                }\n            }\n        }\n        \n        int curI = 0, curJ = 0;\n        \n        // Add extra visits to high-dirt squares\n        while (!pq.empty() && route.size() < MAX_LENGTH - 1000) {\n            auto [dirt, ti, tj] = pq.top();\n            pq.pop();\n            \n            // Find path to target square and back\n            auto pathTo = findPath(curI, curJ, ti, tj);\n            auto pathBack = findPath(ti, tj, 0, 0);\n            \n            if (!pathTo.empty() && !pathBack.empty() && \n                route.size() + pathTo.size() + pathBack.size() <= MAX_LENGTH) {\n                for (int dir : pathTo) route.push_back(dir);\n                for (int dir : pathBack) route.push_back(dir);\n                curI = 0;\n                curJ = 0;\n                \n                // Re-add high-dirt squares for multiple visits\n                if (dirt > 100 && route.size() < MAX_LENGTH - 5000) {\n                    pq.push({dirt / 2, ti, tj});\n                }\n            }\n        }\n    }\n    \n    // Convert route to string\n    string result;\n    for (int dir : route) {\n        result += DIR[dir];\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int i, j;\n};\n\nint manhattan(Position a, Position b) {\n    return abs(a.i - b.i) + abs(a.j - b.j) + 1;\n}\n\n// Calculate overlap between suffix of a and prefix of b\nint getOverlap(const string& a, const string& b) {\n    int maxOverlap = min((int)a.length(), (int)b.length()) - 1;\n    for (int i = maxOverlap; i >= 1; i--) {\n        if (a.substr(a.length() - i) == b.substr(0, i)) {\n            return i;\n        }\n    }\n    return 0;\n}\n\n// Build superstring using greedy approach with maximum overlap\nstring buildSuperstring(vector<string>& words) {\n    int n = words.size();\n    \n    // Precompute all overlaps\n    vector<vector<int>> overlaps(n, vector<int>(n, 0));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (i != j) {\n                overlaps[i][j] = getOverlap(words[i], words[j]);\n            }\n        }\n    }\n    \n    // Find the best starting word and build chain greedily\n    string bestResult = \"\";\n    \n    for (int start = 0; start < min(n, 10); start++) {  // Try multiple starting points\n        vector<bool> used(n, false);\n        vector<int> order;\n        order.push_back(start);\n        used[start] = true;\n        \n        // Greedily add words with maximum overlap\n        for (int count = 1; count < n; count++) {\n            int lastIdx = order.back();\n            int bestNext = -1;\n            int bestOverlap = -1;\n            \n            for (int i = 0; i < n; i++) {\n                if (!used[i] && overlaps[lastIdx][i] > bestOverlap) {\n                    bestOverlap = overlaps[lastIdx][i];\n                    bestNext = i;\n                }\n            }\n            \n            if (bestNext == -1) {\n                for (int i = 0; i < n; i++) {\n                    if (!used[i]) {\n                        bestNext = i;\n                        break;\n                    }\n                }\n            }\n            \n            order.push_back(bestNext);\n            used[bestNext] = true;\n        }\n        \n        // Build superstring from order\n        string result = words[order[0]];\n        for (int i = 1; i < n; i++) {\n            int overlap = overlaps[order[i-1]][order[i]];\n            result += words[order[i]].substr(overlap);\n        }\n        \n        if (bestResult.empty() || result.length() < bestResult.length()) {\n            bestResult = result;\n        }\n    }\n    \n    return bestResult;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    vector<vector<Position>> charPositions(26);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            charPositions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n    \n    vector<string> words(M);\n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    // Build superstring\n    string superstring = buildSuperstring(words);\n    \n    // Type the superstring with minimal cost using greedy nearest neighbor\n    vector<pair<int, int>> moves;\n    Position currentPos = {si, sj};\n    \n    for (char c : superstring) {\n        int charIdx = c - 'A';\n        \n        // Find nearest position with character c\n        Position bestPos = charPositions[charIdx][0];\n        int bestCost = manhattan(currentPos, bestPos);\n        \n        for (const Position& pos : charPositions[charIdx]) {\n            int cost = manhattan(currentPos, pos);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestPos = pos;\n            }\n        }\n        \n        moves.push_back({bestPos.i, bestPos.j});\n        currentPos = bestPos;\n        \n        // Safety check for operation limit\n        if (moves.size() >= 5000) break;\n    }\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    bool operator<(const Point& o) const { return tie(i,j) < tie(o.i,o.j); }\n};\n\nclass OilExplorer {\n    int N, M;\n    double eps;\n    vector<vector<Point>> oilShapes;\n    vector<vector<int>> drilled; // -1=unknown, >=0=drilled value\n    set<Point> confirmedOil;\n    \n    int queryDrill(int i, int j) {\n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        int v; cin >> v;\n        drilled[i][j] = v;\n        if (v > 0) confirmedOil.insert({i, j});\n        return v;\n    }\n    \n    int queryDivine(const vector<Point>& pts) {\n        cout << \"q \" << pts.size();\n        for (auto& p : pts) cout << \" \" << p.i << \" \" << p.j;\n        cout << endl;\n        cout.flush();\n        int v; cin >> v;\n        return v;\n    }\n    \n    bool submitAnswer() {\n        cout << \"a \" << confirmedOil.size();\n        for (auto& p : confirmedOil) cout << \" \" << p.i << \" \" << p.j;\n        cout << endl;\n        cout.flush();\n        int result; cin >> result;\n        return result == 1;\n    }\n    \n    void hierarchicalSearch() {\n        // Start with quadrants\n        int mid = N/2;\n        vector<vector<Point>> quadrants = {\n            {}, {}, {}, {}\n        };\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int q = (i >= mid ? 2 : 0) + (j >= mid ? 1 : 0);\n                quadrants[q].push_back({i, j});\n            }\n        }\n        \n        // Divine each quadrant\n        vector<int> quadrantSums;\n        for (auto& q : quadrants) {\n            if (q.size() >= 2) {\n                quadrantSums.push_back(queryDivine(q));\n            } else {\n                quadrantSums.push_back(0);\n            }\n        }\n        \n        // Focus on promising quadrants\n        for (int q = 0; q < 4; q++) {\n            if (quadrantSums[q] > 0) {\n                // Subdivide and search\n                recursiveSearch(quadrants[q], quadrantSums[q]);\n            }\n        }\n        \n        // Fill gaps with drilling\n        vector<Point> candidates;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] == -1) {\n                    // Check if adjacent to confirmed oil\n                    bool adjacent = false;\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (abs(di) + abs(dj) != 1) continue;\n                            int ni = i + di, nj = j + dj;\n                            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                                if (confirmedOil.count({ni, nj})) {\n                                    adjacent = true;\n                                }\n                            }\n                        }\n                    }\n                    if (adjacent) candidates.push_back({i, j});\n                }\n            }\n        }\n        \n        // Drill high-priority candidates\n        for (auto& p : candidates) {\n            queryDrill(p.i, p.j);\n        }\n    }\n    \n    void recursiveSearch(vector<Point>& region, int expectedSum) {\n        if (region.size() <= 4 || expectedSum == 0) {\n            // Small region or no oil - drill directly\n            for (auto& p : region) {\n                if (drilled[p.i][p.j] == -1 && expectedSum > 0) {\n                    queryDrill(p.i, p.j);\n                }\n            }\n            return;\n        }\n        \n        // Binary split\n        vector<Point> left, right;\n        for (int i = 0; i < region.size(); i++) {\n            if (i < region.size()/2) left.push_back(region[i]);\n            else right.push_back(region[i]);\n        }\n        \n        if (left.size() >= 2) {\n            int leftSum = queryDivine(left);\n            if (leftSum > 0) recursiveSearch(left, leftSum);\n        }\n        \n        if (right.size() >= 2) {\n            int rightSum = queryDivine(right);\n            if (rightSum > 0) recursiveSearch(right, rightSum);\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> M >> eps;\n        \n        oilShapes.resize(M);\n        for (int m = 0; m < M; m++) {\n            int d; cin >> d;\n            for (int k = 0; k < d; k++) {\n                int i, j; cin >> i >> j;\n                oilShapes[m].push_back({i, j});\n            }\n        }\n        \n        drilled.assign(N, vector<int>(N, -1));\n        \n        hierarchicalSearch();\n        \n        // Make attempts until correct\n        int attempts = 0;\n        while (!submitAnswer() && attempts < 5) {\n            // Drill a few more uncertain squares\n            for (int i = 0; i < N && attempts < 5; i++) {\n                for (int j = 0; j < N && attempts < 5; j++) {\n                    if (drilled[i][j] == -1) {\n                        queryDrill(i, j);\n                        if (!submitAnswer()) attempts++;\n                        else return;\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    OilExplorer explorer;\n    explorer.solve();\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Strategy: Use horizontal strips with stable heights across days\n    // Only vary widths to meet daily requirements\n    \n    // Calculate average area needs for each position\n    vector<double> avg_areas(N, 0);\n    for (int k = 0; k < N; k++) {\n        for (int d = 0; d < D; d++) {\n            avg_areas[k] += a[d][k];\n        }\n        avg_areas[k] /= D;\n    }\n    \n    // Determine stable heights based on average proportions\n    double total_avg = accumulate(avg_areas.begin(), avg_areas.end(), 0.0);\n    vector<int> heights(N);\n    int remaining_height = W;\n    \n    for (int k = 0; k < N; k++) {\n        if (k == N - 1) {\n            // Last reservation gets remaining height\n            heights[k] = remaining_height;\n        } else {\n            // Proportional allocation\n            double proportion = avg_areas[k] / total_avg;\n            int h = max(1, (int)(W * proportion + 0.5));\n            \n            // Ensure we leave space for remaining reservations\n            h = min(h, remaining_height - (N - k - 1));\n            heights[k] = h;\n            remaining_height -= h;\n        }\n    }\n    \n    // Adjust heights to ensure they can accommodate max requirements\n    for (int k = 0; k < N; k++) {\n        int max_area = 0;\n        for (int d = 0; d < D; d++) {\n            max_area = max(max_area, a[d][k]);\n        }\n        \n        // Ensure height allows for reasonable width\n        int min_height = max(1, (int)sqrt(max_area / 2));\n        if (heights[k] < min_height) {\n            // Try to steal height from larger allocations\n            int deficit = min_height - heights[k];\n            for (int j = N - 1; j > k && deficit > 0; j--) {\n                int available = max(0, heights[j] - 1);\n                int transfer = min(available, deficit);\n                heights[j] -= transfer;\n                heights[k] += transfer;\n                deficit -= transfer;\n            }\n        }\n    }\n    \n    // Output rectangles for each day\n    for (int d = 0; d < D; d++) {\n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            int height = heights[k];\n            \n            // Calculate required width\n            int width = (a[d][k] + height - 1) / height; // Ceiling division\n            width = min(width, W); // Cap at grid width\n            \n            // Output rectangle: top-left (y, 0) to bottom-right (y+height, width)\n            cout << y << \" \" << 0 << \" \" << (y + height) << \" \" << width << \"\\n\";\n            y += height;\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<long long>>> stamps(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    // Greedy optimization\n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        long long best_score_increase = 0;\n        \n        // Try all possible stamps and positions\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                    // Calculate the score increase for this operation\n                    long long score_increase = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long old_val = board[p + i][q + j];\n                            long long new_val = old_val + stamps[m][i][j];\n                            score_increase += (new_val % MOD) - (old_val % MOD);\n                        }\n                    }\n                    \n                    if (score_increase > best_score_increase) {\n                        best_score_increase = score_increase;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // If no operation increases the score significantly, stop\n        if (best_score_increase <= 0) {\n            break;\n        }\n        \n        // Apply the best operation\n        operations.push_back({best_m, best_p, best_q});\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                board[best_p + i][best_q + j] += stamps[best_m][i][j];\n            }\n        }\n    }\n    \n    // Output the operations\n    cout << operations.size() << \"\\n\";\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 2000;\n\nstruct Position {\n    int r, c;\n    bool operator==(const Position& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nstruct State {\n    vector<vector<int>> grid; // -1 if empty, container number otherwise\n    vector<Position> crane_pos;\n    vector<int> crane_holding; // -1 if not holding\n    vector<int> next_receive; // next container index to receive at each gate\n    vector<int> next_dispatch; // next expected container at each dispatch gate\n    vector<queue<int>> receiving_queues; // containers waiting at each receiving gate\n    \n    State(const vector<vector<int>>& A) : \n        grid(N, vector<int>(N, -1)),\n        crane_pos(N),\n        crane_holding(N, -1),\n        next_receive(N, 0),\n        next_dispatch(N),\n        receiving_queues(N) {\n        \n        // Initialize crane positions\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n        }\n        \n        // Initialize dispatch expectations\n        for (int i = 0; i < N; i++) {\n            next_dispatch[i] = i * N;\n        }\n        \n        // Initialize receiving queues\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                receiving_queues[i].push(A[i][j]);\n            }\n        }\n    }\n    \n    bool canMove(int crane, Position newPos, bool isLarge) {\n        if (newPos.r < 0 || newPos.r >= N || newPos.c < 0 || newPos.c >= N) return false;\n        \n        // Check for crane collision\n        for (int i = 0; i < N; i++) {\n            if (i != crane && crane_pos[i] == newPos) return false;\n        }\n        \n        // If small crane carrying container, can't move to occupied square\n        if (!isLarge && crane_holding[crane] != -1 && grid[newPos.r][newPos.c] != -1) {\n            return false;\n        }\n        \n        return true;\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state(A);\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        vector<char> actions(N, '.');\n        \n        // Step 1: Receive containers\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty() && \n                state.grid[i][0] == -1) {\n                bool crane_holding_here = false;\n                for (int j = 0; j < N; j++) {\n                    if (state.crane_pos[j].r == i && state.crane_pos[j].c == 0 && \n                        state.crane_holding[j] != -1) {\n                        crane_holding_here = true;\n                        break;\n                    }\n                }\n                if (!crane_holding_here) {\n                    state.grid[i][0] = state.receiving_queues[i].front();\n                    state.receiving_queues[i].pop();\n                }\n            }\n        }\n        \n        // Step 2: Decide crane actions\n        for (int crane = 0; crane < N; crane++) {\n            bool isLarge = (crane == 0);\n            Position pos = state.crane_pos[crane];\n            \n            // If holding a container\n            if (state.crane_holding[crane] != -1) {\n                int container = state.crane_holding[crane];\n                int target_row = container / N;\n                \n                // Try to move towards target dispatch gate\n                if (pos.c < N - 1) {\n                    Position newPos = {pos.r, pos.c + 1};\n                    if (state.canMove(crane, newPos, isLarge)) {\n                        actions[crane] = 'R';\n                    } else if (pos.r < target_row) {\n                        newPos = {pos.r + 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'D';\n                        }\n                    } else if (pos.r > target_row) {\n                        newPos = {pos.r - 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'U';\n                        }\n                    }\n                } else if (pos.c == N - 1 && pos.r == target_row) {\n                    // At dispatch gate\n                    if (state.grid[pos.r][pos.c] == -1) {\n                        actions[crane] = 'Q';\n                    }\n                }\n            } else {\n                // Not holding container\n                // Try to pick up if at a position with container\n                if (state.grid[pos.r][pos.c] != -1) {\n                    actions[crane] = 'P';\n                } else {\n                    // Move towards receiving gates\n                    if (pos.c > 0) {\n                        Position newPos = {pos.r, pos.c - 1};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'L';\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Execute actions\n        vector<Position> new_positions = state.crane_pos;\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            Position& pos = state.crane_pos[crane];\n            \n            if (action == 'P') {\n                if (state.grid[pos.r][pos.c] != -1 && state.crane_holding[crane] == -1) {\n                    state.crane_holding[crane] = state.grid[pos.r][pos.c];\n                    state.grid[pos.r][pos.c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (state.crane_holding[crane] != -1 && state.grid[pos.r][pos.c] == -1) {\n                    state.grid[pos.r][pos.c] = state.crane_holding[crane];\n                    state.crane_holding[crane] = -1;\n                }\n            } else if (action == 'U') {\n                new_positions[crane] = {pos.r - 1, pos.c};\n            } else if (action == 'D') {\n                new_positions[crane] = {pos.r + 1, pos.c};\n            } else if (action == 'L') {\n                new_positions[crane] = {pos.r, pos.c - 1};\n            } else if (action == 'R') {\n                new_positions[crane] = {pos.r, pos.c + 1};\n            }\n            \n            commands[crane] += action;\n        }\n        state.crane_pos = new_positions;\n        \n        // Step 3: Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (state.grid[i][N-1] != -1) {\n                state.grid[i][N-1] = -1;\n            }\n        }\n        \n        // Check if all done\n        bool all_done = true;\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty()) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) {\n            bool grid_empty = true;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) {\n                        grid_empty = false;\n                        break;\n                    }\n                }\n            }\n            if (grid_empty) break;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <map>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_OPS = 100000;\nconst int INF = 1e9;\n\nvector<string> operations;\nint grid[N][N];\nint cur_r = 0, cur_c = 0;\nint loaded = 0;\n\n// Direction vectors\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\n// BFS to find shortest path\nvector<int> find_path(int sr, int sc, int tr, int tc) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    \n    dist[sr][sc] = 0;\n    q.push({sr, sc});\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        \n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == INF) {\n                dist[nr][nc] = dist[r][c] + 1;\n                parent[nr][nc] = d;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path;\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int d = parent[r][c];\n        path.push_back(d);\n        r -= dr[d];\n        c -= dc[d];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Move to target location\nvoid move_to(int tr, int tc) {\n    if (cur_r == tr && cur_c == tc) return;\n    \n    vector<int> path = find_path(cur_r, cur_c, tr, tc);\n    for (int d : path) {\n        operations.push_back(string(1, dir_char[d]));\n        cur_r += dr[d];\n        cur_c += dc[d];\n    }\n}\n\n// Load soil from current position\nvoid load_soil(int amount) {\n    if (amount <= 0) return;\n    operations.push_back(\"+\" + to_string(amount));\n    grid[cur_r][cur_c] -= amount;\n    loaded += amount;\n}\n\n// Unload soil to current position  \nvoid unload_soil(int amount) {\n    if (amount <= 0 || loaded <= 0) return;\n    amount = min(amount, loaded);\n    operations.push_back(\"-\" + to_string(amount));\n    grid[cur_r][cur_c] += amount;\n    loaded -= amount;\n}\n\nint manhattan_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    // Read grid\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    // Process soil movements using a greedy nearest-neighbor approach\n    while (operations.size() < MAX_OPS - 1000) {\n        bool found = false;\n        \n        // Find the closest positive-negative pair\n        int best_sr = -1, best_sc = -1, best_dr = -1, best_dc = -1;\n        int best_dist = INF;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] > 0) {\n                    // Find nearest negative cell to this positive cell\n                    for (int di = 0; di < N; di++) {\n                        for (int dj = 0; dj < N; dj++) {\n                            if (grid[di][dj] < 0) {\n                                int dist = manhattan_dist(i, j, di, dj);\n                                // Prefer closer pairs and also consider current position\n                                int total_dist = manhattan_dist(cur_r, cur_c, i, j) + dist;\n                                if (total_dist < best_dist) {\n                                    best_dist = total_dist;\n                                    best_sr = i; best_sc = j;\n                                    best_dr = di; best_dc = dj;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (best_sr == -1) break;\n        \n        // Transport soil from source to destination\n        move_to(best_sr, best_sc);\n        int amount = min(grid[best_sr][best_sc], -grid[best_dr][best_dc]);\n        load_soil(amount);\n        \n        move_to(best_dr, best_dc);\n        unload_soil(amount);\n        \n        found = true;\n        \n        // Check if we're done\n        bool all_zero = true;\n        for (int i = 0; i < N && all_zero; i++) {\n            for (int j = 0; j < N && all_zero; j++) {\n                if (grid[i][j] != 0) all_zero = false;\n            }\n        }\n        if (all_zero) break;\n        \n        if (!found) break;\n    }\n    \n    // Output operations\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 <random>\n#include <numeric>\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));\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    random_device rd;\n    mt19937 gen(rd());\n    \n    for (int t = 0; t < T; t++) {\n        // Calculate values for each seed\n        vector<pair<int, int>> seed_values;\n        for (int i = 0; i < seed_count; i++) {\n            int value = 0;\n            for (int j = 0; j < M; j++) {\n                value += X[i][j];\n            }\n            seed_values.push_back({value, i});\n        }\n        \n        // Sort seeds by value (descending)\n        sort(seed_values.begin(), seed_values.end(), greater<pair<int,int>>());\n        \n        // Create priority order for grid positions (center positions first)\n        vector<pair<int, pair<int,int>>> positions;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                int neighbors = 0;\n                if (i > 0) neighbors++;\n                if (i < N-1) neighbors++;\n                if (j > 0) neighbors++;\n                if (j < N-1) neighbors++;\n                positions.push_back({neighbors, {i, j}});\n            }\n        }\n        \n        // Sort positions by number of neighbors (descending)\n        sort(positions.begin(), positions.end(), greater<pair<int,pair<int,int>>>());\n        \n        // For later iterations, add some randomization\n        if (t >= T/2) {\n            // Shuffle top seeds a bit to maintain diversity\n            int shuffle_size = min(N*N/2, (int)seed_values.size());\n            shuffle(seed_values.begin(), seed_values.begin() + shuffle_size, gen);\n        }\n        \n        // Create placement grid\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Place best seeds in best positions\n        for (int idx = 0; idx < N*N; idx++) {\n            int seed_idx = seed_values[idx].second;\n            int pos_i = positions[idx].second.first;\n            int pos_j = positions[idx].second.second;\n            A[pos_i][pos_j] = seed_idx;\n            used[seed_idx] = true;\n        }\n        \n        // Output placement\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                } else {\n                    cout << endl;\n                }\n            }\n        }\n        cout.flush();\n        \n        // Read new generation of seeds\n        X.clear();\n        X.resize(seed_count, vector<int>(M));\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {0, 1, 0, -1};\nconst int dy[] = {1, 0, -1, 0};\nconst char dirChar[] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& p) const { return x == p.x && y == p.y; }\n    int dist(const Point& p) const { return abs(x - p.x) + abs(y - p.y); }\n};\n\nstruct Arm {\n    int V;\n    vector<int> parent;\n    vector<int> length;\n    vector<int> direction;  // 0=right, 1=down, 2=left, 3=up\n    Point root;\n    vector<bool> isLeaf;\n    vector<Point> positions;\n    \n    void calculatePositions() {\n        positions.resize(V);\n        positions[0] = root;\n        for (int v = 1; v < V; v++) {\n            Point p = positions[parent[v]];\n            positions[v] = Point(p.x + dx[direction[v]] * length[v],\n                                p.y + dy[direction[v]] * length[v]);\n        }\n    }\n    \n    bool isValid(int N) {\n        for (auto& p : positions) {\n            if (p.x < 0 || p.x >= N || p.y < 0 || p.y >= N) {\n                for (int i = 1; i < V; i++) {\n                    if (isLeaf[i] && positions[i] == p) return false;\n                }\n            }\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> grid(N), target(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    for (int i = 0; i < N; i++) cin >> target[i];\n    \n    vector<Point> sources, targets;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') sources.push_back(Point(i, j));\n            if (target[i][j] == '1') targets.push_back(Point(i, j));\n        }\n    }\n    \n    // Design arm: star pattern with center and multiple arms\n    Arm arm;\n    arm.V = min(V, 7);\n    arm.parent.resize(arm.V);\n    arm.length.resize(arm.V);\n    arm.direction.resize(arm.V, 0);\n    arm.isLeaf.resize(arm.V, true);\n    arm.positions.resize(arm.V);\n    \n    arm.parent[0] = -1;\n    arm.isLeaf[0] = false;\n    \n    // Create arms extending from root\n    for (int i = 1; i < arm.V; i++) {\n        arm.parent[i] = 0;\n        arm.length[i] = min(3, (i + 1) / 2);\n        arm.direction[i] = (i - 1) % 4;\n    }\n    \n    arm.root = Point(N/2, N/2);\n    \n    // Output arm design\n    cout << arm.V << \"\\n\";\n    for (int i = 1; i < arm.V; i++) {\n        cout << arm.parent[i] << \" \" << arm.length[i] << \"\\n\";\n    }\n    cout << arm.root.x << \" \" << arm.root.y << \"\\n\";\n    \n    // Simulation\n    vector<bool> sourceDone(M, false);\n    vector<bool> targetDone(M, false);\n    vector<int> holding(arm.V, -1);\n    vector<string> operations;\n    \n    auto currentGrid = grid;\n    \n    for (int turn = 0; turn < 50000; turn++) {\n        if (count(targetDone.begin(), targetDone.end(), true) == M) break;\n        \n        arm.calculatePositions();\n        string op(2 * arm.V, '.');\n        \n        // Try to pick up or place takoyaki\n        for (int v = 1; v < arm.V; v++) {\n            if (!arm.isLeaf[v]) continue;\n            \n            Point pos = arm.positions[v];\n            if (pos.x < 0 || pos.x >= N || pos.y < 0 || pos.y >= N) continue;\n            \n            if (holding[v] == -1) {\n                // Try to pick up\n                for (int i = 0; i < M; i++) {\n                    if (!sourceDone[i] && sources[i] == pos && currentGrid[pos.x][pos.y] == '1') {\n                        op[arm.V + v] = 'P';\n                        holding[v] = i;\n                        sourceDone[i] = true;\n                        currentGrid[pos.x][pos.y] = '0';\n                        break;\n                    }\n                }\n            } else {\n                // Try to place\n                for (int i = 0; i < M; i++) {\n                    if (!targetDone[i] && targets[i] == pos && currentGrid[pos.x][pos.y] == '0') {\n                        op[arm.V + v] = 'P';\n                        targetDone[i] = true;\n                        currentGrid[pos.x][pos.y] = '1';\n                        holding[v] = -1;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Find goal\n        Point goal(-1, -1);\n        int minDist = INT_MAX;\n        \n        // Look for source to pick up\n        for (int i = 0; i < M; i++) {\n            if (!sourceDone[i]) {\n                int d = arm.root.dist(sources[i]);\n                if (d < minDist) {\n                    minDist = d;\n                    goal = sources[i];\n                }\n            }\n        }\n        \n        // Look for target to deliver\n        for (int v = 1; v < arm.V; v++) {\n            if (holding[v] != -1) {\n                for (int i = 0; i < M; i++) {\n                    if (!targetDone[i]) {\n                        int d = arm.root.dist(targets[i]);\n                        if (d < minDist - 2) {\n                            minDist = d;\n                            goal = targets[i];\n                        }\n                    }\n                }\n                break;\n            }\n        }\n        \n        // Move towards goal\n        if (goal.x != -1) {\n            int newX = arm.root.x;\n            int newY = arm.root.y;\n            \n            if (goal.x < arm.root.x && arm.root.x > 0) {\n                newX--;\n                op[0] = 'U';\n            } else if (goal.x > arm.root.x && arm.root.x < N-1) {\n                newX++;\n                op[0] = 'D';\n            } else if (goal.y < arm.root.y && arm.root.y > 0) {\n                newY--;\n                op[0] = 'L';\n            } else if (goal.y > arm.root.y && arm.root.y < N-1) {\n                newY++;\n                op[0] = 'R';\n            }\n            \n            if (op[0] != '.') {\n                arm.root.x = newX;\n                arm.root.y = newY;\n            }\n        }\n        \n        // Adjust arm directions\n        if (turn % 5 == 0) {\n            for (int v = 1; v < arm.V; v++) {\n                if (goal.x != -1) {\n                    Point pos = arm.positions[v];\n                    int bestDir = arm.direction[v];\n                    int bestDist = pos.dist(goal);\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point newPos(arm.positions[arm.parent[v]].x + dx[d] * arm.length[v],\n                                   arm.positions[arm.parent[v]].y + dy[d] * arm.length[v]);\n                        int dist = newPos.dist(goal);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                    \n                    if (bestDir != arm.direction[v]) {\n                        int diff = (bestDir - arm.direction[v] + 4) % 4;\n                        if (diff == 1) {\n                            op[v] = 'R';\n                            arm.direction[v] = bestDir;\n                        } else if (diff == 3) {\n                            op[v] = 'L';\n                            arm.direction[v] = bestDir;\n                        }\n                    }\n                }\n            }\n        }\n        \n        operations.push_back(op);\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int MAX_VERTICES = 1000;\nconst int MAX_EDGE_LENGTH = 400000;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nclass Solution {\nprivate:\n    int N;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    \n    struct Rectangle {\n        int x1, y1, x2, y2;\n        int score;\n        Rectangle() : x1(0), y1(0), x2(1000), y2(1000), score(0) {}\n        Rectangle(int x1, int y1, int x2, int y2, int s) : x1(x1), y1(y1), x2(x2), y2(y2), score(s) {}\n    };\n    \npublic:\n    void solve() {\n        cin >> N;\n        mackerels.resize(N);\n        sardines.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> mackerels[i].x >> mackerels[i].y;\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> sardines[i].x >> sardines[i].y;\n        }\n        \n        // Find optimal rectangle\n        Rectangle best_rect = findBestRectangle();\n        \n        // Try to refine with local adjustments\n        best_rect = refineRectangle(best_rect);\n        \n        // Output as polygon\n        cout << \"4\\n\";\n        cout << best_rect.x1 << \" \" << best_rect.y1 << \"\\n\";\n        cout << best_rect.x2 << \" \" << best_rect.y1 << \"\\n\";\n        cout << best_rect.x2 << \" \" << best_rect.y2 << \"\\n\";\n        cout << best_rect.x1 << \" \" << best_rect.y2 << \"\\n\";\n    }\n    \nprivate:\n    int calculateScore(int x1, int y1, int x2, int y2) {\n        int score = 0;\n        for (const auto& p : mackerels) {\n            if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                score++;\n            }\n        }\n        for (const auto& p : sardines) {\n            if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                score--;\n            }\n        }\n        return score;\n    }\n    \n    Rectangle findBestRectangle() {\n        Rectangle best;\n        \n        // Create sorted lists of coordinates for efficient searching\n        vector<int> x_coords, y_coords;\n        for (const auto& p : mackerels) {\n            x_coords.push_back(p.x);\n            y_coords.push_back(p.y);\n        }\n        sort(x_coords.begin(), x_coords.end());\n        sort(y_coords.begin(), y_coords.end());\n        x_coords.erase(unique(x_coords.begin(), x_coords.end()), x_coords.end());\n        y_coords.erase(unique(y_coords.begin(), y_coords.end()), y_coords.end());\n        \n        // Add boundary coordinates\n        x_coords.insert(x_coords.begin(), 0);\n        x_coords.push_back(MAX_COORD);\n        y_coords.insert(y_coords.begin(), 0);\n        y_coords.push_back(MAX_COORD);\n        \n        // Sample coordinates to reduce computation\n        vector<int> x_sample, y_sample;\n        int x_step = max(1, (int)x_coords.size() / 100);\n        int y_step = max(1, (int)y_coords.size() / 100);\n        \n        for (int i = 0; i < x_coords.size(); i += x_step) {\n            x_sample.push_back(x_coords[i]);\n        }\n        for (int i = 0; i < y_coords.size(); i += y_step) {\n            y_sample.push_back(y_coords[i]);\n        }\n        \n        // Try different rectangles\n        for (int i1 = 0; i1 < x_sample.size(); i1++) {\n            for (int j1 = 0; j1 < y_sample.size(); j1++) {\n                int x1 = x_sample[i1];\n                int y1 = y_sample[j1];\n                \n                for (int i2 = i1 + 1; i2 < x_sample.size(); i2++) {\n                    int x2 = x_sample[i2];\n                    if ((x2 - x1) * 2 > MAX_EDGE_LENGTH) break;\n                    \n                    for (int j2 = j1 + 1; j2 < y_sample.size(); j2++) {\n                        int y2 = y_sample[j2];\n                        \n                        // Check edge length constraint\n                        if (2 * ((x2 - x1) + (y2 - y1)) > MAX_EDGE_LENGTH) break;\n                        \n                        int score = calculateScore(x1, y1, x2, y2);\n                        if (score > best.score) {\n                            best = Rectangle(x1, y1, x2, y2, score);\n                        }\n                    }\n                }\n            }\n        }\n        \n        return best;\n    }\n    \n    Rectangle refineRectangle(const Rectangle& rect) {\n        Rectangle current = rect;\n        bool improved = true;\n        \n        // Try to shrink/expand edges\n        while (improved) {\n            improved = false;\n            Rectangle candidate = current;\n            \n            // Try adjusting each edge\n            int deltas[] = {-1000, -500, -100, 100, 500, 1000};\n            \n            for (int d : deltas) {\n                // Adjust x1\n                if (current.x1 + d >= 0 && current.x1 + d < current.x2) {\n                    int new_score = calculateScore(current.x1 + d, current.y1, current.x2, current.y2);\n                    if (new_score > candidate.score) {\n                        candidate = Rectangle(current.x1 + d, current.y1, current.x2, current.y2, new_score);\n                        improved = true;\n                    }\n                }\n                \n                // Adjust x2\n                if (current.x2 + d <= MAX_COORD && current.x2 + d > current.x1) {\n                    if (2 * ((current.x2 + d - current.x1) + (current.y2 - current.y1)) <= MAX_EDGE_LENGTH) {\n                        int new_score = calculateScore(current.x1, current.y1, current.x2 + d, current.y2);\n                        if (new_score > candidate.score) {\n                            candidate = Rectangle(current.x1, current.y1, current.x2 + d, current.y2, new_score);\n                            improved = true;\n                        }\n                    }\n                }\n                \n                // Adjust y1\n                if (current.y1 + d >= 0 && current.y1 + d < current.y2) {\n                    int new_score = calculateScore(current.x1, current.y1 + d, current.x2, current.y2);\n                    if (new_score > candidate.score) {\n                        candidate = Rectangle(current.x1, current.y1 + d, current.x2, current.y2, new_score);\n                        improved = true;\n                    }\n                }\n                \n                // Adjust y2\n                if (current.y2 + d <= MAX_COORD && current.y2 + d > current.y1) {\n                    if (2 * ((current.x2 - current.x1) + (current.y2 + d - current.y1)) <= MAX_EDGE_LENGTH) {\n                        int new_score = calculateScore(current.x1, current.y1, current.x2, current.y2 + d);\n                        if (new_score > candidate.score) {\n                            candidate = Rectangle(current.x1, current.y1, current.x2, current.y2 + d, new_score);\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            \n            current = candidate;\n        }\n        \n        return current;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int idx;\n    double obs_w, obs_h;  // Observed dimensions\n    double est_w, est_h;  // Estimated true dimensions\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nclass Packer {\nprivate:\n    int N, T;\n    double sigma;\n    vector<Rectangle> rects;\n    vector<pair<double, double>> measurements;\n    \n    // Simulate placement to find actual positions\n    pair<vector<pair<int,int>>, pair<int,int>> simulatePlacement(const vector<Placement>& placements) {\n        vector<pair<int,int>> positions;\n        vector<pair<int,int>> sizes;\n        \n        for (const auto& p : placements) {\n            int w = p.r ? (int)rects[p.p].est_h : (int)rects[p.p].est_w;\n            int h = p.r ? (int)rects[p.p].est_w : (int)rects[p.p].est_h;\n            \n            int x = 0, y = 0;\n            \n            if (p.d == 'U') {\n                // Moving up from bottom\n                if (p.b == -1) {\n                    x = 0;\n                } else {\n                    x = positions[p.b].first + sizes[p.b].first;\n                }\n                y = 0;\n                \n                // Find actual y position (highest obstacle)\n                for (int i = 0; i < (int)positions.size(); i++) {\n                    if (!(x + w <= positions[i].first || x >= positions[i].first + sizes[i].first)) {\n                        y = max(y, positions[i].second + sizes[i].second);\n                    }\n                }\n            } else { // 'L'\n                // Moving left from right\n                if (p.b == -1) {\n                    y = 0;\n                } else {\n                    y = positions[p.b].second + sizes[p.b].second;\n                }\n                x = 0;\n                \n                // Find actual x position (rightmost obstacle)\n                for (int i = 0; i < (int)positions.size(); i++) {\n                    if (!(y + h <= positions[i].second || y >= positions[i].second + sizes[i].second)) {\n                        x = max(x, positions[i].first + sizes[i].first);\n                    }\n                }\n            }\n            \n            positions.push_back({x, y});\n            sizes.push_back({w, h});\n        }\n        \n        int maxX = 0, maxY = 0;\n        for (int i = 0; i < (int)positions.size(); i++) {\n            maxX = max(maxX, positions[i].first + sizes[i].first);\n            maxY = max(maxY, positions[i].second + sizes[i].second);\n        }\n        \n        return {positions, {maxX, maxY}};\n    }\n    \n    vector<Placement> createPacking(const vector<int>& order, const vector<bool>& rotations) {\n        vector<Placement> result;\n        \n        for (size_t i = 0; i < order.size(); i++) {\n            int idx = order[i];\n            \n            if (i == 0) {\n                // First rectangle at origin\n                result.push_back({idx, rotations[i] ? 1 : 0, -1, 'U'});\n            } else {\n                // Try to pack efficiently\n                // Alternate between U and L for variety\n                if (i % 2 == 1) {\n                    // Place to the right of previous\n                    result.push_back({idx, rotations[i] ? 1 : 0, (int)i-1, 'U'});\n                } else {\n                    // Place above previous\n                    result.push_back({idx, rotations[i] ? 1 : 0, (int)i-2, 'L'});\n                }\n            }\n        }\n        \n        return result;\n    }\n    \n    pair<int, int> query(const vector<Placement>& placements) {\n        cout << placements.size() << endl;\n        for (const auto& p : placements) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << endl;\n        }\n        cout.flush();\n        \n        int W, H;\n        cin >> W >> H;\n        measurements.push_back({W, H});\n        return {W, H};\n    }\n    \n    void updateEstimates() {\n        // Simple averaging of measurements to reduce noise\n        if (measurements.size() <= 1) return;\n        \n        double avgRatio = 0;\n        for (auto [W, H] : measurements) {\n            avgRatio += (double)W / H;\n        }\n        avgRatio /= measurements.size();\n        \n        // Adjust estimates slightly based on measured ratios\n        for (auto& rect : rects) {\n            double ratio = rect.est_w / rect.est_h;\n            rect.est_w = rect.obs_w * 0.8 + rect.est_w * 0.2;\n            rect.est_h = rect.obs_h * 0.8 + rect.est_h * 0.2;\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> T >> sigma;\n        rects.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            rects[i].idx = i;\n            cin >> rects[i].obs_w >> rects[i].obs_h;\n            rects[i].est_w = rects[i].obs_w;\n            rects[i].est_h = rects[i].obs_h;\n        }\n        \n        for (int turn = 0; turn < T; turn++) {\n            vector<int> order;\n            vector<bool> rotations;\n            \n            // Create order\n            for (int i = 0; i < N; i++) {\n                order.push_back(i);\n            }\n            \n            // Different strategies for different turns\n            if (turn < T/3) {\n                // Initial exploration: try different orderings\n                if (turn % 2 == 0) {\n                    sort(order.begin(), order.end(), [this](int a, int b) {\n                        return rects[a].est_w * rects[a].est_h > rects[b].est_w * rects[b].est_h;\n                    });\n                }\n            } else if (turn < 2*T/3) {\n                // Sort by height\n                sort(order.begin(), order.end(), [this](int a, int b) {\n                    return max(rects[a].est_w, rects[a].est_h) > max(rects[b].est_w, rects[b].est_h);\n                });\n            } else {\n                // Sort by width\n                sort(order.begin(), order.end(), [this](int a, int b) {\n                    return max(rects[a].est_w, rects[a].est_h) > max(rects[b].est_w, rects[b].est_h);\n                });\n            }\n            \n            // Decide rotations\n            for (int i = 0; i < N; i++) {\n                // Rotate if width > height to make it more vertical\n                rotations.push_back(rects[order[i]].est_w > rects[order[i]].est_h);\n            }\n            \n            auto placements = createPacking(order, rotations);\n            query(placements);\n            updateEstimates();\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.solve();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nlong long calculateScore(const vector<int>& parent, const vector<int>& beauty, int N) {\n    vector<int> depth(N);\n    \n    for (int i = 0; i < N; i++) {\n        if (parent[i] == -1) {\n            depth[i] = 0;\n        } else {\n            int curr = i;\n            int d = 0;\n            while (parent[curr] != -1) {\n                d++;\n                curr = parent[curr];\n            }\n            depth[i] = d;\n        }\n    }\n    \n    long long score = 1;\n    for (int i = 0; i < N; i++) {\n        score += (long long)(depth[i] + 1) * beauty[i];\n    }\n    return score;\n}\n\nvector<int> buildForestGreedy(int N, const vector<int>& beauty, const vector<vector<int>>& adj, int H) {\n    vector<int> parent(N, -2);\n    vector<int> depth(N, -1);\n    vector<bool> visited(N, false);\n    \n    // Sort vertices by beauty value (descending)\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return beauty[a] > beauty[b];\n    });\n    \n    // Build rooted forests\n    for (int root : order) {\n        if (visited[root]) continue;\n        \n        parent[root] = -1;\n        depth[root] = 0;\n        visited[root] = true;\n        \n        // BFS to build the tree\n        queue<int> q;\n        q.push(root);\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            if (depth[u] >= H) continue;\n            \n            // Sort unvisited neighbors by beauty value\n            vector<int> neighbors;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    neighbors.push_back(v);\n                }\n            }\n            sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                return beauty[a] > beauty[b];\n            });\n            \n            // Add neighbors as children\n            for (int v : neighbors) {\n                parent[v] = u;\n                depth[v] = depth[u] + 1;\n                visited[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    return parent;\n}\n\nvector<int> buildForestWeighted(int N, const vector<int>& beauty, const vector<vector<int>>& adj, int H) {\n    vector<int> parent(N, -2);\n    vector<int> depth(N, -1);\n    vector<bool> visited(N, false);\n    \n    // Sort vertices by beauty * degree\n    vector<int> order(N);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return beauty[a] * (int)adj[a].size() > beauty[b] * (int)adj[b].size();\n    });\n    \n    for (int root : order) {\n        if (visited[root]) continue;\n        \n        parent[root] = -1;\n        depth[root] = 0;\n        visited[root] = true;\n        \n        queue<int> q;\n        q.push(root);\n        \n        while (!q.empty()) {\n            int u = q.front();\n            q.pop();\n            \n            if (depth[u] >= H) continue;\n            \n            vector<int> neighbors;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    neighbors.push_back(v);\n                }\n            }\n            sort(neighbors.begin(), neighbors.end(), [&](int a, int b) {\n                return beauty[a] > beauty[b];\n            });\n            \n            for (int v : neighbors) {\n                parent[v] = u;\n                depth[v] = depth[u] + 1;\n                visited[v] = true;\n                q.push(v);\n            }\n        }\n    }\n    \n    return parent;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    vector<int> beauty(N);\n    for (int i = 0; i < N; i++) {\n        cin >> beauty[i];\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    }\n    \n    // Read coordinates (not used in our algorithm)\n    for (int i = 0; i < N; i++) {\n        int x, y;\n        cin >> x >> y;\n    }\n    \n    // Try multiple strategies\n    vector<int> bestParent;\n    long long bestScore = 0;\n    \n    // Strategy 1: Pure greedy by beauty\n    vector<int> parent1 = buildForestGreedy(N, beauty, adj, H);\n    long long score1 = calculateScore(parent1, beauty, N);\n    if (score1 > bestScore) {\n        bestScore = score1;\n        bestParent = parent1;\n    }\n    \n    // Strategy 2: Weighted by degree\n    vector<int> parent2 = buildForestWeighted(N, beauty, adj, H);\n    long long score2 = calculateScore(parent2, beauty, N);\n    if (score2 > bestScore) {\n        bestScore = score2;\n        bestParent = parent2;\n    }\n    \n    // Output the best solution\n    for (int i = 0; i < N; i++) {\n        cout << bestParent[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> operations;\n    \n    // Process each Oni\n    while (true) {\n        // Find an Oni to remove (prioritize those requiring fewer moves)\n        int best_i = -1, best_j = -1;\n        int best_cost = INT_MAX;\n        char best_dir = ' ';\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                // Check upward direction\n                bool up_safe = true;\n                for (int k = 0; k < i; k++) {\n                    if (board[k][j] == 'o') {\n                        up_safe = false;\n                        break;\n                    }\n                }\n                if (up_safe) {\n                    int cost = 2 * (i + 1);\n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = 'U';\n                    }\n                }\n                \n                // Check downward direction\n                bool down_safe = true;\n                for (int k = i + 1; k < N; k++) {\n                    if (board[k][j] == 'o') {\n                        down_safe = false;\n                        break;\n                    }\n                }\n                if (down_safe) {\n                    int cost = 2 * (N - i);\n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = 'D';\n                    }\n                }\n                \n                // Check leftward direction\n                bool left_safe = true;\n                for (int k = 0; k < j; k++) {\n                    if (board[i][k] == 'o') {\n                        left_safe = false;\n                        break;\n                    }\n                }\n                if (left_safe) {\n                    int cost = 2 * (j + 1);\n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = 'L';\n                    }\n                }\n                \n                // Check rightward direction\n                bool right_safe = true;\n                for (int k = j + 1; k < N; k++) {\n                    if (board[i][k] == 'o') {\n                        right_safe = false;\n                        break;\n                    }\n                }\n                if (right_safe) {\n                    int cost = 2 * (N - j);\n                    if (cost < best_cost) {\n                        best_cost = cost;\n                        best_i = i;\n                        best_j = j;\n                        best_dir = 'R';\n                    }\n                }\n            }\n        }\n        \n        if (best_i == -1) break; // All Oni removed\n        \n        // Execute the best move\n        if (best_dir == 'U') {\n            for (int t = 0; t <= best_i; t++) {\n                operations.push_back({'U', best_j});\n            }\n            for (int t = 0; t <= best_i; t++) {\n                operations.push_back({'D', best_j});\n            }\n        } else if (best_dir == 'D') {\n            for (int t = 0; t < N - best_i; t++) {\n                operations.push_back({'D', best_j});\n            }\n            for (int t = 0; t < N - best_i; t++) {\n                operations.push_back({'U', best_j});\n            }\n        } else if (best_dir == 'L') {\n            for (int t = 0; t <= best_j; t++) {\n                operations.push_back({'L', best_i});\n            }\n            for (int t = 0; t <= best_j; t++) {\n                operations.push_back({'R', best_i});\n            }\n        } else if (best_dir == 'R') {\n            for (int t = 0; t < N - best_j; t++) {\n                operations.push_back({'R', best_i});\n            }\n            for (int t = 0; t < N - best_j; t++) {\n                operations.push_back({'L', best_i});\n            }\n        }\n        \n        board[best_i][best_j] = '.';\n    }\n    \n    // Output operations\n    for (auto [dir, pos] : operations) {\n        cout << dir << \" \" << pos << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N), b(N);\n    mt19937 rng(42);\n    \n    // Initialize based on target probabilities\n    vector<double> prob(N);\n    for (int i = 0; i < N; i++) {\n        prob[i] = max(1, T[i]);  // Avoid zero probability\n    }\n    \n    for (int i = 0; i < N; i++) {\n        discrete_distribution<int> dist(prob.begin(), prob.end());\n        a[i] = dist(rng);\n        b[i] = dist(rng);\n    }\n    \n    // Simulation function\n    auto simulate = [&](int maxSteps) {\n        vector<int> count(N, 0);\n        int current = 0;\n        count[0]++;\n        \n        for (int step = 2; step <= maxSteps; step++) {\n            if (count[current] % 2 == 1) {\n                current = a[current];\n            } else {\n                current = b[current];\n            }\n            count[current]++;\n        }\n        \n        return count;\n    };\n    \n    // Calculate error\n    auto calculateError = [&](const vector<int>& counts, int simLength) {\n        double scale = (double)L / simLength;\n        int error = 0;\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            error += abs(projected - T[i]);\n        }\n        return error;\n    };\n    \n    // Optimize using local search\n    int simLength = min(100000, L);\n    auto counts = simulate(simLength);\n    int bestError = calculateError(counts, simLength);\n    \n    vector<int> bestA = a, bestB = b;\n    \n    // Multi-stage optimization\n    vector<int> simLengths = {10000, 50000, 100000};\n    \n    for (int stage = 0; stage < simLengths.size(); stage++) {\n        simLength = min(simLengths[stage], L);\n        \n        for (int iter = 0; iter < 5000; iter++) {\n            // Choose employee to modify (prefer those with large error)\n            counts = simulate(simLength);\n            vector<pair<int, int>> errors;\n            double scale = (double)L / simLength;\n            \n            for (int i = 0; i < N; i++) {\n                int projected = (int)(counts[i] * scale + 0.5);\n                errors.push_back({abs(projected - T[i]), i});\n            }\n            \n            sort(errors.rbegin(), errors.rend());\n            \n            // Pick from top errors with some randomness\n            int idx = min((int)(rng() % 10), (int)errors.size() - 1);\n            int emp = errors[idx].second;\n            \n            // Decide which transition to modify\n            int which = rng() % 2;\n            int oldVal = which == 0 ? a[emp] : b[emp];\n            \n            // Choose new target based on who needs more visits\n            vector<double> weights(N);\n            for (int i = 0; i < N; i++) {\n                int projected = (int)(counts[i] * scale + 0.5);\n                weights[i] = max(0, T[i] - projected) + 1;\n            }\n            \n            discrete_distribution<int> dist(weights.begin(), weights.end());\n            int newVal = dist(rng);\n            \n            if (which == 0) a[emp] = newVal;\n            else b[emp] = newVal;\n            \n            // Evaluate\n            counts = simulate(simLength);\n            int error = calculateError(counts, simLength);\n            \n            if (error < bestError) {\n                bestError = error;\n                bestA = a;\n                bestB = b;\n            } else {\n                // Revert with some probability (simulated annealing)\n                double temp = 1000.0 * (1.0 - (double)iter / 5000);\n                double acceptProb = exp(-(error - bestError) / temp);\n                if (uniform_real_distribution<>(0, 1)(rng) < acceptProb) {\n                    // Keep the change\n                } else {\n                    if (which == 0) a[emp] = oldVal;\n                    else b[emp] = oldVal;\n                }\n            }\n        }\n        \n        a = bestA;\n        b = bestB;\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << \" \" << bestB[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n};\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    \n    UnionFind(int n) : parent(n), size(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (size[px] < size[py]) swap(px, py);\n        parent[py] = px;\n        size[px] += size[py];\n        return true;\n    }\n};\n\ndouble dist(const City& a, const City& b) {\n    double dx = a.cx - b.cx;\n    double dy = a.cy - b.cy;\n    return sqrt(dx * dx + dy * dy);\n}\n\nvector<pair<int, int>> query(const vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v});\n    }\n    return edges;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<City> cities(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    }\n    \n    // Hierarchical clustering approach\n    vector<set<int>> clusters(N);\n    for (int i = 0; i < N; i++) clusters[i].insert(i);\n    \n    vector<int> clusterSize(N, 1);\n    vector<int> targetGroup(N, -1);\n    \n    // Precompute distances\n    vector<vector<double>> distances(N, vector<double>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            distances[i][j] = distances[j][i] = dist(cities[i], cities[j]);\n        }\n    }\n    \n    // Assign clusters to groups based on size constraints\n    priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n    for (int i = 0; i < N; i++) {\n        for (int j = i + 1; j < N; j++) {\n            pq.push({distances[i][j], i, j});\n        }\n    }\n    \n    UnionFind uf(N);\n    vector<vector<int>> groups(M);\n    vector<int> groupAssignment(N, -1);\n    \n    // Greedy merging with size constraints\n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        int pi = uf.find(i);\n        int pj = uf.find(j);\n        \n        if (pi == pj) continue;\n        \n        // Check if we can merge these clusters\n        int sizeI = uf.size[pi];\n        int sizeJ = uf.size[pj];\n        int totalSize = sizeI + sizeJ;\n        \n        // Find a group that can fit this size\n        bool canMerge = false;\n        for (int g = 0; g < M; g++) {\n            if (groups[g].size() == 0 && totalSize <= G[g]) {\n                canMerge = true;\n                break;\n            }\n        }\n        \n        if (canMerge && totalSize <= *max_element(G.begin(), G.end())) {\n            uf.unite(i, j);\n        }\n    }\n    \n    // Assign connected components to groups\n    map<int, vector<int>> components;\n    for (int i = 0; i < N; i++) {\n        components[uf.find(i)].push_back(i);\n    }\n    \n    // Sort components by size\n    vector<pair<int, vector<int>>> sortedComps;\n    for (auto& [root, comp] : components) {\n        sortedComps.push_back({comp.size(), comp});\n    }\n    sort(sortedComps.rbegin(), sortedComps.rend());\n    \n    // Assign components to groups using first-fit-decreasing\n    vector<int> currentGroupSize(M, 0);\n    for (auto& [sz, comp] : sortedComps) {\n        for (int g = 0; g < M; g++) {\n            if (currentGroupSize[g] + sz <= G[g]) {\n                for (int c : comp) {\n                    groups[g].push_back(c);\n                    groupAssignment[c] = g;\n                }\n                currentGroupSize[g] += sz;\n                break;\n            }\n        }\n    }\n    \n    // Handle unassigned cities\n    for (int i = 0; i < N; i++) {\n        if (groupAssignment[i] == -1) {\n            for (int g = 0; g < M; g++) {\n                if (currentGroupSize[g] < G[g]) {\n                    groups[g].push_back(i);\n                    currentGroupSize[g]++;\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Process each group to find MST\n    vector<vector<pair<int, int>>> groupEdges(M);\n    int queriesUsed = 0;\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L && queriesUsed < Q) {\n            auto edges = query(groups[g]);\n            groupEdges[g] = edges;\n            queriesUsed++;\n        } else {\n            // Use overlapping queries\n            set<pair<int, int>> collectedEdges;\n            \n            // Sliding window with overlap\n            int step = max(2, L / 2);\n            for (int start = 0; start < sz && queriesUsed < Q; start += step) {\n                int end = min(start + L, sz);\n                if (end - start >= 2) {\n                    vector<int> subset(groups[g].begin() + start, groups[g].begin() + end);\n                    auto edges = query(subset);\n                    for (auto& e : edges) {\n                        collectedEdges.insert({min(e.first, e.second), max(e.first, e.second)});\n                    }\n                    queriesUsed++;\n                }\n            }\n            \n            // Build MST from collected edges\n            UnionFind mstUF(N);\n            vector<tuple<double, int, int>> allEdges;\n            \n            for (auto& [u, v] : collectedEdges) {\n                allEdges.push_back({distances[u][v], u, v});\n            }\n            \n            // Add remaining possible edges if needed\n            for (int i = 0; i < sz; i++) {\n                for (int j = i + 1; j < sz; j++) {\n                    int u = groups[g][i], v = groups[g][j];\n                    if (collectedEdges.find({min(u, v), max(u, v)}) == collectedEdges.end()) {\n                        allEdges.push_back({distances[u][v], u, v});\n                    }\n                }\n            }\n            \n            sort(allEdges.begin(), allEdges.end());\n            \n            for (auto& [d, u, v] : allEdges) {\n                if (mstUF.unite(u, v)) {\n                    groupEdges[g].push_back({u, v});\n                    if (groupEdges[g].size() == sz - 1) break;\n                }\n            }\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int c : groups[g]) cout << c << \" \";\n        cout << endl;\n        for (auto& e : groupEdges[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int M = 40;\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct Action {\n    char type, dir;\n};\n\nvector<Action> actions;\nset<pair<int,int>> blocks;\nPoint current;\nvector<Point> targets;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\nbool hasBlock(int i, int j) {\n    return blocks.count({i, j}) > 0;\n}\n\nPoint getNext(Point p, int dir) {\n    return {p.i + di[dir], p.j + dj[dir]};\n}\n\nPoint slideFrom(Point p, int dir) {\n    while (true) {\n        Point next = getNext(p, dir);\n        if (!inBounds(next.i, next.j) || hasBlock(next.i, next.j)) break;\n        p = next;\n    }\n    return p;\n}\n\nvoid addAction(char type, char dir) {\n    actions.push_back({type, dir});\n    \n    int d = 0;\n    for (int i = 0; i < 4; i++) {\n        if (dirs[i] == dir) {\n            d = i;\n            break;\n        }\n    }\n    \n    if (type == 'M') {\n        current = getNext(current, d);\n    } else if (type == 'S') {\n        current = slideFrom(current, d);\n    } else if (type == 'A') {\n        Point next = getNext(current, d);\n        if (hasBlock(next.i, next.j)) {\n            blocks.erase({next.i, next.j});\n        } else {\n            blocks.insert({next.i, next.j});\n        }\n    }\n}\n\n// BFS to find shortest path with current blocks\nvector<Action> findPath(Point start, Point target) {\n    if (start == target) return {};\n    \n    queue<pair<Point, vector<Action>>> q;\n    map<pair<int,int>, int> dist;\n    q.push({start, {}});\n    dist[{start.i, start.j}] = 0;\n    \n    while (!q.empty()) {\n        auto [p, path] = q.front();\n        q.pop();\n        \n        // Try moves\n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(p, d);\n            if (!inBounds(next.i, next.j) || hasBlock(next.i, next.j)) continue;\n            \n            if (!dist.count({next.i, next.j}) || dist[{next.i, next.j}] > path.size() + 1) {\n                dist[{next.i, next.j}] = path.size() + 1;\n                auto newPath = path;\n                newPath.push_back({'M', dirs[d]});\n                if (next == target) return newPath;\n                q.push({next, newPath});\n            }\n        }\n        \n        // Try slides\n        for (int d = 0; d < 4; d++) {\n            Point next = slideFrom(p, d);\n            if (next == p) continue;\n            \n            if (!dist.count({next.i, next.j}) || dist[{next.i, next.j}] > path.size() + 1) {\n                dist[{next.i, next.j}] = path.size() + 1;\n                auto newPath = path;\n                newPath.push_back({'S', dirs[d]});\n                if (next == target) return newPath;\n                q.push({next, newPath});\n            }\n        }\n    }\n    \n    return {};\n}\n\nvoid moveToTarget(Point target) {\n    // First try direct path\n    auto directPath = findPath(current, target);\n    \n    // Try to optimize with strategic block placement for sliding\n    vector<Action> bestPath = directPath;\n    \n    // Check if we can create efficient slide path\n    if (current.i == target.i || current.j == target.j) {\n        // Aligned - try to set up slide\n        int dir = -1;\n        Point blockPos;\n        \n        if (current.i == target.i) {\n            // Horizontal slide\n            if (current.j < target.j) {\n                dir = 2; // Right\n                blockPos = {target.i, target.j + 1};\n            } else {\n                dir = 3; // Left\n                blockPos = {target.i, target.j - 1};\n            }\n        } else {\n            // Vertical slide\n            if (current.i < target.i) {\n                dir = 1; // Down\n                blockPos = {target.i + 1, target.j};\n            } else {\n                dir = 0; // Up\n                blockPos = {target.i - 1, target.j};\n            }\n        }\n        \n        if (inBounds(blockPos.i, blockPos.j) && !hasBlock(blockPos.i, blockPos.j)) {\n            // Temporarily place block\n            blocks.insert({blockPos.i, blockPos.j});\n            Point slideEnd = slideFrom(current, dir);\n            \n            if (slideEnd == target) {\n                // Great! This works with just one slide\n                vector<Action> slidePath;\n                slidePath.push_back({'A', dirs[dir]}); // Place block\n                slidePath.push_back({'S', dirs[dir]}); // Slide\n                \n                if (slidePath.size() < bestPath.size()) {\n                    bestPath = slidePath;\n                }\n            }\n            \n            blocks.erase({blockPos.i, blockPos.j});\n        }\n    }\n    \n    // Execute best path\n    for (auto& action : bestPath) {\n        addAction(action.type, action.dir);\n        if (actions.size() >= 2 * N * M - 10) break;\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    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].i >> targets[i].j;\n    }\n    \n    current = targets[0];\n    \n    // Visit each target in order\n    for (int i = 1; i < m; i++) {\n        moveToTarget(targets[i]);\n        \n        // Remove blocks on target if any\n        if (hasBlock(targets[i].i, targets[i].j)) {\n            for (int d = 0; d < 4; d++) {\n                Point adj = getNext(current, d);\n                if (adj.i == targets[i].i && adj.j == targets[i].j) {\n                    addAction('A', dirs[d]);\n                    break;\n                }\n            }\n        }\n        \n        if (actions.size() >= 2 * N * M - 10) break;\n    }\n    \n    // Output actions\n    for (auto& action : actions) {\n        cout << action.type << \" \" << action.dir << \"\\n\";\n    }\n    \n    return 0;\n}"},"2":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <set>\n\nusing namespace std;\n\nstruct Company {\n    int id;\n    int x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d;\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(double px, double py) const {\n        return a < px && px < c && b < py && py < 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\nclass Solver {\nprivate:\n    int n;\n    vector<Company> companies;\n    vector<Rectangle> solution;\n    mt19937 rng;\n    \n    double calculate_satisfaction(int i) {\n        const auto& comp = companies[i];\n        const auto& rect = solution[i];\n        \n        if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) {\n            return 0.0;\n        }\n        \n        int s = rect.area();\n        if (s == 0) return 0.0;\n        \n        double ratio = min(comp.r, s) / (double)max(comp.r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool check_overlaps(const Rectangle& rect, int exclude_id = -1) {\n        for (int i = 0; i < n; i++) {\n            if (i == exclude_id) continue;\n            if (solution[i].area() > 0 && solution[i].overlaps(rect)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    Rectangle find_best_rectangle(int idx, int max_attempts = 100) {\n        const auto& comp = companies[idx];\n        int target_area = comp.r;\n        \n        Rectangle best_rect = {comp.x, comp.y, min(10000, comp.x + 1), min(10000, comp.y + 1)};\n        double best_score = 0;\n        \n        // Try to find rectangle with area close to target\n        int sqrt_area = sqrt(target_area);\n        \n        for (int attempt = 0; attempt < max_attempts; attempt++) {\n            int w, h;\n            \n            if (attempt < max_attempts / 2) {\n                // Try systematic sizes\n                double aspect_ratio = 1.0 + (attempt % 10) * 0.2;\n                w = sqrt(target_area * aspect_ratio);\n                h = target_area / max(1, w);\n            } else {\n                // Try random sizes\n                w = max(1, min(10000, (int)(sqrt_area * (0.5 + (rng() % 100) / 50.0))));\n                h = target_area / max(1, w);\n            }\n            \n            w = max(1, min(10000, w));\n            h = max(1, min(10000, h));\n            \n            // Try different positions that include the required point\n            for (int dx = 0; dx <= min(w - 1, comp.x); dx++) {\n                for (int dy = 0; dy <= min(h - 1, comp.y); dy++) {\n                    int a = comp.x - dx;\n                    int b = comp.y - dy;\n                    int c = min(10000, a + w);\n                    int d = min(10000, b + h);\n                    \n                    Rectangle rect = {a, b, c, d};\n                    \n                    if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) continue;\n                    if (check_overlaps(rect, idx)) continue;\n                    \n                    int area = rect.area();\n                    double ratio = min(target_area, area) / (double)max(target_area, area);\n                    double score = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_rect = rect;\n                        if (score > 0.99) return best_rect;  // Good enough\n                    }\n                }\n            }\n        }\n        \n        return best_rect;\n    }\n    \n    void greedy_placement() {\n        // Sort companies by area (largest first)\n        vector<int> order(n);\n        for (int i = 0; i < n; i++) order[i] = i;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return companies[i].r > companies[j].r;\n        });\n        \n        // Initialize all rectangles to empty\n        for (int i = 0; i < n; i++) {\n            solution[i] = {0, 0, 0, 0};\n        }\n        \n        // Place rectangles greedily\n        for (int idx : order) {\n            solution[idx] = find_best_rectangle(idx);\n        }\n    }\n    \n    void local_optimization(int iterations) {\n        double total_score = 0;\n        for (int i = 0; i < n; i++) {\n            total_score += calculate_satisfaction(i);\n        }\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            int idx = rng() % n;\n            Rectangle old_rect = solution[idx];\n            \n            // Try to adjust the rectangle\n            Rectangle new_rect = old_rect;\n            int type = rng() % 8;\n            \n            switch(type) {\n                case 0: if (new_rect.a > 0) new_rect.a--; break;\n                case 1: if (new_rect.b > 0) new_rect.b--; break;\n                case 2: if (new_rect.c < 10000) new_rect.c++; break;\n                case 3: if (new_rect.d < 10000) new_rect.d++; break;\n                case 4: if (new_rect.a < new_rect.c - 1 && new_rect.a < companies[idx].x) new_rect.a++; break;\n                case 5: if (new_rect.b < new_rect.d - 1 && new_rect.b < companies[idx].y) new_rect.b++; break;\n                case 6: if (new_rect.c > new_rect.a + 1 && new_rect.c > companies[idx].x + 1) new_rect.c--; break;\n                case 7: if (new_rect.d > new_rect.b + 1 && new_rect.d > companies[idx].y + 1) new_rect.d--; break;\n            }\n            \n            // Check validity\n            if (!new_rect.contains(companies[idx].x + 0.5, companies[idx].y + 0.5)) continue;\n            if (check_overlaps(new_rect, idx)) continue;\n            \n            // Calculate score change\n            solution[idx] = new_rect;\n            double new_total = 0;\n            for (int i = 0; i < n; i++) {\n                new_total += calculate_satisfaction(i);\n            }\n            \n            if (new_total > total_score) {\n                total_score = new_total;\n            } else {\n                solution[idx] = old_rect;\n            }\n        }\n    }\n    \npublic:\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void solve() {\n        cin >> n;\n        companies.resize(n);\n        solution.resize(n);\n        \n        for (int i = 0; i < n; i++) {\n            companies[i].id = i;\n            cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        }\n        \n        greedy_placement();\n        \n        // Local optimization with time limit\n        auto start_time = chrono::steady_clock::now();\n        const auto time_limit = chrono::milliseconds(4500);\n        \n        while (chrono::steady_clock::now() - start_time < time_limit) {\n            local_optimization(100);\n        }\n    }\n    \n    void output() {\n        for (const auto& rect : solution) {\n            cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    solver.output();\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500;\n\nint si, sj;\nint tile[N][N];\nint points[N][N];\nvector<pair<int,int>> tile_squares[MAX_TILES];\nint tile_value[MAX_TILES];\nset<int> tile_neighbors[MAX_TILES];\nint num_tiles;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n};\n\nvoid preprocess() {\n    num_tiles = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n            tile_squares[tile[i][j]].push_back({i, j});\n        }\n    }\n    \n    // Calculate tile values\n    for (int t = 0; t < num_tiles; t++) {\n        tile_value[t] = 0;\n        for (auto [i, j] : tile_squares[t]) {\n            tile_value[t] += points[i][j];\n        }\n    }\n    \n    // Find neighboring tiles\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int curr = tile[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int next = tile[ni][nj];\n                    if (next != curr) {\n                        tile_neighbors[curr].insert(next);\n                    }\n                }\n            }\n        }\n    }\n}\n\nState greedy_walk(double randomness = 0.0) {\n    State state;\n    state.i = si;\n    state.j = sj;\n    state.score = points[si][sj];\n    state.visited[tile[si][sj]] = true;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    while (true) {\n        vector<tuple<int, int, int, int>> candidates; // score, ni, nj, dir\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            int score = tile_value[next_tile];\n            \n            // Add lookahead bonus\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!state.visited[neighbor]) {\n                    score += tile_value[neighbor] / 4;\n                }\n            }\n            \n            candidates.push_back({score, ni, nj, d});\n        }\n        \n        if (candidates.empty()) break;\n        \n        // Sort by score\n        sort(candidates.rbegin(), candidates.rend());\n        \n        // Choose with some randomness\n        int choice = 0;\n        if (randomness > 0 && dis(gen) < randomness && candidates.size() > 1) {\n            choice = min(1, (int)candidates.size() - 1);\n        }\n        \n        auto [score, ni, nj, dir] = candidates[choice];\n        \n        state.i = ni;\n        state.j = nj;\n        state.path += dir_char[dir];\n        state.score += points[ni][nj];\n        state.visited[tile[ni][nj]] = true;\n    }\n    \n    return state;\n}\n\nint main() {\n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess();\n    \n    State best;\n    best.score = 0;\n    \n    // Try multiple strategies\n    auto start = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count();\n        if (elapsed > 1900) break;\n        \n        // Pure greedy\n        State s1 = greedy_walk(0.0);\n        if (s1.score > best.score) best = s1;\n        \n        // With some randomness\n        State s2 = greedy_walk(0.3);\n        if (s2.score > best.score) best = s2;\n        \n        State s3 = greedy_walk(0.5);\n        if (s3.score > best.score) best = s3;\n    }\n    \n    cout << best.path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int QUERIES = 1000;\nconst double INF = 1e9;\n\ndouble h_weight[N][N-1]; // horizontal edges\ndouble v_weight[N-1][N]; // vertical edges\nint h_count[N][N-1];\nint v_count[N-1][N];\n\nstruct State {\n    double dist;\n    int i, j;\n    bool operator<(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\nstruct EdgeInfo {\n    int type; // 0 for vertical, 1 for horizontal\n    int i, j;\n};\n\npair<string, vector<EdgeInfo>> dijkstra(int si, int sj, int ti, int tj) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    priority_queue<State> pq;\n    \n    dist[si][sj] = 0;\n    pq.push({0, si, sj});\n    \n    while (!pq.empty()) {\n        State cur = pq.top();\n        pq.pop();\n        \n        int i = cur.i, j = cur.j;\n        double d = cur.dist;\n        \n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        // Try all 4 directions\n        // Up\n        if (i > 0) {\n            double nd = dist[i][j] + v_weight[i-1][j];\n            if (nd < dist[i-1][j]) {\n                dist[i-1][j] = nd;\n                parent[i-1][j] = {i, j};\n                pq.push({nd, i-1, j});\n            }\n        }\n        // Down\n        if (i < N-1) {\n            double nd = dist[i][j] + v_weight[i][j];\n            if (nd < dist[i+1][j]) {\n                dist[i+1][j] = nd;\n                parent[i+1][j] = {i, j};\n                pq.push({nd, i+1, j});\n            }\n        }\n        // Left\n        if (j > 0) {\n            double nd = dist[i][j] + h_weight[i][j-1];\n            if (nd < dist[i][j-1]) {\n                dist[i][j-1] = nd;\n                parent[i][j-1] = {i, j};\n                pq.push({nd, i, j-1});\n            }\n        }\n        // Right\n        if (j < N-1) {\n            double nd = dist[i][j] + h_weight[i][j];\n            if (nd < dist[i][j+1]) {\n                dist[i][j+1] = nd;\n                parent[i][j+1] = {i, j};\n                pq.push({nd, i, j+1});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<EdgeInfo> edges;\n    string path = \"\";\n    int ci = ti, cj = tj;\n    \n    while (!(ci == si && cj == sj)) {\n        int pi = parent[ci][cj].first;\n        int pj = parent[ci][cj].second;\n        \n        if (pi == ci - 1) {\n            path += 'D';\n            edges.push_back({0, ci-1, cj});\n        } else if (pi == ci + 1) {\n            path += 'U';\n            edges.push_back({0, ci, cj});\n        } else if (pj == cj - 1) {\n            path += 'R';\n            edges.push_back({1, ci, cj-1});\n        } else if (pj == cj + 1) {\n            path += 'L';\n            edges.push_back({1, ci, cj});\n        }\n        ci = pi;\n        cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(edges.begin(), edges.end());\n    \n    return {path, edges};\n}\n\nvoid update_weights(const vector<EdgeInfo>& edges, int actual_length) {\n    if (edges.empty()) return;\n    \n    double total_estimated = 0;\n    for (const auto& e : edges) {\n        if (e.type == 0) {\n            total_estimated += v_weight[e.i][e.j];\n        } else {\n            total_estimated += h_weight[e.i][e.j];\n        }\n    }\n    \n    if (total_estimated <= 0) return;\n    \n    double ratio = (double)actual_length / total_estimated;\n    \n    // Update each edge weight with adaptive learning rate\n    for (const auto& e : edges) {\n        if (e.type == 0) {\n            int cnt = v_count[e.i][e.j];\n            double lr = 0.3 / (1.0 + cnt * 0.1);\n            v_weight[e.i][e.j] = v_weight[e.i][e.j] * (1 - lr) + v_weight[e.i][e.j] * ratio * lr;\n            v_count[e.i][e.j]++;\n        } else {\n            int cnt = h_count[e.i][e.j];\n            double lr = 0.3 / (1.0 + cnt * 0.1);\n            h_weight[e.i][e.j] = h_weight[e.i][e.j] * (1 - lr) + h_weight[e.i][e.j] * ratio * lr;\n            h_count[e.i][e.j]++;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Initialize weights to expected average\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N-1; j++) {\n            h_weight[i][j] = 5000;\n            h_count[i][j] = 0;\n        }\n    }\n    for (int i = 0; i < N-1; i++) {\n        for (int j = 0; j < N; j++) {\n            v_weight[i][j] = 5000;\n            v_count[i][j] = 0;\n        }\n    }\n    \n    for (int k = 0; k < QUERIES; k++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto result = dijkstra(si, sj, ti, tj);\n        string path = result.first;\n        vector<EdgeInfo> edges = result.second;\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int actual_length;\n        cin >> actual_length;\n        \n        update_weights(edges, actual_length);\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\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<string> strings(m);\n    for (int i = 0; i < m; i++) {\n        cin >> strings[i];\n    }\n    \n    // Sort strings by length (longer first) for more constraints\n    vector<int> order(m);\n    iota(order.begin(), order.end(), 0);\n    sort(order.begin(), order.end(), [&](int a, int b) {\n        return strings[a].length() > strings[b].length();\n    });\n    \n    vector<vector<char>> grid(n, vector<char>(n, '.'));\n    vector<bool> placed(m, false);\n    \n    // Check if string can be placed at position\n    auto canPlaceH = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int col = (c + i) % n;\n            if (grid[r][col] != '.' && grid[r][col] != s[i]) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    auto canPlaceV = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            int row = (r + i) % n;\n            if (grid[row][c] != '.' && grid[row][c] != s[i]) {\n                return false;\n            }\n        }\n        return true;\n    };\n    \n    // Place string at position\n    auto placeH = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            grid[r][(c + i) % n] = s[i];\n        }\n    };\n    \n    auto placeV = [&](int r, int c, const string& s) {\n        for (int i = 0; i < s.length(); i++) {\n            grid[(r + i) % n][c] = s[i];\n        }\n    };\n    \n    // Count overlaps with already placed strings\n    auto countOverlapH = [&](int r, int c, const string& s) {\n        int overlap = 0;\n        for (int i = 0; i < s.length(); i++) {\n            if (grid[r][(c + i) % n] == s[i]) overlap++;\n        }\n        return overlap;\n    };\n    \n    auto countOverlapV = [&](int r, int c, const string& s) {\n        int overlap = 0;\n        for (int i = 0; i < s.length(); i++) {\n            if (grid[(r + i) % n][c] == s[i]) overlap++;\n        }\n        return overlap;\n    };\n    \n    // Multi-pass placement strategy\n    for (int pass = 0; pass < 3; pass++) {\n        for (int idx : order) {\n            if (placed[idx]) continue;\n            \n            const string& s = strings[idx];\n            int bestR = -1, bestC = -1, bestDir = -1;\n            int bestScore = -1;\n            \n            // Find best placement based on overlap\n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (canPlaceH(r, c, s)) {\n                        int score = countOverlapH(r, c, s) * 10 + (pass == 0 ? 1 : 0);\n                        if (score > bestScore) {\n                            bestScore = score;\n                            bestR = r; bestC = c; bestDir = 0;\n                        }\n                    }\n                    if (canPlaceV(r, c, s)) {\n                        int score = countOverlapV(r, c, s) * 10 + (pass == 0 ? 1 : 0);\n                        if (score > bestScore) {\n                            bestScore = score;\n                            bestR = r; bestC = c; bestDir = 1;\n                        }\n                    }\n                }\n            }\n            \n            // Place if found valid position\n            if (bestR != -1) {\n                if (bestDir == 0) {\n                    placeH(bestR, bestC, s);\n                } else {\n                    placeV(bestR, bestC, s);\n                }\n                placed[idx] = true;\n            }\n        }\n    }\n    \n    // Try to place remaining strings more aggressively\n    for (int attempts = 0; attempts < 2; attempts++) {\n        for (int idx = 0; idx < m; idx++) {\n            if (placed[idx]) continue;\n            \n            const string& s = strings[idx];\n            \n            // Try all positions, even with minimal overlap\n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (canPlaceH(r, c, s)) {\n                        placeH(r, c, s);\n                        placed[idx] = true;\n                        goto next1;\n                    }\n                    if (canPlaceV(r, c, s)) {\n                        placeV(r, c, s);\n                        placed[idx] = true;\n                        goto next1;\n                    }\n                }\n            }\n            next1:;\n        }\n    }\n    \n    // Fill remaining dots with most frequent characters\n    map<char, int> freq;\n    for (const auto& s : strings) {\n        for (char c : s) {\n            freq[c]++;\n        }\n    }\n    \n    char mostFreq = 'A';\n    int maxFreq = 0;\n    for (auto [c, f] : freq) {\n        if (f > maxFreq) {\n            maxFreq = f;\n            mostFreq = c;\n        }\n    }\n    \n    // Smart fill based on neighbors\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (grid[i][j] == '.') {\n                map<char, int> neighborFreq;\n                // Check neighbors\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (di == 0 && dj == 0) continue;\n                        int ni = (i + di + n) % n;\n                        int nj = (j + dj + n) % n;\n                        if (grid[ni][nj] != '.') {\n                            neighborFreq[grid[ni][nj]]++;\n                        }\n                    }\n                }\n                \n                if (!neighborFreq.empty()) {\n                    char best = neighborFreq.begin()->first;\n                    int bestCnt = 0;\n                    for (auto [c, cnt] : neighborFreq) {\n                        if (cnt > bestCnt || (cnt == bestCnt && freq[c] > freq[best])) {\n                            bestCnt = cnt;\n                            best = c;\n                        }\n                    }\n                    grid[i][j] = best;\n                } else {\n                    grid[i][j] = mostFreq;\n                }\n            }\n        }\n    }\n    \n    // Output the grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << grid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nvector<pair<int,int>> compute_visible_list(int i, int j) {\n    vector<pair<int,int>> visible;\n    if (!is_road(i, j)) return visible;\n    \n    visible.push_back({i, j});\n    \n    for (int jj = j - 1; jj >= 0 && is_road(i, jj); jj--) {\n        visible.push_back({i, jj});\n    }\n    for (int jj = j + 1; jj < N && is_road(i, jj); jj++) {\n        visible.push_back({i, jj});\n    }\n    for (int ii = i - 1; ii >= 0 && is_road(ii, j); ii--) {\n        visible.push_back({ii, j});\n    }\n    for (int ii = i + 1; ii < N && is_road(ii, j); ii++) {\n        visible.push_back({ii, j});\n    }\n    \n    return visible;\n}\n\nstring find_path_bfs(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return \"\";\n    \n    queue<tuple<int, int>> q;\n    map<pair<int,int>, pair<int,int>> parent;\n    map<pair<int,int>, int> dir_used;\n    \n    q.push({si, sj});\n    parent[{si, sj}] = {-1, -1};\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        if (i == ei && j == ej) {\n            // Reconstruct path\n            string path = \"\";\n            int ci = ei, cj = ej;\n            while (parent[{ci, cj}].first != -1) {\n                path = dir[dir_used[{ci, cj}]] + path;\n                auto [pi, pj] = parent[{ci, cj}];\n                ci = pi;\n                cj = pj;\n            }\n            return path;\n        }\n        \n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k];\n            int nj = j + dj[k];\n            \n            if (is_road(ni, nj) && !parent.count({ni, nj})) {\n                parent[{ni, nj}] = {i, j};\n                dir_used[{ni, nj}] = k;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Find all roads\n    vector<pair<int,int>> all_roads;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j)) {\n                all_roads.push_back({i, j});\n            }\n        }\n    }\n    \n    // Precompute visibility for each position\n    map<pair<int,int>, vector<pair<int,int>>> visibility;\n    for (auto [i, j] : all_roads) {\n        visibility[{i, j}] = compute_visible_list(i, j);\n    }\n    \n    // Simple greedy approach with limited candidates\n    string route = \"\";\n    int ci = si, cj = sj;\n    vector<bool> covered(all_roads.size(), false);\n    \n    auto mark_covered = [&](int i, int j) {\n        for (auto [vi, vj] : visibility[{i, j}]) {\n            for (int idx = 0; idx < all_roads.size(); idx++) {\n                if (all_roads[idx].first == vi && all_roads[idx].second == vj) {\n                    covered[idx] = true;\n                }\n            }\n        }\n    };\n    \n    mark_covered(ci, cj);\n    \n    // Select key positions to visit (sampling strategy)\n    vector<pair<int,int>> key_positions;\n    for (int i = 0; i < N; i += 4) {\n        for (int j = 0; j < N; j += 4) {\n            if (is_road(i, j)) {\n                key_positions.push_back({i, j});\n            }\n        }\n    }\n    \n    // Visit positions greedily\n    while (true) {\n        int uncovered_count = count(covered.begin(), covered.end(), false);\n        if (uncovered_count == 0) break;\n        \n        int best_i = -1, best_j = -1;\n        int best_new_coverage = 0;\n        \n        // Check key positions first\n        for (auto [i, j] : key_positions) {\n            if (i == ci && j == cj) continue;\n            \n            int new_coverage = 0;\n            for (auto [vi, vj] : visibility[{i, j}]) {\n                for (int idx = 0; idx < all_roads.size(); idx++) {\n                    if (!covered[idx] && all_roads[idx].first == vi && all_roads[idx].second == vj) {\n                        new_coverage++;\n                    }\n                }\n            }\n            \n            if (new_coverage > best_new_coverage) {\n                best_new_coverage = new_coverage;\n                best_i = i;\n                best_j = j;\n            }\n        }\n        \n        // If no good key position, find any uncovered position\n        if (best_i == -1) {\n            for (int idx = 0; idx < all_roads.size(); idx++) {\n                if (!covered[idx]) {\n                    best_i = all_roads[idx].first;\n                    best_j = all_roads[idx].second;\n                    break;\n                }\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        // Move to the selected position\n        string path = find_path_bfs(ci, cj, best_i, best_j);\n        if (path.empty() && (ci != best_i || cj != best_j)) break;\n        \n        route += path;\n        ci = best_i;\n        cj = best_j;\n        mark_covered(ci, cj);\n    }\n    \n    // Return to start\n    route += find_path_bfs(ci, cj, si, sj);\n    \n    cout << route << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, 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>> dependents(N);\n    vector<vector<int>> dependencies(N);\n    vector<int> dep_count(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        dependents[u].push_back(v);\n        dependencies[v].push_back(u);\n        dep_count[v]++;\n    }\n    \n    // Calculate critical path length for each task\n    vector<int> path_length(N, 0);\n    vector<bool> computed(N, false);\n    function<int(int)> compute_path = [&](int task) -> int {\n        if (computed[task]) return path_length[task];\n        computed[task] = true;\n        int max_len = 0;\n        for (int dep : dependents[task]) {\n            max_len = max(max_len, compute_path(dep));\n        }\n        path_length[task] = max_len + 1;\n        return path_length[task];\n    };\n    \n    for (int i = 0; i < N; i++) {\n        if (!computed[i]) compute_path(i);\n    }\n    \n    // Initialize skill estimates with higher initial values and uncertainty\n    vector<vector<double>> skill_mean(M, vector<double>(K, 40.0));\n    vector<vector<double>> skill_var(M, vector<double>(K, 100.0));\n    vector<int> completed_count(M, 0);\n    vector<double> total_work(M, 0);\n    \n    // Track task-member history for better learning\n    vector<vector<pair<int,int>>> history(M); // (task, actual_days)\n    \n    vector<int> task_state(N, -1);  // -1: not started, 0: in progress, 1: done\n    vector<int> member_task(M, -1); // -1: idle, else task ID\n    vector<int> start_day(M, 0);\n    vector<int> remaining_deps(N);\n    for (int i = 0; i < N; i++) remaining_deps[i] = dep_count[i];\n    \n    int day = 0;\n    int completed = 0;\n    \n    while (completed < N && day < 1990) { // Leave buffer for ongoing tasks\n        day++;\n        \n        // Find available tasks\n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (task_state[i] == -1 && remaining_deps[i] == 0) {\n                available.push_back(i);\n            }\n        }\n        \n        // Score tasks by urgency and importance\n        vector<pair<double, int>> task_scores;\n        for (int task : available) {\n            double score = 0;\n            \n            // Critical path component\n            score += path_length[task] * 1000.0;\n            \n            // Number of directly blocked tasks\n            score += dependents[task].size() * 100.0;\n            \n            // Task difficulty (prefer easier tasks when path lengths are similar)\n            int total_req = 0;\n            for (int k = 0; k < K; k++) total_req += d[task][k];\n            score -= total_req * 0.5;\n            \n            // Boost for tasks with many available successors\n            int ready_successors = 0;\n            for (int succ : dependents[task]) {\n                if (remaining_deps[succ] == 1) ready_successors++;\n            }\n            score += ready_successors * 50.0;\n            \n            task_scores.push_back({score, task});\n        }\n        sort(task_scores.rbegin(), task_scores.rend());\n        \n        // Assign tasks to members\n        vector<pair<int, int>> assignments;\n        set<int> used_tasks;\n        \n        for (auto [_, task] : task_scores) {\n            if (used_tasks.count(task)) continue;\n            \n            // Find best member for this task\n            int best_member = -1;\n            double best_score = -1e9;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1) continue;\n                \n                // Calculate expected completion time\n                double expected_w = 0;\n                double uncertainty = 0;\n                for (int k = 0; k < K; k++) {\n                    double gap = max(0.0, d[task][k] - skill_mean[m][k]);\n                    expected_w += gap;\n                    if (gap > 0) uncertainty += sqrt(skill_var[m][k]);\n                }\n                \n                double expected_time = (expected_w == 0) ? 1 : max(1.0, expected_w);\n                \n                // Create a score that balances:\n                // 1. Expected completion time (lower is better)\n                // 2. Workload balance\n                // 3. Exploration bonus for uncertain members\n                double score = -expected_time * 10;\n                \n                // Workload balancing\n                double avg_work = 0;\n                for (int j = 0; j < M; j++) avg_work += total_work[j];\n                avg_work /= M;\n                score -= abs(total_work[m] + expected_time - avg_work) * 2;\n                \n                // Exploration bonus\n                if (completed_count[m] < 15) {\n                    double explore_bonus = (15 - completed_count[m]) * 3;\n                    explore_bonus *= (1 + uncertainty * 0.1);\n                    score += explore_bonus;\n                }\n                \n                // Prefer members who have done similar tasks\n                for (auto [prev_task, _] : history[m]) {\n                    double similarity = 0;\n                    for (int k = 0; k < K; k++) {\n                        similarity += min(d[task][k], d[prev_task][k]);\n                    }\n                    score += similarity * 0.01;\n                }\n                \n                if (best_member == -1 || score > best_score) {\n                    best_member = m;\n                    best_score = score;\n                }\n            }\n            \n            if (best_member != -1) {\n                assignments.push_back({best_member, task});\n                used_tasks.insert(task);\n                member_task[best_member] = task;\n                start_day[best_member] = day;\n                task_state[task] = 0;\n                \n                // Update expected workload\n                double expected_w = 0;\n                for (int k = 0; k < K; k++) {\n                    expected_w += max(0.0, d[task][k] - skill_mean[best_member][k]);\n                }\n                double expected_time = (expected_w == 0) ? 1 : max(1.0, expected_w);\n                total_work[best_member] += expected_time;\n            }\n        }\n        \n        // Output assignments\n        cout << assignments.size();\n        for (auto [m, t] : assignments) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        // Read completions\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) break;\n        \n        for (int i = 0; i < n_completed; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int task = member_task[m];\n            if (task != -1) {\n                task_state[task] = 1;\n                completed++;\n                \n                int actual_days = day - start_day[m] + 1;\n                history[m].push_back({task, actual_days});\n                \n                // Update dependencies\n                for (int dep : dependents[task]) {\n                    remaining_deps[dep]--;\n                }\n                \n                // Bayesian-like skill update\n                if (actual_days == 1) {\n                    // w = 0, skills definitely meet requirements\n                    for (int k = 0; k < K; k++) {\n                        if (d[task][k] > skill_mean[m][k]) {\n                            skill_mean[m][k] = d[task][k] + 0.5;\n                            skill_var[m][k] *= 0.5;\n                        }\n                    }\n                } else {\n                    // w is approximately actual_days (with \u00b13 noise)\n                    double observed_w = actual_days;\n                    double current_w = 0;\n                    vector<double> gaps(K);\n                    for (int k = 0; k < K; k++) {\n                        gaps[k] = max(0.0, d[task][k] - skill_mean[m][k]);\n                        current_w += gaps[k];\n                    }\n                    \n                    if (current_w > 0.01) {\n                        // Adjust skills based on observed vs expected\n                        double adjustment = (observed_w - current_w) / current_w;\n                        double lr = 0.3 / (1 + completed_count[m] * 0.02);\n                        \n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double update = gaps[k] * adjustment * lr;\n                                skill_mean[m][k] -= update;\n                                skill_mean[m][k] = max(0.0, min(100.0, skill_mean[m][k]));\n                                \n                                // Reduce uncertainty\n                                skill_var[m][k] *= 0.9;\n                                skill_var[m][k] = max(1.0, skill_var[m][k]);\n                            }\n                        }\n                    }\n                }\n                \n                completed_count[m]++;\n                member_task[m] = -1;\n                \n                // Update actual workload\n                total_work[m] -= (total_work[m] - actual_days) * 0.1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n    double score;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    vector<Order> orders(1000);\n    \n    // Read all orders\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        orders[i].id = i + 1;\n        \n        // Score based on proximity to center and delivery distance\n        int dist_from_center_pickup = manhattan(400, 400, orders[i].ax, orders[i].ay);\n        int dist_from_center_delivery = manhattan(400, 400, orders[i].cx, orders[i].cy);\n        int delivery_dist = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n        \n        // Prefer orders close to center with reasonable delivery distances\n        orders[i].score = dist_from_center_pickup + dist_from_center_delivery + delivery_dist * 0.3;\n    }\n    \n    // Sort orders by score (lower is better)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    \n    // Select the best 50 orders\n    vector<int> selected_ids;\n    vector<pair<int, int>> pickups, deliveries;\n    \n    for (int i = 0; i < 50; i++) {\n        selected_ids.push_back(orders[i].id);\n        pickups.push_back({orders[i].ax, orders[i].ay});\n        deliveries.push_back({orders[i].cx, orders[i].cy});\n    }\n    \n    // Build route using greedy approach with preference for clearing deliveries\n    vector<pair<int, int>> route;\n    route.push_back({400, 400});\n    \n    vector<bool> picked(50, false);\n    vector<bool> delivered(50, false);\n    int num_delivered = 0;\n    \n    while (num_delivered < 50) {\n        int cur_x = route.back().first;\n        int cur_y = route.back().second;\n        \n        int best_dist = INT_MAX;\n        int best_idx = -1;\n        bool best_is_pickup = false;\n        \n        // Count how many items we're currently carrying\n        int carrying = 0;\n        for (int i = 0; i < 50; i++) {\n            if (picked[i] && !delivered[i]) carrying++;\n        }\n        \n        // If carrying many items, prioritize deliveries\n        double delivery_weight = (carrying > 10) ? 0.7 : 1.0;\n        \n        // Consider pickups\n        for (int i = 0; i < 50; i++) {\n            if (picked[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, pickups[i].first, pickups[i].second);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = i;\n                best_is_pickup = true;\n            }\n        }\n        \n        // Consider deliveries for items we're carrying\n        for (int i = 0; i < 50; i++) {\n            if (!picked[i] || delivered[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, deliveries[i].first, deliveries[i].second);\n            int weighted_dist = dist * delivery_weight;\n            \n            if (weighted_dist < best_dist) {\n                best_dist = weighted_dist;\n                best_idx = i;\n                best_is_pickup = false;\n            }\n        }\n        \n        if (best_is_pickup) {\n            route.push_back(pickups[best_idx]);\n            picked[best_idx] = true;\n        } else {\n            route.push_back(deliveries[best_idx]);\n            delivered[best_idx] = true;\n            num_delivered++;\n        }\n    }\n    \n    // Return to office\n    route.push_back({400, 400});\n    \n    // Output\n    cout << \"50\";\n    for (int id : selected_ids) {\n        cout << \" \" << id;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        \n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n    \n    int getComponents() {\n        return components;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const 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<pair<int, int>> edges(M);\n    vector<int> distances(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n        int dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        int dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        distances[i] = round(sqrt(dx * dx + dy * dy));\n    }\n    \n    UnionFind uf(N);\n    int edges_accepted = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n        \n        int u = edges[i].first;\n        int v = edges[i].second;\n        int d_i = distances[i];\n        \n        int decision = 0;\n        \n        if (!uf.connected(u, v)) {\n            // Edge connects different components\n            double ratio = (double)l_i / d_i;\n            int remaining_edges = M - i - 1;\n            int edges_needed = uf.getComponents() - 1;\n            \n            // Be selective only if we have plenty of edges left\n            if (edges_needed > 0 && remaining_edges > edges_needed * 3 && ratio > 2.8) {\n                // Very bad edge and we have plenty of opportunities left\n                decision = 0;\n            } else {\n                // Accept the edge - either it's good enough or we need it for connectivity\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            }\n        }\n        // Reject edges that would create cycles (already connected)\n        \n        cout << decision << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Position& other) const {\n        return x < other.x || (x == other.x && y < other.y);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> walls;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dirChar[4] = {'U', 'D', 'L', 'R'};\n    const char blockChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) const {\n        return x >= 1 && x <= GRID_SIZE && y >= 1 && y <= GRID_SIZE;\n    }\n    \n    bool canMakeWall(int x, int y, const set<Position>& plannedWalls) const {\n        if (!isValid(x, y) || walls[x][y]) return false;\n        if (plannedWalls.count({x, y})) return false;\n        \n        // Check no pets or humans at this position\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return false;\n        }\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        // Check no pets adjacent to this position\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny)) {\n                for (const auto& p : petPos) {\n                    if (p.x == nx && p.y == ny) return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    bool canMoveTo(int x, int y, const set<Position>& wallsBeingBuilt) const {\n        if (!isValid(x, y)) return false;\n        if (walls[x][y]) return false;\n        if (wallsBeingBuilt.count({x, y})) return false;\n        return true;\n    }\n    \n    double distanceToNearestPet(int x, int y) const {\n        double minDist = 1e9;\n        for (const auto& p : petPos) {\n            double dist = abs(p.x - x) + abs(p.y - y);\n            minDist = min(minDist, dist);\n        }\n        return minDist;\n    }\n    \n    Position findCenterTarget() const {\n        // Find a good target position for humans to gather\n        Position best = {15, 15};\n        double bestScore = -1e9;\n        \n        // Try different positions, prefer corners and edges away from pets\n        for (int x = 5; x <= 25; x += 5) {\n            for (int y = 5; y <= 25; y += 5) {\n                double score = 0;\n                \n                // Prefer positions far from pets\n                for (const auto& p : petPos) {\n                    double dist = sqrt((p.x - x) * (p.x - x) + (p.y - y) * (p.y - y));\n                    score += dist;\n                }\n                \n                // Slightly prefer edges/corners\n                if (x <= 10 || x >= 20) score += 5;\n                if (y <= 10 || y >= 20) score += 5;\n                \n                // Prefer positions close to current human positions\n                for (const auto& h : humanPos) {\n                    double dist = abs(h.x - x) + abs(h.y - y);\n                    score -= dist * 0.3;\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    best = {x, y};\n                }\n            }\n        }\n        \n        return best;\n    }\n    \npublic:\n    void solve() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n        }\n        \n        walls.assign(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        \n        for (int turn = 0; turn < MAX_TURNS; turn++) {\n            string actions(M, '.');\n            set<Position> wallsBeingBuilt;\n            set<Position> nextPositions;\n            \n            Position target = findCenterTarget();\n            \n            // Plan actions for each human\n            vector<char> plannedActions(M, '.');\n            vector<Position> plannedMoves(M);\n            vector<Position> plannedWalls(M, {-1, -1});\n            \n            for (int i = 0; i < M; i++) {\n                plannedMoves[i] = humanPos[i];\n            }\n            \n            // First pass: decide on actions\n            for (int i = 0; i < M; i++) {\n                Position& human = humanPos[i];\n                \n                // Early game: move towards target\n                if (turn < 60) {\n                    int dist = abs(human.x - target.x) + abs(human.y - target.y);\n                    if (dist > 4) {\n                        int bestDir = -1;\n                        int minDist = dist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                int newDist = abs(nx - target.x) + abs(ny - target.y);\n                                if (newDist < minDist) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            plannedActions[i] = dirChar[bestDir];\n                            plannedMoves[i] = {human.x + dx[bestDir], human.y + dy[bestDir]};\n                            continue;\n                        }\n                    }\n                }\n                \n                // Try to build walls\n                if (turn >= 40) {\n                    int bestWallDir = -1;\n                    double bestWallScore = -1e9;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int wx = human.x + dx[d];\n                        int wy = human.y + dy[d];\n                        \n                        if (canMakeWall(wx, wy, wallsBeingBuilt)) {\n                            double score = 0;\n                            \n                            // Prefer walls that separate from pets\n                            double petDist = distanceToNearestPet(wx, wy);\n                            score += petDist * 2;\n                            \n                            // Prefer walls that connect to existing walls\n                            int wallsNearby = 0;\n                            for (int dd = 0; dd < 4; dd++) {\n                                int nwx = wx + dx[dd];\n                                int nwy = wy + dy[dd];\n                                if (isValid(nwx, nwy) && walls[nwx][nwy]) {\n                                    wallsNearby++;\n                                }\n                            }\n                            score += wallsNearby * 10;\n                            \n                            // Avoid building walls too close to the center of human group\n                            int humansNearby = 0;\n                            for (const auto& h : humanPos) {\n                                if (abs(h.x - wx) + abs(h.y - wy) <= 2) {\n                                    humansNearby++;\n                                }\n                            }\n                            if (humansNearby >= M - 1) {\n                                score -= 20;\n                            }\n                            \n                            if (score > bestWallScore) {\n                                bestWallScore = score;\n                                bestWallDir = d;\n                            }\n                        }\n                    }\n                    \n                    if (bestWallDir != -1 && bestWallScore > 0) {\n                        int wx = human.x + dx[bestWallDir];\n                        int wy = human.y + dy[bestWallDir];\n                        plannedActions[i] = blockChar[bestWallDir];\n                        plannedWalls[i] = {wx, wy};\n                        wallsBeingBuilt.insert({wx, wy});\n                    }\n                }\n                \n                // If still no action and late game, try to move away from pets\n                if (plannedActions[i] == '.' && turn >= 100) {\n                    double minPetDist = distanceToNearestPet(human.x, human.y);\n                    if (minPetDist < 3) {\n                        int bestDir = -1;\n                        double maxDist = minPetDist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                double newDist = distanceToNearestPet(nx, ny);\n                                if (newDist > maxDist) {\n                                    maxDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            plannedActions[i] = dirChar[bestDir];\n                            plannedMoves[i] = {human.x + dx[bestDir], human.y + dy[bestDir]};\n                        }\n                    }\n                }\n            }\n            \n            // Second pass: validate and fix conflicts\n            for (int i = 0; i < M; i++) {\n                if (plannedActions[i] == 'U' || plannedActions[i] == 'D' || \n                    plannedActions[i] == 'L' || plannedActions[i] == 'R') {\n                    // Check if trying to move to a square being made into a wall\n                    if (!canMoveTo(plannedMoves[i].x, plannedMoves[i].y, wallsBeingBuilt)) {\n                        plannedActions[i] = '.';\n                        plannedMoves[i] = humanPos[i];\n                    }\n                }\n                actions[i] = plannedActions[i];\n            }\n            \n            cout << actions << endl;\n            cout.flush();\n            \n            // Apply human actions\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                Position& human = humanPos[i];\n                \n                if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    for (int d = 0; d < 4; d++) {\n                        if (dirChar[d] == action) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            if (canMoveTo(nx, ny, wallsBeingBuilt)) {\n                                human.x = nx;\n                                human.y = ny;\n                            }\n                            break;\n                        }\n                    }\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            if (isValid(wx, wy)) {\n                                walls[wx][wy] = true;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Read pet movements\n            for (int i = 0; i < N; i++) {\n                string petMove;\n                cin >> petMove;\n                \n                for (char c : petMove) {\n                    if (c != '.') {\n                        for (int d = 0; d < 4; d++) {\n                            if (dirChar[d] == c) {\n                                petPos[i].x += dx[d];\n                                petPos[i].y += dy[d];\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    // Build wall information\n    vector<vector<bool>> canGoRight(20, vector<bool>(20, false));\n    vector<vector<bool>> canGoDown(20, vector<bool>(20, false));\n    \n    for (int i = 0; i < 20; i++) {\n        for (int j = 0; j < 19; j++) {\n            if (h[i][j] == '0') {\n                canGoRight[i][j] = true;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 19; i++) {\n        for (int j = 0; j < 20; j++) {\n            if (v[i][j] == '0') {\n                canGoDown[i][j] = true;\n            }\n        }\n    }\n    \n    // BFS to find shortest path\n    queue<pair<int,int>> q;\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> parent(20, vector<pair<int,int>>(20, {-1, -1}));\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        // Check all 4 directions\n        if (j < 19 && canGoRight[i][j] && dist[i][j+1] == -1) {\n            dist[i][j+1] = dist[i][j] + 1;\n            parent[i][j+1] = {i, j};\n            q.push({i, j+1});\n        }\n        if (j > 0 && canGoRight[i][j-1] && dist[i][j-1] == -1) {\n            dist[i][j-1] = dist[i][j] + 1;\n            parent[i][j-1] = {i, j};\n            q.push({i, j-1});\n        }\n        if (i < 19 && canGoDown[i][j] && dist[i+1][j] == -1) {\n            dist[i+1][j] = dist[i][j] + 1;\n            parent[i+1][j] = {i, j};\n            q.push({i+1, j});\n        }\n        if (i > 0 && canGoDown[i-1][j] && dist[i-1][j] == -1) {\n            dist[i-1][j] = dist[i][j] + 1;\n            parent[i-1][j] = {i, j};\n            q.push({i-1, j});\n        }\n    }\n    \n    // Reconstruct shortest path\n    string shortestPath;\n    int ci = ti, cj = tj;\n    vector<pair<int,int>> pathCoords;\n    \n    while (ci != si || cj != sj) {\n        pathCoords.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        \n        // Determine the move\n        if (ci - pi == 1) shortestPath = \"D\" + shortestPath;\n        else if (ci - pi == -1) shortestPath = \"U\" + shortestPath;\n        else if (cj - pj == 1) shortestPath = \"R\" + shortestPath;\n        else if (cj - pj == -1) shortestPath = \"L\" + shortestPath;\n        \n        ci = pi;\n        cj = pj;\n    }\n    \n    // Strategy: repeat each move based on p value to ensure robustness\n    string result;\n    int baseRepeat = 1;\n    \n    // Adjust repetition based on p\n    if (p >= 0.4) baseRepeat = 3;\n    else if (p >= 0.3) baseRepeat = 2;\n    else if (p >= 0.2) baseRepeat = 2;\n    else baseRepeat = 1;\n    \n    // First, add the path with repetitions for each move\n    for (char move : shortestPath) {\n        for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n            result += move;\n        }\n    }\n    \n    // If we have space left, repeat the entire path for extra robustness\n    int pathLen = shortestPath.length() * baseRepeat;\n    while (result.length() + pathLen <= 200) {\n        for (char move : shortestPath) {\n            for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n                result += move;\n            }\n        }\n    }\n    \n    // Fill remaining space with the shortest path\n    int idx = 0;\n    while (result.length() < 200 && result.length() < 200) {\n        result += shortestPath[idx % shortestPath.length()];\n        idx++;\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint rotations[N][N];\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nint rotate_tile(int tile) {\n    if (tile <= 3) return (tile + 1) % 4;\n    if (tile == 4) return 5;\n    if (tile == 5) return 4;\n    if (tile == 6) return 7;\n    return 6;\n}\n\nint get_tile_state(int i, int j) {\n    int t = tiles[i][j];\n    for (int r = 0; r < rotations[i][j]; r++) {\n        t = rotate_tile(t);\n    }\n    return t;\n}\n\nint trace_path(int si, int sj, int sd, vector<vector<vector<bool>>>& visited) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;\n        \n        int tile_state = get_tile_state(i, j);\n        int d2 = to[tile_state][d];\n        if (d2 == -1) return 0;\n        \n        int ni = i + di[d2];\n        int nj = j + dj[d2];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return 0;\n        \n        i = ni;\n        j = nj;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (length > N * N * 4) return 0; // Prevent infinite loops\n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\nvector<int> find_all_loops() {\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    vector<int> loops;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = trace_path(i, j, d, visited);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    // Mark all positions in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ci][cj][cd] = true;\n                        int tile_state = get_tile_state(ci, cj);\n                        int d2 = to[tile_state][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    return loops;\n}\n\nint calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    sort(loops.rbegin(), loops.rend());\n    return loops[0] * loops[1];\n}\n\n// Try to connect tiles greedily\nvoid greedy_init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; r++) {\n                rotations[i][j] = r;\n                int connections = 0;\n                int tile_state = get_tile_state(i, j);\n                \n                // Count valid connections to neighbors\n                for (int d = 0; d < 4; d++) {\n                    int d2 = to[tile_state][d];\n                    if (d2 == -1) continue;\n                    \n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    \n                    int neighbor_state = get_tile_state(ni, nj);\n                    int return_dir = (d2 + 2) % 4;\n                    if (to[neighbor_state][return_dir] != -1) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rotations[i][j] = best_rot;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rot_dist(0, 3);\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    // Start with greedy initialization\n    greedy_init();\n    \n    int best_score = calculate_score();\n    int best_rotations[N][N];\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    auto start_time = chrono::steady_clock::now();\n    int iteration = 0;\n    int no_improve = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        iteration++;\n        \n        // Multi-restart strategy\n        if (no_improve > 10000) {\n            // Random restart\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n            no_improve = 0;\n        }\n        \n        // Try different neighborhood moves\n        int move_type = rng() % 3;\n        vector<pair<pair<int,int>, int>> changes;\n        \n        if (move_type == 0) {\n            // Single tile change\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            int old_rot = rotations[i][j];\n            int new_rot = rot_dist(rng);\n            if (new_rot == old_rot) continue;\n            changes.push_back({{i, j}, old_rot});\n            rotations[i][j] = new_rot;\n        } else if (move_type == 1) {\n            // Change 2x2 block\n            int i = rng() % (N-1);\n            int j = rng() % (N-1);\n            for (int di = 0; di < 2; di++) {\n                for (int dj = 0; dj < 2; dj++) {\n                    changes.push_back({{i+di, j+dj}, rotations[i+di][j+dj]});\n                    rotations[i+di][j+dj] = rot_dist(rng);\n                }\n            }\n        } else {\n            // Change a row or column\n            if (rng() % 2 == 0) {\n                int i = pos_dist(rng);\n                for (int j = 0; j < N; j++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            } else {\n                int j = pos_dist(rng);\n                for (int i = 0; i < N; i++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n        }\n        \n        int new_score = calculate_score();\n        \n        if (new_score > best_score) {\n            best_score = new_score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n            no_improve = 0;\n        } else {\n            // Revert changes with some probability\n            double temp = max(1.0, 50.0 * (1.0 - iteration / 100000.0));\n            if (prob_dist(rng) >= exp((new_score - best_score) / temp)) {\n                for (auto& [pos, old_val] : changes) {\n                    rotations[pos.first][pos.second] = old_val;\n                }\n            }\n            no_improve++;\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\npair<int, int> empty_pos;\nvector<char> answer;\nmt19937 rng(42);\n\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int opposite_dir[] = {1, 0, 3, 2};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n                return;\n            }\n        }\n    }\n}\n\nvoid make_move(int dir) {\n    int nx = empty_pos.first + dx[dir];\n    int ny = empty_pos.second + dy[dir];\n    if (in_bounds(nx, ny)) {\n        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        empty_pos = {nx, ny};\n        answer.push_back(dir_char[dir]);\n    }\n}\n\nstruct UnionFind {\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    int get_size(int x) { return size[find(x)]; }\n};\n\nint get_tree_size() {\n    // Map positions to indices\n    map<pair<int,int>, int> pos_to_id;\n    int id = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != 0) {\n                pos_to_id[{i,j}] = id++;\n            }\n        }\n    }\n    \n    if (id == 0) return 0;\n    \n    UnionFind uf(id);\n    vector<set<int>> adj(id);\n    int edge_count = 0;\n    \n    // Build graph\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 cur_id = pos_to_id[{i,j}];\n            \n            // Check down\n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    int next_id = pos_to_id[{i+1,j}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n            \n            // Check right\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    int next_id = pos_to_id[{i,j+1}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find largest tree (connected component without cycles)\n    int max_tree = 0;\n    map<int, vector<int>> components;\n    for (int i = 0; i < id; i++) {\n        components[uf.find(i)].push_back(i);\n    }\n    \n    for (auto& [root, comp] : components) {\n        int comp_edges = 0;\n        set<pair<int,int>> counted;\n        for (int v : comp) {\n            for (int u : adj[v]) {\n                if (counted.insert({min(u,v), max(u,v)}).second) {\n                    comp_edges++;\n                }\n            }\n        }\n        \n        // It's a tree if edges = vertices - 1\n        if (comp_edges == (int)comp.size() - 1) {\n            max_tree = max(max_tree, (int)comp.size());\n        }\n    }\n    \n    return max_tree;\n}\n\n// BFS to move empty square to target position\nvector<int> move_empty_to(pair<int,int> target) {\n    if (empty_pos == target) return {};\n    \n    queue<pair<pair<int,int>, vector<int>>> q;\n    set<pair<int,int>> visited;\n    q.push({empty_pos, {}});\n    visited.insert(empty_pos);\n    \n    while (!q.empty()) {\n        auto [pos, path] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = pos.first + dx[dir];\n            int ny = pos.second + dy[dir];\n            if (!in_bounds(nx, ny) || visited.count({nx, ny})) continue;\n            \n            vector<int> new_path = path;\n            new_path.push_back(dir);\n            \n            if (make_pair(nx, ny) == target) {\n                return new_path;\n            }\n            \n            visited.insert({nx, ny});\n            q.push({{nx, ny}, new_path});\n        }\n    }\n    return {};\n}\n\n// Evaluate board state\ndouble evaluate_board() {\n    int tree_size = get_tree_size();\n    int connected_edges = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    connected_edges++;\n                }\n            }\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    connected_edges++;\n                }\n            }\n        }\n    }\n    \n    return tree_size * 1000.0 + connected_edges;\n}\n\nvoid solve() {\n    int best_tree = get_tree_size();\n    auto best_board = board;\n    auto best_empty = empty_pos;\n    int stagnation = 0;\n    \n    while (answer.size() < T * 0.95 && best_tree < N * N - 1) {\n        double temp = 1.0 - (double)answer.size() / T;\n        \n        if (stagnation > 50) {\n            // Strategic restart: try to connect largest components\n            int depth = min(5, (int)(T - answer.size()) / 10);\n            \n            // Try multiple random sequences and pick the best\n            auto save_board = board;\n            auto save_empty = empty_pos;\n            int save_ans_size = answer.size();\n            \n            double best_eval = evaluate_board();\n            vector<int> best_moves;\n            \n            for (int attempt = 0; attempt < 10; attempt++) {\n                board = save_board;\n                empty_pos = save_empty;\n                vector<int> moves;\n                \n                for (int m = 0; m < depth; m++) {\n                    vector<int> dirs;\n                    for (int d = 0; d < 4; d++) {\n                        if (in_bounds(empty_pos.first + dx[d], empty_pos.second + dy[d])) {\n                            if (moves.empty() || d != opposite_dir[moves.back()]) {\n                                dirs.push_back(d);\n                            }\n                        }\n                    }\n                    if (!dirs.empty()) {\n                        int dir = dirs[rng() % dirs.size()];\n                        moves.push_back(dir);\n                        int nx = empty_pos.first + dx[dir];\n                        int ny = empty_pos.second + dy[dir];\n                        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                        empty_pos = {nx, ny};\n                    }\n                }\n                \n                double eval = evaluate_board();\n                if (eval > best_eval) {\n                    best_eval = eval;\n                    best_moves = moves;\n                }\n            }\n            \n            board = save_board;\n            empty_pos = save_empty;\n            for (int dir : best_moves) {\n                make_move(dir);\n            }\n            \n            stagnation = 0;\n        }\n        \n        // Try deeper lookahead\n        int lookahead = min(3, (int)(T - answer.size()) / 20);\n        \n        function<pair<double, vector<int>>(int, int, vector<int>&)> search = \n            [&](int depth, int last_dir, vector<int>& path) -> pair<double, vector<int>> {\n            \n            if (depth == 0) {\n                return {evaluate_board(), path};\n            }\n            \n            double best_score = -1e9;\n            vector<int> best_path;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                if (last_dir != -1 && dir == opposite_dir[last_dir]) continue;\n                \n                int nx = empty_pos.first + dx[dir];\n                int ny = empty_pos.second + dy[dir];\n                if (!in_bounds(nx, ny)) continue;\n                \n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                auto old_empty = empty_pos;\n                empty_pos = {nx, ny};\n                path.push_back(dir);\n                \n                auto [score, sub_path] = search(depth - 1, dir, path);\n                \n                if (score > best_score || \n                    (score == best_score && (rng() % 100) < temp * 50)) {\n                    best_score = score;\n                    best_path = sub_path;\n                }\n                \n                path.pop_back();\n                empty_pos = old_empty;\n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n            }\n            \n            return {best_score, best_path};\n        };\n        \n        vector<int> empty_path;\n        auto [score, path] = search(lookahead, -1, empty_path);\n        \n        if (!path.empty()) {\n            make_move(path[0]);\n            \n            int new_tree = get_tree_size();\n            if (new_tree > best_tree) {\n                best_tree = new_tree;\n                best_board = board;\n                best_empty = empty_pos;\n                stagnation = 0;\n            } else {\n                stagnation++;\n            }\n        } else {\n            stagnation++;\n        }\n    }\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            if (line[j] >= '0' && line[j] <= '9') {\n                board[i][j] = line[j] - '0';\n            } else {\n                board[i][j] = line[j] - 'a' + 10;\n            }\n        }\n    }\n    \n    find_empty();\n    solve();\n    \n    for (char c : answer) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst double RADIUS = 10000.0;\nconst double EPS = 1e-9;\nconst int MAX_COORD = 1000000000;\n\nstruct Point {\n    double x, y;\n    Point(double x = 0, double y = 0) : x(x), y(y) {}\n    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }\n    double cross(const Point& p) const { return x * p.y - y * p.x; }\n};\n\nstruct Line {\n    int px, py, qx, qy;\n    Line(int px = 0, int py = 0, int qx = 0, int qy = 0) : px(px), py(py), qx(qx), qy(qy) {}\n    \n    int side(const Point& p) const {\n        double dx1 = qx - px;\n        double dy1 = qy - py;\n        double dx2 = p.x - px;\n        double dy2 = p.y - py;\n        double v = dx1 * dy2 - dy1 * dx2;\n        if (v > EPS) return 1;\n        if (v < -EPS) return -1;\n        return 0;\n    }\n};\n\nint N, K;\nvector<int> a(11);\nvector<Point> strawberries;\nvector<Line> lines;\nvector<Line> bestLines;\nint bestScore = 0;\nvector<int> currentRegions;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool insideCircle(const Point& p) {\n    return p.x * p.x + p.y * p.y < RADIUS * RADIUS - EPS;\n}\n\nvoid computeRegions() {\n    currentRegions.resize(N);\n    \n    for (int i = 0; i < N; i++) {\n        if (!insideCircle(strawberries[i])) {\n            currentRegions[i] = -1;\n            continue;\n        }\n        \n        bool onLine = false;\n        int code = 0;\n        for (int j = 0; j < (int)lines.size(); j++) {\n            int s = lines[j].side(strawberries[i]);\n            if (s == 0) {\n                onLine = true;\n                break;\n            }\n            if (s > 0) code |= (1 << j);\n        }\n        currentRegions[i] = onLine ? -1 : code;\n    }\n}\n\nint calculateScoreFromRegions() {\n    map<int, int> regionCount;\n    \n    for (int r : currentRegions) {\n        if (r >= 0) regionCount[r]++;\n    }\n    \n    vector<int> b(11, 0);\n    for (auto& [r, cnt] : regionCount) {\n        if (cnt <= 10) b[cnt]++;\n    }\n    \n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(a[d], b[d]);\n    }\n    \n    return score;\n}\n\nint calculateScore() {\n    computeRegions();\n    return calculateScoreFromRegions();\n}\n\nLine randomLine() {\n    uniform_int_distribution<int> dist(-20000, 20000);\n    int px = dist(rng);\n    int py = dist(rng);\n    int qx = dist(rng);\n    int qy = dist(rng);\n    \n    while (px == qx && py == qy) {\n        qx = dist(rng);\n        qy = dist(rng);\n    }\n    \n    return Line(px, py, qx, qy);\n}\n\nLine targetedLine() {\n    int i = rng() % N;\n    int j = rng() % N;\n    while (i == j) j = rng() % N;\n    \n    double dx = strawberries[j].x - strawberries[i].x;\n    double dy = strawberries[j].y - strawberries[i].y;\n    \n    uniform_real_distribution<double> offset_dist(-1000, 1000);\n    uniform_real_distribution<double> angle_dist(-0.3, 0.3);\n    \n    double angle = atan2(dy, dx) + angle_dist(rng);\n    double offset = offset_dist(rng);\n    \n    int px = (int)(strawberries[i].x + offset * cos(angle));\n    int py = (int)(strawberries[i].y + offset * sin(angle));\n    int qx = px + (int)(10000 * cos(angle + M_PI/2));\n    int qy = py + (int)(10000 * sin(angle + M_PI/2));\n    \n    return Line(px, py, qx, qy);\n}\n\nvoid solve() {\n    lines.clear();\n    \n    double startTime = clock();\n    double timeLimit = 2.7 * CLOCKS_PER_SEC; // Reduced from 2.8 to ensure we don't exceed\n    \n    // Quick greedy initialization with fewer trials\n    for (int iter = 0; iter < min(15, K); iter++) {\n        if (clock() - startTime > timeLimit * 0.3) break; // Use at most 30% time for initialization\n        \n        Line bestLine = targetedLine();\n        int bestImprovement = -1;\n        int currentScore = calculateScore();\n        \n        for (int trial = 0; trial < 20; trial++) { // Reduced from 50\n            Line candidate = (trial < 10) ? targetedLine() : randomLine();\n            lines.push_back(candidate);\n            int newScore = calculateScore();\n            lines.pop_back();\n            \n            if (newScore - currentScore > bestImprovement) {\n                bestImprovement = newScore - currentScore;\n                bestLine = candidate;\n            }\n        }\n        \n        if (bestImprovement >= 0) {\n            lines.push_back(bestLine);\n        }\n    }\n    \n    // Simulated annealing with time checks\n    int currentScore = calculateScore();\n    bestLines = lines;\n    bestScore = currentScore;\n    \n    double temp = 10.0;\n    int iter = 0;\n    int checkInterval = 100; // Check time every 100 iterations\n    \n    while (clock() - startTime < timeLimit) {\n        iter++;\n        \n        if (iter % checkInterval == 0) {\n            double elapsed = (clock() - startTime) / CLOCKS_PER_SEC;\n            if (elapsed > 2.65) break; // Stop early to be safe\n            temp = 10.0 * (1.0 - elapsed / 2.7);\n        }\n        \n        int op = rng() % 100;\n        \n        if (op < 30 && lines.size() < K) {\n            // Add a line\n            Line newLine = (rng() % 2) ? targetedLine() : randomLine();\n            lines.push_back(newLine);\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.pop_back();\n            }\n        } else if (op < 50 && lines.size() > 5) {\n            // Remove a line\n            int idx = rng() % lines.size();\n            Line removed = lines[idx];\n            lines.erase(lines.begin() + idx);\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.insert(lines.begin() + idx, removed);\n            }\n        } else if (lines.size() > 0) {\n            // Modify a line\n            int idx = rng() % lines.size();\n            Line old = lines[idx];\n            lines[idx] = (rng() % 2) ? targetedLine() : randomLine();\n            int newScore = calculateScore();\n            \n            double prob = exp((newScore - currentScore) / max(temp, 0.01));\n            if (newScore > currentScore || (rng() % 10000) / 10000.0 < prob) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines[idx] = old;\n            }\n        }\n    }\n    \n    lines = bestLines;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    \n    solve();\n    \n    cout << lines.size() << \"\\n\";\n    for (const Line& line : lines) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return x != p.x ? x < p.x : y < p.y;\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n};\n\nstruct Rectangle {\n    Point p1, p2, p3, p4;\n    Rectangle(Point a, Point b, Point c, Point d) : p1(a), p2(b), p3(c), p4(d) {}\n};\n\nint N, M;\nset<Point> dots;\nvector<Rectangle> rectangles;\nset<pair<Point, Point>> usedSegments;\n\nint weight(int x, int y) {\n    int c = (N - 1) / 2;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\nbool isValidPoint(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nbool isRectangle(Point p1, Point p2, Point p3, Point p4, bool& isAxis) {\n    // Check if 4 points form a rectangle (axis-aligned or 45\u00b0 rotated)\n    vector<Point> pts = {p1, p2, p3, p4};\n    sort(pts.begin(), pts.end());\n    \n    // Check axis-aligned rectangle\n    if (pts[0].x == pts[1].x && pts[2].x == pts[3].x && \n        pts[0].y == pts[2].y && pts[1].y == pts[3].y) {\n        isAxis = true;\n        return true;\n    }\n    \n    // Check 45\u00b0 rotated rectangle\n    int cx = (pts[0].x + pts[1].x + pts[2].x + pts[3].x) / 4;\n    int cy = (pts[0].y + pts[1].y + pts[2].y + pts[3].y) / 4;\n    \n    vector<pair<int, int>> dists;\n    for (auto& p : pts) {\n        int dx = p.x - cx;\n        int dy = p.y - cy;\n        dists.push_back({dx * dx + dy * dy, dx * 1000 + dy});\n    }\n    sort(dists.begin(), dists.end());\n    \n    if (dists[0].first == dists[1].first && dists[1].first == dists[2].first && \n        dists[2].first == dists[3].first) {\n        isAxis = false;\n        return true;\n    }\n    \n    return false;\n}\n\nvector<Point> getPerimeter(Point p1, Point p2, Point p3, Point p4) {\n    vector<Point> perimeter;\n    \n    // Find the correct order of points\n    vector<Point> pts = {p2, p3, p4};\n    sort(pts.begin(), pts.end(), [&](Point a, Point b) {\n        int d1 = abs(a.x - p1.x) + abs(a.y - p1.y);\n        int d2 = abs(b.x - p1.x) + abs(b.y - p1.y);\n        return d1 < d2;\n    });\n    \n    Point a = p1, b = pts[0], c = pts[2], d = pts[1];\n    \n    // Generate all points on perimeter\n    auto addLine = [&](Point from, Point to) {\n        int dx = (to.x > from.x) ? 1 : (to.x < from.x) ? -1 : 0;\n        int dy = (to.y > from.y) ? 1 : (to.y < from.y) ? -1 : 0;\n        Point curr = from;\n        while (curr.x != to.x || curr.y != to.y) {\n            perimeter.push_back(curr);\n            curr.x += dx;\n            curr.y += dy;\n        }\n    };\n    \n    addLine(a, b);\n    addLine(b, c);\n    addLine(c, d);\n    addLine(d, a);\n    \n    return perimeter;\n}\n\nbool canPlaceRectangle(Point newDot, Point p2, Point p3, Point p4) {\n    if (dots.count(newDot)) return false;\n    \n    bool isAxis;\n    if (!isRectangle(newDot, p2, p3, p4, isAxis)) return false;\n    \n    vector<Point> perimeter = getPerimeter(newDot, p2, p3, p4);\n    \n    // Check no other dots on perimeter\n    for (auto& p : perimeter) {\n        if (p == newDot || p == p2 || p == p3 || p == p4) continue;\n        if (dots.count(p)) return false;\n    }\n    \n    // Check segments don't overlap with existing rectangles\n    for (int i = 0; i < perimeter.size(); i++) {\n        Point a = perimeter[i];\n        Point b = perimeter[(i + 1) % perimeter.size()];\n        if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n        if (usedSegments.count({a, b})) return false;\n    }\n    \n    return true;\n}\n\nint main() {\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert(Point(x, y));\n    }\n    \n    vector<vector<int>> result;\n    \n    // Try to add dots and rectangles\n    for (int iter = 0; iter < 1000; iter++) {\n        Point bestNew;\n        vector<Point> bestRect;\n        int bestWeight = -1;\n        \n        // Try all combinations of 3 existing dots\n        vector<Point> dotVec(dots.begin(), dots.end());\n        int n = dotVec.size();\n        \n        for (int i = 0; i < min(n, 50); i++) {\n            for (int j = i + 1; j < min(n, 50); j++) {\n                for (int k = j + 1; k < min(n, 50); k++) {\n                    Point p2 = dotVec[i], p3 = dotVec[j], p4 = dotVec[k];\n                    \n                    // Try different positions for new dot\n                    for (int x = 0; x < N; x++) {\n                        for (int y = 0; y < N; y++) {\n                            Point newDot(x, y);\n                            if (canPlaceRectangle(newDot, p2, p3, p4)) {\n                                int w = weight(x, y);\n                                if (w > bestWeight) {\n                                    bestWeight = w;\n                                    bestNew = newDot;\n                                    bestRect = {newDot, p2, p3, p4};\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (bestWeight == -1) break;\n        \n        // Add the new dot and rectangle\n        dots.insert(bestNew);\n        result.push_back({bestNew.x, bestNew.y, bestRect[1].x, bestRect[1].y, \n                         bestRect[2].x, bestRect[2].y, bestRect[3].x, bestRect[3].y});\n        \n        // Mark used segments\n        vector<Point> perimeter = getPerimeter(bestRect[0], bestRect[1], bestRect[2], bestRect[3]);\n        for (int i = 0; i < perimeter.size(); i++) {\n            Point a = perimeter[i];\n            Point b = perimeter[(i + 1) % perimeter.size()];\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            usedSegments.insert({a, b});\n        }\n    }\n    \n    cout << result.size() << endl;\n    for (auto& r : result) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << \" \";\n            cout << r[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int TOTAL = 100;\n\nstruct Board {\n    int grid[N][N]; // 0 = empty, 1-3 = candy flavors\n    \n    Board() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void place(int pos, int flavor) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tiltForward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = 0;\n            for (int i = 0; i < N; i++) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltBackward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = N-1;\n            for (int i = N-1; i >= 0; i--) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tiltLeft() {\n        for (int i = 0; i < N; i++) {\n            int writePos = 0;\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltRight() {\n        for (int i = 0; i < N; i++) {\n            int writePos = N-1;\n            for (int j = N-1; j >= 0; j--) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') tiltForward();\n        else if (dir == 'B') tiltBackward();\n        else if (dir == 'L') tiltLeft();\n        else if (dir == 'R') tiltRight();\n    }\n    \n    // Get connected component sizes and info\n    tuple<vector<vector<int>>, int, vector<int>> analyzeComponents() {\n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        \n        vector<vector<int>> componentSizes(4); // index 0 unused, 1-3 for flavors\n        int totalComponents = 0;\n        vector<int> largestComponent(4, 0);\n        \n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int flavor = grid[i][j];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    componentSizes[flavor].push_back(size);\n                    largestComponent[flavor] = max(largestComponent[flavor], size);\n                    totalComponents++;\n                }\n            }\n        }\n        return {componentSizes, totalComponents, largestComponent};\n    }\n    \n    // Enhanced evaluation function\n    double evaluate(int t, const vector<int>& allFlavors) {\n        auto [componentSizes, totalComponents, largestComponent] = analyzeComponents();\n        \n        double score = 0;\n        \n        // Main scoring: sum of squares\n        for (int flavor = 1; flavor <= 3; flavor++) {\n            for (int size : componentSizes[flavor]) {\n                score += size * size * 1000;\n            }\n        }\n        \n        // Penalty for fragmentation\n        score -= totalComponents * 200;\n        \n        // Bonus for large components\n        for (int flavor = 1; flavor <= 3; flavor++) {\n            score += largestComponent[flavor] * largestComponent[flavor] * 50;\n        }\n        \n        // Consider compactness (candies should be close together)\n        double compactness = calculateCompactness();\n        score += compactness * 100;\n        \n        // Look ahead bonus: prefer consolidating flavors that will appear soon\n        if (t < TOTAL - 1) {\n            vector<int> upcomingCount(4, 0);\n            for (int i = t + 1; i < min(t + 15, TOTAL); i++) {\n                upcomingCount[allFlavors[i]]++;\n            }\n            \n            for (int flavor = 1; flavor <= 3; flavor++) {\n                if (upcomingCount[flavor] > 0 && largestComponent[flavor] > 0) {\n                    // Bonus for having a large component of a flavor that will appear soon\n                    score += largestComponent[flavor] * upcomingCount[flavor] * 30;\n                }\n            }\n        }\n        \n        return score;\n    }\n    \n    double calculateCompactness() {\n        double totalDist = 0;\n        int count = 0;\n        \n        for (int flavor = 1; flavor <= 3; flavor++) {\n            vector<pair<int, int>> positions;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] == flavor) {\n                        positions.push_back({i, j});\n                    }\n                }\n            }\n            \n            if (positions.size() <= 1) continue;\n            \n            // Calculate average distance between same-flavor candies\n            for (size_t i = 0; i < positions.size(); i++) {\n                for (size_t j = i + 1; j < positions.size(); j++) {\n                    int dist = abs(positions[i].first - positions[j].first) + \n                              abs(positions[i].second - positions[j].second);\n                    totalDist += dist;\n                    count++;\n                }\n            }\n        }\n        \n        // Lower distance is better, so return negative\n        return count > 0 ? -totalDist / count : 0;\n    }\n    \n    // Count adjacent pairs of same flavor\n    int countAdjacentPairs() {\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (i + 1 < N && grid[i+1][j] == grid[i][j]) count++;\n                    if (j + 1 < N && grid[i][j+1] == grid[i][j]) count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(TOTAL);\n    for (int i = 0; i < TOTAL; i++) {\n        cin >> flavors[i];\n    }\n    \n    Board board;\n    \n    for (int t = 0; t < TOTAL; t++) {\n        int pos;\n        cin >> pos;\n        \n        board.place(pos, flavors[t]);\n        \n        if (t == TOTAL - 1) break;\n        \n        char dirs[] = {'F', 'B', 'L', 'R'};\n        char bestDir = 'F';\n        double bestScore = -1e9;\n        \n        // Evaluate each direction\n        for (char dir : dirs) {\n            Board tempBoard = board;\n            tempBoard.tilt(dir);\n            \n            double score;\n            if (t < 10) {\n                // Very early game: prioritize adjacent pairs\n                score = tempBoard.countAdjacentPairs() * 1000.0;\n                auto [comp, total, largest] = tempBoard.analyzeComponents();\n                score -= total * 10; // Still prefer fewer components\n            } else {\n                // Use full evaluation\n                score = tempBoard.evaluate(t, flavors);\n            }\n            \n            // Tie-breaking: prefer certain directions based on board state\n            if (abs(score - bestScore) < 0.01) {\n                // If scores are very close, prefer to keep board compact\n                if (dir == 'L' || dir == 'F') score += 0.001;\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestDir = dir;\n            }\n        }\n        \n        board.tilt(bestDir);\n        cout << bestDir << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass Graph {\n    int N;\n    vector<vector<int>> adj;\n    \npublic:\n    Graph(int n) : N(n), adj(n, vector<int>(n, 0)) {}\n    \n    void setEdge(int i, int j, int val) {\n        adj[i][j] = adj[j][i] = val;\n    }\n    \n    string toString() const {\n        string s;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void fromString(const string& s) {\n        int idx = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1' ? 1 : 0);\n            }\n        }\n    }\n    \n    vector<double> getInvariants() const {\n        vector<double> inv;\n        \n        // Edge count\n        int edges = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                edges += adj[i][j];\n            }\n        }\n        inv.push_back(edges);\n        \n        // Degree sequence\n        vector<int> degrees(N);\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        \n        // Add degree distribution stats\n        for(int i = 0; i < min(5, N); i++) {\n            inv.push_back(degrees[i]);\n            inv.push_back(degrees[N-1-i]);\n        }\n        \n        // Triangle count\n        int triangles = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                for(int k = j + 1; k < N; k++) {\n                    triangles += adj[i][j] * adj[j][k] * adj[k][i];\n                }\n            }\n        }\n        inv.push_back(triangles);\n        \n        // Degree correlation\n        double deg_corr = 0;\n        int edge_count = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(adj[i][j]) {\n                    deg_corr += degrees[i] * degrees[j];\n                    edge_count++;\n                }\n            }\n        }\n        if(edge_count > 0) deg_corr /= edge_count;\n        inv.push_back(deg_corr);\n        \n        return inv;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Choose N based on M and error rate\n    int N = 20;\n    if(eps <= 0.15) {\n        N = min(100, 15 + M/4);\n    } else if(eps <= 0.25) {\n        N = min(100, 20 + M/3);\n    } else {\n        N = min(100, 25 + M/2);\n    }\n    \n    vector<Graph> graphs;\n    mt19937 rng(42);\n    \n    // Generate M maximally different graphs\n    for(int idx = 0; idx < M; idx++) {\n        Graph g(N);\n        \n        // Create graphs with different edge densities\n        double target_density = (double)idx / (M - 1);\n        int target_edges = (int)(target_density * N * (N - 1) / 2);\n        \n        // Add edges with structured patterns for better distinguishability\n        set<pair<int,int>> edges;\n        \n        // Create different structural patterns based on index\n        if(idx % 4 == 0) {\n            // Path-like structure plus random edges\n            for(int i = 0; i < min(N-1, target_edges); i++) {\n                edges.insert({i, i+1});\n            }\n        } else if(idx % 4 == 1) {\n            // Star-like structure\n            for(int i = 1; i < min(N, target_edges+1); i++) {\n                edges.insert({0, i});\n            }\n        } else if(idx % 4 == 2) {\n            // Cycle plus chords\n            for(int i = 0; i < N && edges.size() < target_edges; i++) {\n                edges.insert({i, (i+1)%N});\n            }\n        }\n        \n        // Fill remaining edges randomly but deterministically\n        uniform_int_distribution<int> dist(0, N-1);\n        while(edges.size() < target_edges) {\n            int u = dist(rng);\n            int v = dist(rng);\n            if(u > v) swap(u, v);\n            if(u != v) edges.insert({u, v});\n        }\n        \n        for(auto [u, v] : edges) {\n            g.setEdge(u, v, 1);\n        }\n        \n        graphs.push_back(g);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for(const auto& g : graphs) {\n        cout << g.toString() << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute invariants\n    vector<vector<double>> invariants;\n    for(const auto& g : graphs) {\n        invariants.push_back(g.getInvariants());\n    }\n    \n    // Process queries\n    for(int q = 0; q < 100; q++) {\n        string h_str;\n        cin >> h_str;\n        \n        Graph h(N);\n        h.fromString(h_str);\n        auto h_inv = h.getInvariants();\n        \n        // Find closest match using weighted distance\n        int best = 0;\n        double best_dist = 1e18;\n        \n        for(int i = 0; i < M; i++) {\n            double dist = 0;\n            for(int j = 0; j < h_inv.size(); j++) {\n                double weight = (j == 0) ? 2.0 : 1.0;  // Weight edge count more\n                dist += weight * abs(h_inv[j] - invariants[i][j]);\n            }\n            \n            if(dist < best_dist) {\n                best_dist = dist;\n                best = i;\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<int> assignment;\n\nconst int INF = 1000000000;\n\n// Dijkstra with edge mask\nvector<int> dijkstra(int s, const vector<bool>& usable, const vector<vector<pair<int, int>>>& graph) {\n    vector<int> dist(N, INF);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            if (!usable[eid]) continue;\n            int w = edges[eid].w;\n            \n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    return dist;\n}\n\ndouble evaluateFrustration(const vector<vector<int>>& original_dist) {\n    double total = 0;\n    \n    vector<vector<int>> day_edges(D + 1);\n    for (int i = 0; i < M; i++) {\n        day_edges[assignment[i]].push_back(i);\n    }\n    \n    // Build adjacency list with edge indices\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    for (int day = 1; day <= D; day++) {\n        vector<bool> usable(M, true);\n        for (int e : day_edges[day]) {\n            usable[e] = false;\n        }\n        \n        double day_frustration = 0;\n        \n        // Sample vertices for faster evaluation\n        int samples = min(30, N);\n        for (int i = 0; i < samples; i++) {\n            int s = (i * N) / samples;\n            auto dist = dijkstra(s, usable, graph);\n            \n            for (int t = 0; t < N; t++) {\n                if (s != t) {\n                    day_frustration += (dist[t] - original_dist[s][t]) * (double)N / samples;\n                }\n            }\n        }\n        \n        total += day_frustration / (N * (N - 1));\n    }\n    \n    return total / D;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build graph for original distances\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    // Compute original distances for sampled vertices\n    vector<bool> all_usable(M, true);\n    vector<vector<int>> original_dist(N);\n    \n    int samples = min(30, N);\n    for (int i = 0; i < samples; i++) {\n        int s = (i * N) / samples;\n        original_dist[s] = dijkstra(s, all_usable, graph);\n    }\n    \n    // Initial assignment using K-means on edge midpoints\n    assignment.resize(M);\n    \n    vector<pair<double, double>> midpoints(M);\n    for (int i = 0; i < M; i++) {\n        midpoints[i] = {\n            (coords[edges[i].u].first + coords[edges[i].v].first) / 2.0,\n            (coords[edges[i].u].second + coords[edges[i].v].second) / 2.0\n        };\n    }\n    \n    // Simple K-means\n    mt19937 rng(42);\n    vector<pair<double, double>> centers(D);\n    \n    for (int i = 0; i < D; i++) {\n        centers[i] = midpoints[rng() % M];\n    }\n    \n    for (int iter = 0; iter < 10; iter++) {\n        vector<vector<int>> clusters(D);\n        \n        for (int i = 0; i < M; i++) {\n            double min_dist = 1e18;\n            int best = 0;\n            \n            for (int j = 0; j < D; j++) {\n                double dx = midpoints[i].first - centers[j].first;\n                double dy = midpoints[i].second - centers[j].second;\n                double d = dx * dx + dy * dy;\n                \n                if (d < min_dist) {\n                    min_dist = d;\n                    best = j;\n                }\n            }\n            \n            if (clusters[best].size() < K) {\n                clusters[best].push_back(i);\n                assignment[i] = best + 1;\n            } else {\n                // Find another cluster with space\n                for (int j = 0; j < D; j++) {\n                    if (clusters[j].size() < K) {\n                        clusters[j].push_back(i);\n                        assignment[i] = j + 1;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Update centers\n        for (int j = 0; j < D; j++) {\n            if (!clusters[j].empty()) {\n                double sx = 0, sy = 0;\n                for (int i : clusters[j]) {\n                    sx += midpoints[i].first;\n                    sy += midpoints[i].second;\n                }\n                centers[j] = {sx / clusters[j].size(), sy / clusters[j].size()};\n            }\n        }\n    }\n    \n    // Simulated annealing\n    double current_score = evaluateFrustration(original_dist);\n    double best_score = current_score;\n    vector<int> best_assignment = assignment;\n    \n    double T = 10.0;\n    uniform_real_distribution<double> prob(0, 1);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        if (elapsed > 5500) break;\n        \n        // Try swapping two random edges\n        int e1 = rng() % M;\n        int e2 = rng() % M;\n        if (e1 == e2 || assignment[e1] == assignment[e2]) continue;\n        \n        swap(assignment[e1], assignment[e2]);\n        \n        double new_score = evaluateFrustration(original_dist);\n        double delta = new_score - current_score;\n        \n        if (delta < 0 || prob(rng) < exp(-delta / T)) {\n            current_score = new_score;\n            if (current_score < best_score) {\n                best_score = current_score;\n                best_assignment = assignment;\n            }\n        } else {\n            swap(assignment[e1], assignment[e2]);\n        }\n        \n        T *= 0.9995;\n    }\n    \n    assignment = best_assignment;\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nvoid read_input() {\n    cin >> D;\n    f1.resize(D); r1.resize(D);\n    f2.resize(D); r2.resize(D);\n    \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\nvector<vector<vector<int>>> construct_object(vector<string>& f, vector<string>& r) {\n    vector<vector<vector<int>>> obj(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    // Place cube at (x,y,z) if both f[z][x] and r[z][y] are 1\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(f[z][x] == '1' && r[z][y] == '1') {\n                    obj[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    return obj;\n}\n\nvoid create_and_output() {\n    auto obj1 = construct_object(f1, r1);\n    auto obj2 = construct_object(f2, r2);\n    \n    vector<int> b1(D * D * D, 0);\n    vector<int> b2(D * D * D, 0);\n    \n    map<tuple<int,int,int>, int> cell_to_block;\n    int block_id = 0;\n    \n    // Strategy: Create unit blocks for common positions first, then fill the rest\n    // This ensures shape consistency when blocks are reused\n    \n    // First pass: assign blocks for cells that exist in both objects at the same position\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && obj2[x][y][z] == 1) {\n                    block_id++;\n                    int idx = x * D * D + y * D + z;\n                    b1[idx] = block_id;\n                    b2[idx] = block_id;\n                    cell_to_block[{x,y,z}] = block_id;\n                }\n            }\n        }\n    }\n    \n    // Second pass: assign unique blocks for remaining cells in obj1\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && cell_to_block.find({x,y,z}) == cell_to_block.end()) {\n                    block_id++;\n                    int idx = x * D * D + y * D + z;\n                    b1[idx] = block_id;\n                }\n            }\n        }\n    }\n    \n    // Third pass: assign unique blocks for remaining cells in obj2\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj2[x][y][z] == 1 && cell_to_block.find({x,y,z}) == cell_to_block.end()) {\n                    block_id++;\n                    int idx = x * D * D + y * D + z;\n                    b2[idx] = block_id;\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << block_id << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b1[i];\n    }\n    cout << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b2[i];\n    }\n    cout << endl;\n}\n\nint main() {\n    read_input();\n    create_and_output();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\n// Dijkstra for shortest paths\nvector<pair<long long, vector<int>>> dijkstra_with_path(int source, const vector<vector<pair<int, pair<int, long long>>>>& adj, int target = -1) {\n    int n = adj.size();\n    vector<long long> dist(n, LLONG_MAX);\n    vector<int> parent(n, -1);\n    vector<int> parent_edge(n, -1);\n    priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n    \n    dist[source] = 0;\n    pq.push({0, source});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        if (target != -1 && u == target) break;\n        \n        for (auto [v, info] : adj[u]) {\n            long long w = info.second;\n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                parent[v] = u;\n                parent_edge[v] = info.first;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    vector<pair<long long, vector<int>>> result(n);\n    for (int i = 0; i < n; i++) {\n        result[i].first = dist[i];\n        if (parent[i] != -1) {\n            int curr = i;\n            while (parent[curr] != -1) {\n                result[i].second.push_back(parent_edge[curr]);\n                curr = parent[curr];\n            }\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<pair<int, int>> vertices(N);\n    for (int i = 0; i < N; i++) {\n        cin >> vertices[i].first >> vertices[i].second;\n    }\n    \n    vector<Edge> edges(M);\n    vector<vector<pair<int, pair<int, long long>>>> adj(N);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--; edges[i].v--;\n        edges[i].id = i;\n        adj[edges[i].u].push_back({edges[i].v, {i, edges[i].w}});\n        adj[edges[i].v].push_back({edges[i].u, {i, edges[i].w}});\n    }\n    \n    vector<pair<int, int>> residents(K);\n    for (int i = 0; i < K; i++) {\n        cin >> residents[i].first >> residents[i].second;\n    }\n    \n    // Calculate distance from each resident to each vertex\n    vector<vector<int>> resident_dist(K, vector<int>(N));\n    vector<vector<int>> vertices_for_resident(K);\n    \n    for (int r = 0; r < K; r++) {\n        for (int v = 0; v < N; v++) {\n            long long dx = residents[r].first - vertices[v].first;\n            long long dy = residents[r].second - vertices[v].second;\n            resident_dist[r][v] = (int)ceil(sqrt(dx * dx + dy * dy));\n            if (resident_dist[r][v] <= 5000) {\n                vertices_for_resident[r].push_back(v);\n            }\n        }\n    }\n    \n    // Get shortest paths from vertex 0\n    auto paths_from_0 = dijkstra_with_path(0, adj);\n    \n    // Greedy set cover with connection cost consideration\n    vector<bool> covered(K, false);\n    vector<int> vertex_power(N, 0);\n    set<int> active_vertices;\n    active_vertices.insert(0);\n    \n    while (count(covered.begin(), covered.end(), false) > 0) {\n        double best_efficiency = 1e18;\n        int best_vertex = -1;\n        vector<int> best_new_covered;\n        int best_power = 0;\n        \n        for (int v = 0; v < N; v++) {\n            if (paths_from_0[v].first == LLONG_MAX) continue;\n            \n            vector<int> new_covered;\n            int required_power = vertex_power[v];\n            \n            for (int r = 0; r < K; r++) {\n                if (!covered[r] && resident_dist[r][v] <= 5000) {\n                    new_covered.push_back(r);\n                    required_power = max(required_power, resident_dist[r][v]);\n                }\n            }\n            \n            if (!new_covered.empty() && required_power <= 5000) {\n                long long power_cost = (long long)required_power * required_power - \n                                      (long long)vertex_power[v] * vertex_power[v];\n                long long edge_cost = (active_vertices.count(v) ? 0 : paths_from_0[v].first);\n                double efficiency = (power_cost + edge_cost) / (double)new_covered.size();\n                \n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_vertex = v;\n                    best_new_covered = new_covered;\n                    best_power = required_power;\n                }\n            }\n        }\n        \n        if (best_vertex == -1) break;\n        \n        active_vertices.insert(best_vertex);\n        vertex_power[best_vertex] = best_power;\n        for (int r : best_new_covered) {\n            covered[r] = true;\n        }\n    }\n    \n    // Build minimal tree connecting active vertices\n    vector<int> edge_used(M, 0);\n    set<int> connected;\n    connected.insert(0);\n    \n    for (int v : active_vertices) {\n        if (v != 0 && connected.find(v) == connected.end()) {\n            for (int e : paths_from_0[v].second) {\n                edge_used[e] = 1;\n                int u = edges[e].u;\n                int w = edges[e].v;\n                connected.insert(u);\n                connected.insert(w);\n            }\n        }\n    }\n    \n    // Optimize: reduce unnecessary power\n    for (int v : active_vertices) {\n        if (vertex_power[v] > 0) {\n            int min_needed = 0;\n            for (int r = 0; r < K; r++) {\n                if (resident_dist[r][v] <= vertex_power[v]) {\n                    bool covered_elsewhere = false;\n                    for (int u : active_vertices) {\n                        if (u != v && resident_dist[r][u] <= vertex_power[u]) {\n                            covered_elsewhere = true;\n                            break;\n                        }\n                    }\n                    if (!covered_elsewhere) {\n                        min_needed = max(min_needed, resident_dist[r][v]);\n                    }\n                }\n            }\n            vertex_power[v] = min_needed;\n        }\n    }\n    \n    // Clear power for non-connected vertices\n    for (int v = 0; v < N; v++) {\n        if (connected.find(v) == connected.end()) {\n            vertex_power[v] = 0;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << vertex_power[i] << (i == N-1 ? \"\\n\" : \" \");\n    }\n    for (int i = 0; i < M; i++) {\n        cout << edge_used[i] << (i == M-1 ? \"\\n\" : \" \");\n    }\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nvector<vector<int>> pyramid(N);\nvector<tuple<int,int,int,int>> moves;\n\nvoid swapBalls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    moves.push_back({x1, y1, x2, y2});\n}\n\n// Count violations for a specific position\nint positionViolations(int x, int y) {\n    int violations = 0;\n    if (x < N - 1) {\n        if (pyramid[x][y] > pyramid[x + 1][y]) violations++;\n        if (pyramid[x][y] > pyramid[x + 1][y + 1]) violations++;\n    }\n    return violations;\n}\n\n// Count total violations\nint countViolations() {\n    int violations = 0;\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            violations += positionViolations(x, y);\n        }\n    }\n    return violations;\n}\n\n// Heapify from a position downward\nvoid heapifyDown(int x, int y) {\n    if (x >= N - 1) return;\n    \n    int leftChild = pyramid[x + 1][y];\n    int rightChild = pyramid[x + 1][y + 1];\n    \n    // Find minimum among parent and children\n    if (pyramid[x][y] > leftChild && leftChild <= rightChild) {\n        swapBalls(x, y, x + 1, y);\n        heapifyDown(x + 1, y);\n    } else if (pyramid[x][y] > rightChild) {\n        swapBalls(x, y, x + 1, y + 1);\n        heapifyDown(x + 1, y + 1);\n    }\n}\n\n// Try to bubble up small values\nvoid bubbleUp(int x, int y) {\n    if (x == 0) return;\n    \n    // Check possible parent positions\n    vector<pair<int,int>> parents;\n    if (y > 0) parents.push_back({x - 1, y - 1});\n    if (y < x) parents.push_back({x - 1, y});\n    \n    for (auto [px, py] : parents) {\n        if (px >= 0 && py >= 0 && py <= px) {\n            if (pyramid[x][y] < pyramid[px][py]) {\n                // Check if swap would not create new violations\n                int currentViolations = positionViolations(px, py);\n                swapBalls(x, y, px, py);\n                int newViolations = positionViolations(px, py);\n                \n                if (newViolations <= currentViolations) {\n                    bubbleUp(px, py);\n                    return;\n                } else {\n                    // Revert if it made things worse\n                    swapBalls(x, y, px, py);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x + 1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Phase 1: Initial heapify from bottom-up\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            heapifyDown(x, y);\n        }\n    }\n    \n    // Phase 2: Find small values in lower levels and bubble them up\n    vector<tuple<int, int, int>> valuePositions;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            valuePositions.push_back({pyramid[x][y], x, y});\n        }\n    }\n    sort(valuePositions.begin(), valuePositions.end());\n    \n    // Try to move smallest values upward\n    for (int i = 0; i < min(100, (int)valuePositions.size()); i++) {\n        auto [val, x, y] = valuePositions[i];\n        // Find current position of this value\n        bool found = false;\n        for (int cx = 0; cx < N && !found; cx++) {\n            for (int cy = 0; cy <= cx && !found; cy++) {\n                if (pyramid[cx][cy] == val) {\n                    bubbleUp(cx, cy);\n                    found = true;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Final cleanup - fix remaining violations\n    int maxCleanupIter = 1000;\n    for (int iter = 0; iter < maxCleanupIter && moves.size() < 9500; iter++) {\n        if (countViolations() == 0) break;\n        \n        bool improved = false;\n        for (int x = 0; x < N - 1; x++) {\n            for (int y = 0; y <= x; y++) {\n                if (pyramid[x][y] > pyramid[x + 1][y]) {\n                    swapBalls(x, y, x + 1, y);\n                    heapifyDown(x + 1, y);\n                    improved = true;\n                }\n                if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                    swapBalls(x, y, x + 1, y + 1);\n                    heapifyDown(x + 1, y + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Output\n    cout << moves.size() << endl;\n    for (auto [x1, y1, x2, y2] : moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {-1, 0, 1, 0};\nconst int dy[] = {0, 1, 0, -1};\n\nstruct Container {\n    int number;\n    int x, y;\n};\n\nclass Warehouse {\n    int D, N;\n    int entrance_x, entrance_y;\n    vector<vector<int>> grid; // -1: obstacle, -2: empty, >=0: container number\n    vector<Container> containers;\n    vector<pair<int,int>> obstacles;\n    \npublic:\n    Warehouse() {\n        cin >> D >> N;\n        entrance_x = 0;\n        entrance_y = (D - 1) / 2;\n        \n        grid.resize(D, vector<int>(D, -2));\n        \n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n            grid[x][y] = -1;\n            obstacles.push_back({x, y});\n        }\n    }\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < D && y >= 0 && y < D;\n    }\n    \n    bool isReachable(int tx, int ty) {\n        if (!isValid(tx, ty) || grid[tx][ty] == -1) return false;\n        if (tx == entrance_x && ty == entrance_y) return true;\n        \n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        q.push({entrance_x, entrance_y});\n        visited[entrance_x][entrance_y] = true;\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                if (!isValid(nx, ny) || visited[nx][ny]) continue;\n                if (grid[nx][ny] != -2 && !(nx == tx && ny == ty)) continue;\n                \n                if (nx == tx && ny == ty) return true;\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return false;\n    }\n    \n    int getDistance(int x, int y) {\n        if (!isReachable(x, y)) return INT_MAX;\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n        q.push({entrance_x, entrance_y});\n        dist[entrance_x][entrance_y] = 0;\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front();\n            q.pop();\n            \n            if (cx == x && cy == y) return dist[x][y];\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = cx + dx[dir];\n                int ny = cy + dy[dir];\n                \n                if (!isValid(nx, ny) || grid[nx][ny] != -2) continue;\n                if (dist[nx][ny] != INT_MAX) continue;\n                \n                dist[nx][ny] = dist[cx][cy] + 1;\n                q.push({nx, ny});\n            }\n        }\n        \n        return INT_MAX;\n    }\n    \n    pair<int,int> placeContainer(int container_num) {\n        // Find all reachable empty positions\n        vector<pair<int, pair<int,int>>> candidates;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == entrance_x && j == entrance_y) continue;\n                if (grid[i][j] != -2) continue;\n                \n                int dist = getDistance(i, j);\n                if (dist != INT_MAX) {\n                    candidates.push_back({dist, {i, j}});\n                }\n            }\n        }\n        \n        if (candidates.empty()) {\n            // Should not happen in valid test cases\n            return {0, 0};\n        }\n        \n        // Sort by distance\n        sort(candidates.begin(), candidates.end());\n        \n        // Place based on container number relative to total containers\n        int total_containers = D * D - 1 - N;\n        int idx = (container_num * candidates.size()) / total_containers;\n        idx = min(idx, (int)candidates.size() - 1);\n        \n        // Try to place at the calculated index, but also consider nearby positions\n        // to avoid blocking\n        int best_idx = idx;\n        int range = min(5, (int)candidates.size());\n        \n        for (int offset = 0; offset < range; offset++) {\n            for (int sign : {1, -1}) {\n                int test_idx = idx + sign * offset;\n                if (test_idx >= 0 && test_idx < candidates.size()) {\n                    auto [x, y] = candidates[test_idx].second;\n                    \n                    // Check if this placement would block fewer cells\n                    int blocked_count = 0;\n                    grid[x][y] = container_num; // Temporarily place\n                    \n                    for (int i = 0; i < D; i++) {\n                        for (int j = 0; j < D; j++) {\n                            if (grid[i][j] == -2 && !isReachable(i, j)) {\n                                blocked_count++;\n                            }\n                        }\n                    }\n                    \n                    grid[x][y] = -2; // Remove temporary placement\n                    \n                    if (blocked_count <= 2) { // Acceptable blocking\n                        best_idx = test_idx;\n                        goto found;\n                    }\n                }\n            }\n        }\n        \n        found:\n        auto [px, py] = candidates[best_idx].second;\n        grid[px][py] = container_num;\n        containers.push_back({container_num, px, py});\n        \n        return {px, py};\n    }\n    \n    vector<pair<int,int>> getRetrievalOrder() {\n        vector<pair<int,int>> result;\n        vector<bool> retrieved(containers.size(), false);\n        \n        while (result.size() < containers.size()) {\n            int best_idx = -1;\n            int best_number = INT_MAX;\n            \n            // Find the smallest numbered container that's accessible\n            for (int i = 0; i < containers.size(); i++) {\n                if (retrieved[i]) continue;\n                \n                if (isReachable(containers[i].x, containers[i].y)) {\n                    if (containers[i].number < best_number) {\n                        best_number = containers[i].number;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx == -1) {\n                // Should not happen, but fallback to any accessible container\n                for (int i = 0; i < containers.size(); i++) {\n                    if (retrieved[i]) continue;\n                    if (isReachable(containers[i].x, containers[i].y)) {\n                        best_idx = i;\n                        break;\n                    }\n                }\n            }\n            \n            retrieved[best_idx] = true;\n            grid[containers[best_idx].x][containers[best_idx].y] = -2;\n            result.push_back({containers[best_idx].x, containers[best_idx].y});\n        }\n        \n        return result;\n    }\n    \n    void run() {\n        int total_containers = D * D - 1 - N;\n        \n        // Place containers as they arrive\n        for (int i = 0; i < total_containers; i++) {\n            int container_num;\n            cin >> container_num;\n            \n            auto [x, y] = placeContainer(container_num);\n            cout << x << \" \" << y << endl;\n            cout.flush();\n        }\n        \n        // Determine retrieval order\n        auto retrieval_order = getRetrievalOrder();\n        for (auto [x, y] : retrieval_order) {\n            cout << x << \" \" << y << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Warehouse warehouse;\n    warehouse.run();\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\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    // Extract adjacency information\n    set<pair<int, int>> adjacencies;\n    \n    // Check internal adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            // Check right neighbor\n            if (j + 1 < n && grid[i][j] != grid[i][j+1]) {\n                int c1 = min(grid[i][j], grid[i][j+1]);\n                int c2 = max(grid[i][j], grid[i][j+1]);\n                adjacencies.insert({c1, c2});\n            }\n            \n            // Check bottom neighbor\n            if (i + 1 < n && grid[i][j] != grid[i+1][j]) {\n                int c1 = min(grid[i][j], grid[i+1][j]);\n                int c2 = max(grid[i][j], grid[i+1][j]);\n                adjacencies.insert({c1, c2});\n            }\n        }\n    }\n    \n    // Check boundary adjacencies (with color 0)\n    set<int> boundaryWards;\n    for (int i = 0; i < n; i++) {\n        boundaryWards.insert(grid[0][i]);\n        boundaryWards.insert(grid[n-1][i]);\n        boundaryWards.insert(grid[i][0]);\n        boundaryWards.insert(grid[i][n-1]);\n    }\n    \n    for (int ward : boundaryWards) {\n        adjacencies.insert({0, ward});\n    }\n    \n    // Build adjacency list\n    vector<vector<int>> adj(m + 1);\n    for (auto [c1, c2] : adjacencies) {\n        adj[c1].push_back(c2);\n        adj[c2].push_back(c1);\n    }\n    \n    // Create a compact grid representation\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    vector<bool> placed(m + 1, false);\n    placed[0] = true; // Color 0 is implicitly placed\n    \n    // Direction vectors\n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    // Start with boundary wards\n    queue<int> toPlace;\n    for (int ward : boundaryWards) {\n        toPlace.push(ward);\n        placed[ward] = true;\n    }\n    \n    // Place boundary wards near edges\n    int idx = 0;\n    for (int ward : boundaryWards) {\n        if (idx < n/4) {\n            result[1][2 + idx * 2] = ward;\n        } else if (idx < n/2) {\n            result[2 + (idx - n/4) * 2][n-2] = ward;\n        } else if (idx < 3*n/4) {\n            result[n-2][n-3 - (idx - n/2) * 2] = ward;\n        } else {\n            result[n-3 - (idx - 3*n/4) * 2][1] = ward;\n        }\n        idx++;\n        if (idx * 2 >= n) break;\n    }\n    \n    // BFS to place remaining wards based on adjacencies\n    while (!toPlace.empty()) {\n        int ward = toPlace.front();\n        toPlace.pop();\n        \n        for (int neighbor : adj[ward]) {\n            if (!placed[neighbor] && neighbor != 0) {\n                // Find a position adjacent to ward's position\n                bool found = false;\n                for (int i = 0; i < n && !found; i++) {\n                    for (int j = 0; j < n && !found; j++) {\n                        if (result[i][j] == ward) {\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 && result[ni][nj] == 0) {\n                                    result[ni][nj] = neighbor;\n                                    placed[neighbor] = true;\n                                    toPlace.push(neighbor);\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place any remaining wards\n    for (int ward = 1; ward <= m; ward++) {\n        if (!placed[ward]) {\n            // Find empty position, preferably near its neighbors\n            bool found = false;\n            for (int i = 1; i < n-1 && !found; i++) {\n                for (int j = 1; j < n-1 && !found; j++) {\n                    if (result[i][j] == 0) {\n                        result[i][j] = ward;\n                        placed[ward] = true;\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Ensure all required adjacencies exist by expanding regions if needed\n    for (auto [c1, c2] : adjacencies) {\n        if (c1 == 0) continue; // Boundary adjacencies handled by placement\n        \n        // Check if adjacency exists\n        bool adjacent = false;\n        for (int i = 0; i < n && !adjacent; i++) {\n            for (int j = 0; j < n && !adjacent; j++) {\n                if (result[i][j] == c1) {\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 && result[ni][nj] == c2) {\n                            adjacent = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If not adjacent, try to make them adjacent\n        if (!adjacent) {\n            // Find positions of c1 and c2 and try to grow one toward the other\n            vector<pair<int,int>> pos1, pos2;\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (result[i][j] == c1) pos1.push_back({i, j});\n                    if (result[i][j] == c2) pos2.push_back({i, j});\n                }\n            }\n            \n            if (!pos1.empty() && !pos2.empty()) {\n                // Try to extend c1 toward c2\n                int minDist = n * n;\n                int bestX = -1, bestY = -1;\n                for (auto [x1, y1] : pos1) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x1 + dx[d];\n                        int ny = y1 + dy[d];\n                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                            for (auto [x2, y2] : pos2) {\n                                int dist = abs(nx - x2) + abs(ny - y2);\n                                if (dist < minDist) {\n                                    minDist = dist;\n                                    bestX = nx;\n                                    bestY = ny;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (bestX != -1) {\n                    result[bestX][bestY] = c1;\n                }\n            }\n        }\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<double> weight_estimate;\nvector<double> weight_lower, weight_upper;\nvector<vector<int>> comparison_matrix; // -1: i<j, 0: unknown, 1: i>j\n\nchar query(vector<int> left, vector<int> right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid update_bounds_from_comparison(const vector<int>& left, const vector<int>& right, char result) {\n    double left_min = 0, left_max = 0;\n    double right_min = 0, right_max = 0;\n    \n    for (int i : left) {\n        left_min += weight_lower[i];\n        left_max += weight_upper[i];\n    }\n    for (int i : right) {\n        right_min += weight_lower[i];\n        right_max += weight_upper[i];\n    }\n    \n    if (result == '<') {\n        // left_max < right_min ideally\n        if (left_max >= right_min) {\n            double ratio = right_min / left_max;\n            for (int i : left) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : right) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else if (result == '>') {\n        // right_max < left_min ideally\n        if (right_max >= left_min) {\n            double ratio = left_min / right_max;\n            for (int i : right) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : left) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else { // '='\n        // Weights should be equal\n        double avg = (left_min + left_max + right_min + right_max) / 4;\n        double per_item_left = avg / left.size();\n        double per_item_right = avg / right.size();\n        \n        for (int i : left) {\n            weight_estimate[i] = per_item_left;\n            weight_lower[i] = per_item_left * 0.8;\n            weight_upper[i] = per_item_left * 1.2;\n        }\n        for (int i : right) {\n            weight_estimate[i] = per_item_right;\n            weight_lower[i] = per_item_right * 0.8;\n            weight_upper[i] = per_item_right * 1.2;\n        }\n    }\n}\n\ndouble calculate_variance(const vector<vector<int>>& groups) {\n    vector<double> group_sums(D, 0);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            group_sums[g] += weight_estimate[item];\n        }\n    }\n    \n    double mean = 0;\n    for (double s : group_sums) mean += s;\n    mean /= D;\n    \n    double variance = 0;\n    for (double s : group_sums) {\n        variance += (s - mean) * (s - mean);\n    }\n    return variance / D;\n}\n\nvoid local_search(vector<int>& assignment) {\n    vector<double> group_sums(D, 0);\n    vector<vector<int>> groups(D);\n    \n    for (int i = 0; i < N; i++) {\n        groups[assignment[i]].push_back(i);\n        group_sums[assignment[i]] += weight_estimate[i];\n    }\n    \n    bool improved = true;\n    int iterations = 0;\n    while (improved && iterations < 100) {\n        improved = false;\n        iterations++;\n        \n        for (int g1 = 0; g1 < D; g1++) {\n            for (int g2 = g1 + 1; g2 < D; g2++) {\n                // Try swapping items between groups\n                for (int i : groups[g1]) {\n                    for (int j : groups[g2]) {\n                        double curr_diff = abs(group_sums[g1] - group_sums[g2]);\n                        double new_sum_g1 = group_sums[g1] - weight_estimate[i] + weight_estimate[j];\n                        double new_sum_g2 = group_sums[g2] - weight_estimate[j] + weight_estimate[i];\n                        double new_diff = abs(new_sum_g1 - new_sum_g2);\n                        \n                        if (new_diff < curr_diff) {\n                            // Perform swap\n                            assignment[i] = g2;\n                            assignment[j] = g1;\n                            group_sums[g1] = new_sum_g1;\n                            group_sums[g2] = new_sum_g2;\n                            \n                            // Update groups\n                            groups[g1].erase(find(groups[g1].begin(), groups[g1].end(), i));\n                            groups[g1].push_back(j);\n                            groups[g2].erase(find(groups[g2].begin(), groups[g2].end(), j));\n                            groups[g2].push_back(i);\n                            \n                            improved = true;\n                            break;\n                        }\n                    }\n                    if (improved) break;\n                }\n                if (improved) break;\n            }\n            if (improved) break;\n        }\n    }\n}\n\nvoid solve() {\n    cin >> N >> D >> Q;\n    \n    weight_estimate.resize(N, 1000.0);\n    weight_lower.resize(N, 100.0);\n    weight_upper.resize(N, 10000.0);\n    comparison_matrix.resize(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Phase 1: Strategic individual comparisons\n    vector<pair<double, pair<int, int>>> uncertain_pairs;\n    \n    // First, do some initial random sampling to get rough estimates\n    for (int round = 0; round < 3 && queries_used < Q / 3; round++) {\n        for (int i = 0; i < N && queries_used < Q / 3; i++) {\n            int j = (i + 1 + round * 7) % N;\n            if (i != j && comparison_matrix[i][j] == 0) {\n                char result = query({i}, {j});\n                queries_used++;\n                \n                if (result == '<') {\n                    comparison_matrix[i][j] = -1;\n                    comparison_matrix[j][i] = 1;\n                    weight_estimate[i] *= 0.85;\n                    weight_estimate[j] *= 1.15;\n                } else if (result == '>') {\n                    comparison_matrix[i][j] = 1;\n                    comparison_matrix[j][i] = -1;\n                    weight_estimate[i] *= 1.15;\n                    weight_estimate[j] *= 0.85;\n                } else {\n                    weight_estimate[i] = weight_estimate[j] = (weight_estimate[i] + weight_estimate[j]) / 2;\n                }\n                \n                update_bounds_from_comparison({i}, {j}, result);\n            }\n        }\n    }\n    \n    // Phase 2: Group comparisons for refinement\n    while (queries_used < Q * 2 / 3) {\n        vector<pair<double, int>> sorted_items;\n        for (int i = 0; i < N; i++) {\n            sorted_items.push_back({weight_estimate[i], i});\n        }\n        sort(sorted_items.begin(), sorted_items.end());\n        \n        // Compare different percentiles\n        int size = max(2, N / 10);\n        vector<int> light, heavy, mid_low, mid_high;\n        \n        for (int i = 0; i < size && i < N/2; i++) {\n            light.push_back(sorted_items[i].second);\n            heavy.push_back(sorted_items[N - 1 - i].second);\n        }\n        \n        int mid = N / 2;\n        for (int i = max(0, mid - size/2); i < mid && i < N; i++) {\n            mid_low.push_back(sorted_items[i].second);\n        }\n        for (int i = mid; i < min(N, mid + size/2); i++) {\n            mid_high.push_back(sorted_items[i].second);\n        }\n        \n        if (!light.empty() && !heavy.empty()) {\n            char result = query(light, heavy);\n            queries_used++;\n            update_bounds_from_comparison(light, heavy, result);\n        }\n        \n        if (queries_used < Q * 2 / 3 && !mid_low.empty() && !mid_high.empty()) {\n            char result = query(mid_low, mid_high);\n            queries_used++;\n            update_bounds_from_comparison(mid_low, mid_high, result);\n        }\n    }\n    \n    // Initial partitioning\n    vector<pair<double, int>> final_sorted;\n    for (int i = 0; i < N; i++) {\n        final_sorted.push_back({weight_estimate[i], i});\n    }\n    sort(final_sorted.begin(), final_sorted.end(), greater<pair<double, int>>());\n    \n    vector<double> group_sums(D, 0);\n    vector<int> assignment(N);\n    \n    // Greedy assignment\n    for (auto [weight, item] : final_sorted) {\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < group_sums[min_group]) {\n                min_group = g;\n            }\n        }\n        assignment[item] = min_group;\n        group_sums[min_group] += weight;\n    }\n    \n    // Local search optimization\n    local_search(assignment);\n    \n    // Phase 3: Use remaining queries to verify and refine partition\n    vector<vector<int>> final_groups(D);\n    for (int i = 0; i < N; i++) {\n        final_groups[assignment[i]].push_back(i);\n    }\n    \n    while (queries_used < Q && D > 1) {\n        // Compare pairs of groups to verify balance\n        for (int g1 = 0; g1 < D && queries_used < Q; g1++) {\n            for (int g2 = g1 + 1; g2 < D && queries_used < Q; g2++) {\n                if (!final_groups[g1].empty() && !final_groups[g2].empty()) {\n                    // Sample from each group\n                    int sample_size = min(5, min((int)final_groups[g1].size(), (int)final_groups[g2].size()));\n                    vector<int> sample1, sample2;\n                    \n                    for (int i = 0; i < sample_size; i++) {\n                        sample1.push_back(final_groups[g1][i % final_groups[g1].size()]);\n                        sample2.push_back(final_groups[g2][i % final_groups[g2].size()]);\n                    }\n                    \n                    char result = query(sample1, sample2);\n                    queries_used++;\n                    update_bounds_from_comparison(sample1, sample2, result);\n                }\n            }\n        }\n    }\n    \n    // Final local search with updated estimates\n    if (queries_used >= Q * 0.9) {\n        local_search(assignment);\n    }\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}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    // Read initial configuration\n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        int stack_size = n / m;\n        for (int j = 0; j < stack_size; j++) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    // Process boxes in ascending order\n    for (int target = 1; target <= n; target++) {\n        // Find current position of target box\n        int target_stack = -1;\n        int target_pos = -1;\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    target_stack = i;\n                    target_pos = j;\n                    break;\n                }\n            }\n            if (target_stack != -1) break;\n        }\n        \n        // If target is not at the top, move boxes above it\n        if (target_pos < (int)stacks[target_stack].size() - 1) {\n            // Find best destination stack (prefer empty or smaller stacks)\n            int best_dest = -1;\n            int min_size = INT_MAX;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == target_stack) continue;\n                if ((int)stacks[i].size() < min_size) {\n                    min_size = stacks[i].size();\n                    best_dest = i;\n                }\n            }\n            \n            // Move the box directly above target and all boxes above it\n            int box_to_move = stacks[target_stack][target_pos + 1];\n            \n            // Record the move operation\n            operations.push_back({box_to_move, best_dest + 1}); // +1 for 1-indexed\n            \n            // Update stacks - move boxes from target_pos+1 to end\n            vector<int> moved_boxes;\n            for (int j = target_pos + 1; j < (int)stacks[target_stack].size(); j++) {\n                moved_boxes.push_back(stacks[target_stack][j]);\n            }\n            \n            stacks[target_stack].resize(target_pos + 1);\n            \n            for (int box : moved_boxes) {\n                stacks[best_dest].push_back(box);\n            }\n        }\n        \n        // Now target is at the top, carry it out\n        operations.push_back({target, 0});\n        stacks[target_stack].pop_back();\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nconst int MAX_LENGTH = 100000;\nconst int DIJ[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\nconst char DIR[4] = {'R', 'D', 'L', 'U'};\n\nbool canMove(int i, int j, int dir) {\n    int di = DIJ[dir][0], dj = DIJ[dir][1];\n    int i2 = i + di, j2 = j + dj;\n    \n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    \n    if (di == 0) {\n        return v[i][min(j, j2)] == '0';\n    } else {\n        return h[min(i, i2)][j] == '0';\n    }\n}\n\n// BFS to find shortest path\nvector<int> findPath(int si, int sj, int ei, int ej) {\n    queue<tuple<int, int, vector<int>>> q;\n    set<pair<int, int>> vis;\n    q.push({si, sj, {}});\n    vis.insert({si, sj});\n    \n    while (!q.empty()) {\n        auto [ci, cj, path] = q.front();\n        q.pop();\n        \n        if (ci == ei && cj == ej) {\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            if (vis.count({ni, nj})) continue;\n            vis.insert({ni, nj});\n            auto newPath = path;\n            newPath.push_back(dir);\n            q.push({ni, nj, newPath});\n        }\n    }\n    return {};\n}\n\nint main() {\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    d.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N - 1; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\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    // Create base route visiting all squares using DFS\n    vector<int> route;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            int di = DIJ[dir][0], dj = DIJ[dir][1];\n            int i2 = i + di, j2 = j + dj;\n            \n            if (i2 >= 0 && i2 < N && j2 >= 0 && j2 < N && !visited[i2][j2] && canMove(i, j, dir)) {\n                route.push_back(dir);\n                dfs(i2, j2);\n                route.push_back((dir + 2) % 4);\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Use remaining moves to revisit high-dirt squares\n    if (route.size() < MAX_LENGTH) {\n        // Create priority queue of squares by dirt value\n        priority_queue<tuple<int, int, int>> pq;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != 0 || j != 0) { // Don't add origin\n                    pq.push({d[i][j], i, j});\n                }\n            }\n        }\n        \n        int curI = 0, curJ = 0;\n        \n        // Add extra visits to high-dirt squares\n        while (!pq.empty() && route.size() < MAX_LENGTH - 1000) {\n            auto [dirt, ti, tj] = pq.top();\n            pq.pop();\n            \n            // Find path to target square and back\n            auto pathTo = findPath(curI, curJ, ti, tj);\n            auto pathBack = findPath(ti, tj, 0, 0);\n            \n            if (!pathTo.empty() && !pathBack.empty() && \n                route.size() + pathTo.size() + pathBack.size() <= MAX_LENGTH) {\n                for (int dir : pathTo) route.push_back(dir);\n                for (int dir : pathBack) route.push_back(dir);\n                curI = 0;\n                curJ = 0;\n                \n                // Re-add high-dirt squares for multiple visits\n                if (dirt > 100 && route.size() < MAX_LENGTH - 5000) {\n                    pq.push({dirt / 2, ti, tj});\n                }\n            }\n        }\n    }\n    \n    // Convert route to string\n    string result;\n    for (int dir : route) {\n        result += DIR[dir];\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int i, j;\n};\n\nint manhattan(Position a, Position b) {\n    return abs(a.i - b.i) + abs(a.j - b.j) + 1;\n}\n\n// Calculate overlap between suffix of a and prefix of b\nint getOverlap(const string& a, const string& b) {\n    int maxOverlap = min((int)a.length(), (int)b.length());\n    for (int i = maxOverlap; i > 0; i--) {\n        if (a.size() >= i && b.size() >= i && a.substr(a.length() - i) == b.substr(0, i)) {\n            return i;\n        }\n    }\n    return 0;\n}\n\n// Check if string contains word as substring\nbool containsWord(const string& s, const string& word) {\n    return s.find(word) != string::npos;\n}\n\n// Calculate cost of typing a string from given position\nint calculateTypingCost(const string& s, Position startPos, const vector<vector<Position>>& charPositions) {\n    Position currentPos = startPos;\n    int totalCost = 0;\n    \n    for (char c : s) {\n        int charIdx = c - 'A';\n        if (charPositions[charIdx].empty()) return INT_MAX;\n        \n        Position bestPos = charPositions[charIdx][0];\n        int bestCost = manhattan(currentPos, bestPos);\n        \n        for (const Position& pos : charPositions[charIdx]) {\n            int cost = manhattan(currentPos, pos);\n            if (cost < bestCost) {\n                bestCost = cost;\n                bestPos = pos;\n            }\n        }\n        \n        totalCost += bestCost;\n        currentPos = bestPos;\n    }\n    \n    return totalCost;\n}\n\n// Build superstring using improved greedy with keyboard awareness\nstring buildSuperstring(vector<string>& words, Position startPos, const vector<vector<Position>>& charPositions) {\n    int n = words.size();\n    \n    // Remove words that are substrings of other words\n    vector<string> filteredWords;\n    for (int i = 0; i < n; i++) {\n        bool isSubstring = false;\n        for (int j = 0; j < n; j++) {\n            if (i != j && words[j].find(words[i]) != string::npos) {\n                isSubstring = true;\n                break;\n            }\n        }\n        if (!isSubstring) {\n            filteredWords.push_back(words[i]);\n        }\n    }\n    \n    n = filteredWords.size();\n    \n    // Precompute overlaps\n    vector<vector<int>> overlaps(n, vector<int>(n, 0));\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (i != j) {\n                overlaps[i][j] = getOverlap(filteredWords[i], filteredWords[j]);\n            }\n        }\n    }\n    \n    string bestResult = \"\";\n    int bestCost = INT_MAX;\n    \n    // Try multiple starting strategies\n    for (int strategy = 0; strategy < 5; strategy++) {\n        vector<bool> used(n, false);\n        vector<int> order;\n        \n        // Choose starting word based on strategy\n        int startIdx = -1;\n        if (strategy == 0) {\n            // Start with word closest to current position\n            for (int i = 0; i < n; i++) {\n                int cost = calculateTypingCost(filteredWords[i], startPos, charPositions);\n                if (startIdx == -1 || cost < bestCost) {\n                    bestCost = cost;\n                    startIdx = i;\n                }\n            }\n        } else {\n            // Random starting points for diversity\n            startIdx = rand() % n;\n        }\n        \n        order.push_back(startIdx);\n        used[startIdx] = true;\n        \n        // Build chain greedily with weighted score\n        for (int count = 1; count < n; count++) {\n            int lastIdx = order.back();\n            int bestNext = -1;\n            double bestScore = -1e9;\n            \n            for (int i = 0; i < n; i++) {\n                if (!used[i]) {\n                    // Score based on overlap and estimated keyboard cost\n                    double score = overlaps[lastIdx][i] * 10.0;\n                    \n                    // Penalize if the new word requires expensive keyboard movements\n                    string transition = filteredWords[i].substr(overlaps[lastIdx][i]);\n                    if (!transition.empty()) {\n                        Position currentPos = startPos;\n                        if (!order.empty()) {\n                            string soFar = filteredWords[order[0]];\n                            for (int j = 1; j < order.size(); j++) {\n                                soFar += filteredWords[order[j]].substr(overlaps[order[j-1]][order[j]]);\n                            }\n                            if (!soFar.empty()) {\n                                char lastChar = soFar.back();\n                                if (!charPositions[lastChar - 'A'].empty()) {\n                                    currentPos = charPositions[lastChar - 'A'][0];\n                                }\n                            }\n                        }\n                        int typingCost = calculateTypingCost(transition, currentPos, charPositions);\n                        score -= typingCost * 0.1;\n                    }\n                    \n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestNext = i;\n                    }\n                }\n            }\n            \n            if (bestNext == -1) {\n                for (int i = 0; i < n; i++) {\n                    if (!used[i]) {\n                        bestNext = i;\n                        break;\n                    }\n                }\n            }\n            \n            order.push_back(bestNext);\n            used[bestNext] = true;\n        }\n        \n        // Build superstring from order\n        string result = filteredWords[order[0]];\n        for (int i = 1; i < n; i++) {\n            int overlap = overlaps[order[i-1]][order[i]];\n            result += filteredWords[order[i]].substr(overlap);\n        }\n        \n        // Add back any missing words\n        for (const string& word : words) {\n            if (!containsWord(result, word)) {\n                result += word;\n            }\n        }\n        \n        // Evaluate total cost\n        int cost = calculateTypingCost(result, startPos, charPositions);\n        if (bestResult.empty() || cost < bestCost) {\n            bestResult = result;\n            bestCost = cost;\n        }\n    }\n    \n    return bestResult;\n}\n\n// Type string with dynamic programming lookahead\nvector<pair<int, int>> typeStringOptimal(const string& s, Position startPos, const vector<vector<Position>>& charPositions) {\n    vector<pair<int, int>> moves;\n    Position currentPos = startPos;\n    \n    for (int idx = 0; idx < s.length(); idx++) {\n        char c = s[idx];\n        int charIdx = c - 'A';\n        \n        Position bestPos = charPositions[charIdx][0];\n        int bestTotalCost = INT_MAX;\n        \n        // Look ahead up to 3 characters\n        int lookahead = min(3, (int)s.length() - idx - 1);\n        \n        for (const Position& pos : charPositions[charIdx]) {\n            int immediateCost = manhattan(currentPos, pos);\n            int futureCost = 0;\n            \n            if (lookahead > 0) {\n                Position tempPos = pos;\n                for (int k = 1; k <= lookahead; k++) {\n                    if (idx + k < s.length()) {\n                        char nextChar = s[idx + k];\n                        int nextCharIdx = nextChar - 'A';\n                        \n                        int minNextCost = INT_MAX;\n                        for (const Position& nextPos : charPositions[nextCharIdx]) {\n                            minNextCost = min(minNextCost, manhattan(tempPos, nextPos));\n                        }\n                        futureCost += minNextCost;\n                        \n                        // Update tempPos to best position for next character\n                        for (const Position& nextPos : charPositions[nextCharIdx]) {\n                            if (manhattan(tempPos, nextPos) == minNextCost) {\n                                tempPos = nextPos;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            int totalCost = immediateCost + futureCost;\n            if (totalCost < bestTotalCost) {\n                bestTotalCost = totalCost;\n                bestPos = pos;\n            }\n        }\n        \n        moves.push_back({bestPos.i, bestPos.j});\n        currentPos = bestPos;\n        \n        if (moves.size() >= 5000) break;\n    }\n    \n    return moves;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(42); // Fixed seed for reproducibility\n    \n    int N, M;\n    cin >> N >> M;\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    vector<vector<Position>> charPositions(26);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            charPositions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n    \n    vector<string> words(M);\n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    // Build keyboard-aware superstring\n    Position startPos = {si, sj};\n    string superstring = buildSuperstring(words, startPos, charPositions);\n    \n    // Type the superstring with optimal path planning\n    vector<pair<int, int>> moves = typeStringOptimal(superstring, startPos, charPositions);\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    bool operator<(const Point& o) const { return tie(i,j) < tie(o.i,o.j); }\n    bool operator==(const Point& o) const { return i == o.i && j == o.j; }\n};\n\nclass OilExplorer {\n    int N, M;\n    double eps;\n    vector<vector<Point>> oilShapes;\n    vector<vector<int>> drilled; // -1=unknown, >=0=drilled value\n    set<Point> confirmedOil;\n    int operationCount = 0;\n    int maxOperations;\n    \n    double getCost(int numSquares) {\n        if (numSquares == 1) return 1.0;\n        return 1.0 / sqrt(numSquares);\n    }\n    \n    int queryDrill(int i, int j) {\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        if (drilled[i][j] != -1) return drilled[i][j];\n        \n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        int v;\n        if (!(cin >> v)) return 0;\n        \n        drilled[i][j] = v;\n        if (v > 0) confirmedOil.insert({i, j});\n        operationCount++;\n        return v;\n    }\n    \n    int queryDivine(const vector<Point>& pts) {\n        if (pts.size() < 2) return 0;\n        \n        cout << \"q \" << pts.size();\n        for (const auto& p : pts) {\n            cout << \" \" << p.i << \" \" << p.j;\n        }\n        cout << endl;\n        cout.flush();\n        \n        int v;\n        if (!(cin >> v)) return 0;\n        \n        operationCount++;\n        return v;\n    }\n    \n    bool submitAnswer() {\n        if (confirmedOil.empty()) {\n            // If no oil found, still need to submit something\n            cout << \"a 0\" << endl;\n        } else {\n            cout << \"a \" << confirmedOil.size();\n            for (const auto& p : confirmedOil) {\n                cout << \" \" << p.i << \" \" << p.j;\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        int result;\n        if (!(cin >> result)) return false;\n        return result == 1;\n    }\n    \n    void exploreGrid() {\n        // Phase 1: Coarse grid divination\n        int gridSize = max(3, N/4);\n        vector<vector<Point>> grids;\n        vector<int> gridResults;\n        \n        for (int gi = 0; gi < N; gi += gridSize) {\n            for (int gj = 0; gj < N; gj += gridSize) {\n                vector<Point> grid;\n                for (int i = gi; i < min(N, gi + gridSize); i++) {\n                    for (int j = gj; j < min(N, gj + gridSize); j++) {\n                        if (drilled[i][j] == -1) {\n                            grid.push_back({i, j});\n                        }\n                    }\n                }\n                \n                if (grid.size() >= 2 && operationCount < maxOperations - 50) {\n                    int result = queryDivine(grid);\n                    grids.push_back(grid);\n                    gridResults.push_back(result);\n                }\n            }\n        }\n        \n        // Phase 2: Focus on promising grids\n        for (int g = 0; g < grids.size(); g++) {\n            // Consider noise - explore even if result is low\n            double threshold = grids[g].size() * eps * 2;\n            if (gridResults[g] > threshold || gridResults[g] > 0) {\n                exploreRegion(grids[g], gridResults[g]);\n            }\n        }\n        \n        // Phase 3: Pattern matching and filling gaps\n        fillGapsWithPatternMatching();\n        \n        // Phase 4: Final drilling for uncertain areas\n        finalDrilling();\n    }\n    \n    void exploreRegion(const vector<Point>& region, int hint) {\n        if (region.size() <= 3 || operationCount >= maxOperations - 20) {\n            // Small region - drill directly\n            for (const auto& p : region) {\n                if (drilled[p.i][p.j] == -1 && operationCount < maxOperations - 10) {\n                    queryDrill(p.i, p.j);\n                }\n            }\n            return;\n        }\n        \n        // Binary split\n        vector<Point> left, right;\n        for (size_t i = 0; i < region.size(); i++) {\n            if (i < region.size() / 2) left.push_back(region[i]);\n            else right.push_back(region[i]);\n        }\n        \n        if (left.size() >= 2 && operationCount < maxOperations - 30) {\n            int leftSum = queryDivine(left);\n            if (leftSum > 0 || leftSum > left.size() * eps) {\n                exploreRegion(left, leftSum);\n            }\n        }\n        \n        if (right.size() >= 2 && operationCount < maxOperations - 30) {\n            int rightSum = queryDivine(right);\n            if (rightSum > 0 || rightSum > right.size() * eps) {\n                exploreRegion(right, rightSum);\n            }\n        }\n    }\n    \n    void fillGapsWithPatternMatching() {\n        // Check areas adjacent to confirmed oil\n        set<Point> candidates;\n        for (const auto& oil : confirmedOil) {\n            for (int di = -2; di <= 2; di++) {\n                for (int dj = -2; dj <= 2; dj++) {\n                    int ni = oil.i + di;\n                    int nj = oil.j + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && drilled[ni][nj] == -1) {\n                        candidates.insert({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Drill high-priority candidates\n        for (const auto& p : candidates) {\n            if (operationCount >= maxOperations - 10) break;\n            queryDrill(p.i, p.j);\n        }\n    }\n    \n    void finalDrilling() {\n        // Do a final pass with remaining operations\n        for (int i = 0; i < N && operationCount < maxOperations - 5; i++) {\n            for (int j = 0; j < N && operationCount < maxOperations - 5; j++) {\n                if (drilled[i][j] == -1) {\n                    // Check if likely to have oil based on surroundings\n                    int adjacentOil = 0;\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (di == 0 && dj == 0) continue;\n                            int ni = i + di, nj = j + dj;\n                            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                                if (drilled[ni][nj] > 0) adjacentOil++;\n                            }\n                        }\n                    }\n                    \n                    if (adjacentOil >= 2) {\n                        queryDrill(i, j);\n                    }\n                }\n            }\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> M >> eps;\n        \n        oilShapes.resize(M);\n        for (int m = 0; m < M; m++) {\n            int d; \n            cin >> d;\n            oilShapes[m].resize(d);\n            for (int k = 0; k < d; k++) {\n                cin >> oilShapes[m][k].i >> oilShapes[m][k].j;\n            }\n        }\n        \n        maxOperations = 2 * N * N;\n        drilled.assign(N, vector<int>(N, -1));\n        \n        exploreGrid();\n        \n        // Submit answer with retry\n        int attempts = 0;\n        while (!submitAnswer() && attempts < 3 && operationCount < maxOperations) {\n            attempts++;\n            \n            // Drill a few more uncertain squares\n            for (int i = 0; i < N && operationCount < maxOperations - 2; i++) {\n                for (int j = 0; j < N && operationCount < maxOperations - 2; j++) {\n                    if (drilled[i][j] == -1) {\n                        queryDrill(i, j);\n                        break;\n                    }\n                }\n                if (operationCount >= maxOperations - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    OilExplorer explorer;\n    explorer.solve();\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <numeric>\n#include <cmath>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Strategy: Use horizontal strips with stable heights across days\n    // Only vary widths to meet daily requirements\n    \n    // Calculate average area needs for each position\n    vector<double> avg_areas(N, 0);\n    for (int k = 0; k < N; k++) {\n        for (int d = 0; d < D; d++) {\n            avg_areas[k] += a[d][k];\n        }\n        avg_areas[k] /= D;\n    }\n    \n    // Determine stable heights based on average proportions\n    double total_avg = accumulate(avg_areas.begin(), avg_areas.end(), 0.0);\n    vector<int> heights(N);\n    int remaining_height = W;\n    \n    for (int k = 0; k < N; k++) {\n        if (k == N - 1) {\n            // Last reservation gets remaining height\n            heights[k] = remaining_height;\n        } else {\n            // Proportional allocation\n            double proportion = avg_areas[k] / total_avg;\n            int h = max(1, (int)(W * proportion + 0.5));\n            \n            // Ensure we leave space for remaining reservations\n            h = min(h, remaining_height - (N - k - 1));\n            heights[k] = h;\n            remaining_height -= h;\n        }\n    }\n    \n    // Adjust heights to ensure they can accommodate max requirements\n    for (int k = 0; k < N; k++) {\n        int max_area = 0;\n        for (int d = 0; d < D; d++) {\n            max_area = max(max_area, a[d][k]);\n        }\n        \n        // Ensure height allows for reasonable width\n        int min_height = max(1, (int)sqrt(max_area / 2));\n        if (heights[k] < min_height) {\n            // Try to steal height from larger allocations\n            int deficit = min_height - heights[k];\n            for (int j = N - 1; j > k && deficit > 0; j--) {\n                int available = max(0, heights[j] - 1);\n                int transfer = min(available, deficit);\n                heights[j] -= transfer;\n                heights[k] += transfer;\n                deficit -= transfer;\n            }\n        }\n    }\n    \n    // Output rectangles for each day\n    for (int d = 0; d < D; d++) {\n        int y = 0;\n        for (int k = 0; k < N; k++) {\n            int height = heights[k];\n            \n            // Calculate required width\n            int width = (a[d][k] + height - 1) / height; // Ceiling division\n            width = min(width, W); // Cap at grid width\n            \n            // Output rectangle: top-left (y, 0) to bottom-right (y+height, width)\n            cout << y << \" \" << 0 << \" \" << (y + height) << \" \" << width << \"\\n\";\n            y += height;\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<long long>>> stamps(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    mt19937 rng(42);\n    \n    // Use all K operations\n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        // Try all possible stamps and positions\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                    // Calculate the score for this operation\n                    double score = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long old_val = board[p + i][q + j];\n                            long long new_val = old_val + stamps[m][i][j];\n                            \n                            // Direct score increase\n                            long long old_mod = old_val % MOD;\n                            long long new_mod = new_val % MOD;\n                            score += new_mod - old_mod;\n                            \n                            // Bonus for getting closer to MOD-1 without going over\n                            if (new_val < MOD) {\n                                // Reward getting closer to MOD-1\n                                double distance_bonus = 1.0 / (1.0 + (MOD - 1 - new_val));\n                                score += distance_bonus * 100000;\n                            } else if (new_val >= MOD && old_val < MOD) {\n                                // Penalty for wrapping around from a high value\n                                score -= (old_mod / 1000.0);\n                            }\n                            \n                            // Small bonus for values in the sweet spot (90-99% of MOD)\n                            if (new_mod > 0.9 * MOD && new_mod < MOD) {\n                                score += 1000;\n                            }\n                        }\n                    }\n                    \n                    // Add small random perturbation to escape local optima\n                    score += uniform_real_distribution<double>(-0.01, 0.01)(rng);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation (even if score is not positive)\n        if (best_m != -1) {\n            operations.push_back({best_m, best_p, best_q});\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n        } else {\n            // If no operation found (shouldn't happen), pick random\n            int m = uniform_int_distribution<int>(0, M-1)(rng);\n            int p = uniform_int_distribution<int>(0, N-3)(rng);\n            int q = uniform_int_distribution<int>(0, N-3)(rng);\n            operations.push_back({m, p, q});\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[p + i][q + j] += stamps[m][i][j];\n                }\n            }\n        }\n    }\n    \n    // Output the operations\n    cout << operations.size() << \"\\n\";\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 2000;\n\nstruct Position {\n    int r, c;\n    bool operator==(const Position& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nstruct State {\n    vector<vector<int>> grid; // -1 if empty, container number otherwise\n    vector<Position> crane_pos;\n    vector<int> crane_holding; // -1 if not holding\n    vector<int> next_receive; // next container index to receive at each gate\n    vector<int> next_dispatch; // next expected container at each dispatch gate\n    vector<queue<int>> receiving_queues; // containers waiting at each receiving gate\n    \n    State(const vector<vector<int>>& A) : \n        grid(N, vector<int>(N, -1)),\n        crane_pos(N),\n        crane_holding(N, -1),\n        next_receive(N, 0),\n        next_dispatch(N),\n        receiving_queues(N) {\n        \n        // Initialize crane positions\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n        }\n        \n        // Initialize dispatch expectations\n        for (int i = 0; i < N; i++) {\n            next_dispatch[i] = i * N;\n        }\n        \n        // Initialize receiving queues\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                receiving_queues[i].push(A[i][j]);\n            }\n        }\n    }\n    \n    bool canMove(int crane, Position newPos, bool isLarge) {\n        if (newPos.r < 0 || newPos.r >= N || newPos.c < 0 || newPos.c >= N) return false;\n        \n        // Check for crane collision\n        for (int i = 0; i < N; i++) {\n            if (i != crane && crane_pos[i] == newPos) return false;\n        }\n        \n        // If small crane carrying container, can't move to occupied square\n        if (!isLarge && crane_holding[crane] != -1 && grid[newPos.r][newPos.c] != -1) {\n            return false;\n        }\n        \n        return true;\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state(A);\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        vector<char> actions(N, '.');\n        \n        // Step 1: Receive containers\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty() && \n                state.grid[i][0] == -1) {\n                bool crane_holding_here = false;\n                for (int j = 0; j < N; j++) {\n                    if (state.crane_pos[j].r == i && state.crane_pos[j].c == 0 && \n                        state.crane_holding[j] != -1) {\n                        crane_holding_here = true;\n                        break;\n                    }\n                }\n                if (!crane_holding_here) {\n                    state.grid[i][0] = state.receiving_queues[i].front();\n                    state.receiving_queues[i].pop();\n                }\n            }\n        }\n        \n        // Step 2: Decide crane actions\n        for (int crane = 0; crane < N; crane++) {\n            bool isLarge = (crane == 0);\n            Position pos = state.crane_pos[crane];\n            \n            // If holding a container\n            if (state.crane_holding[crane] != -1) {\n                int container = state.crane_holding[crane];\n                int target_row = container / N;\n                \n                // Try to move towards target dispatch gate\n                if (pos.c < N - 1) {\n                    Position newPos = {pos.r, pos.c + 1};\n                    if (state.canMove(crane, newPos, isLarge)) {\n                        actions[crane] = 'R';\n                    } else if (pos.r < target_row) {\n                        newPos = {pos.r + 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'D';\n                        }\n                    } else if (pos.r > target_row) {\n                        newPos = {pos.r - 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'U';\n                        }\n                    }\n                } else if (pos.c == N - 1 && pos.r == target_row) {\n                    // At dispatch gate\n                    if (state.grid[pos.r][pos.c] == -1) {\n                        actions[crane] = 'Q';\n                    }\n                }\n            } else {\n                // Not holding container\n                // Try to pick up if at a position with container\n                if (state.grid[pos.r][pos.c] != -1) {\n                    actions[crane] = 'P';\n                } else {\n                    // Move towards receiving gates\n                    if (pos.c > 0) {\n                        Position newPos = {pos.r, pos.c - 1};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'L';\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Execute actions\n        vector<Position> new_positions = state.crane_pos;\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            Position& pos = state.crane_pos[crane];\n            \n            if (action == 'P') {\n                if (state.grid[pos.r][pos.c] != -1 && state.crane_holding[crane] == -1) {\n                    state.crane_holding[crane] = state.grid[pos.r][pos.c];\n                    state.grid[pos.r][pos.c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (state.crane_holding[crane] != -1 && state.grid[pos.r][pos.c] == -1) {\n                    state.grid[pos.r][pos.c] = state.crane_holding[crane];\n                    state.crane_holding[crane] = -1;\n                }\n            } else if (action == 'U') {\n                new_positions[crane] = {pos.r - 1, pos.c};\n            } else if (action == 'D') {\n                new_positions[crane] = {pos.r + 1, pos.c};\n            } else if (action == 'L') {\n                new_positions[crane] = {pos.r, pos.c - 1};\n            } else if (action == 'R') {\n                new_positions[crane] = {pos.r, pos.c + 1};\n            }\n            \n            commands[crane] += action;\n        }\n        state.crane_pos = new_positions;\n        \n        // Step 3: Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (state.grid[i][N-1] != -1) {\n                state.grid[i][N-1] = -1;\n            }\n        }\n        \n        // Check if all done\n        bool all_done = true;\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty()) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) {\n            bool grid_empty = true;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) {\n                        grid_empty = false;\n                        break;\n                    }\n                }\n            }\n            if (grid_empty) break;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <map>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_OPS = 100000;\nconst int INF = 1e9;\n\nvector<string> operations;\nint grid[N][N];\nint cur_r = 0, cur_c = 0;\nint loaded = 0;\n\n// Direction vectors\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\n// BFS to find shortest path\nvector<int> find_path(int sr, int sc, int tr, int tc) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    \n    dist[sr][sc] = 0;\n    q.push({sr, sc});\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        \n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == INF) {\n                dist[nr][nc] = dist[r][c] + 1;\n                parent[nr][nc] = d;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path;\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int d = parent[r][c];\n        path.push_back(d);\n        r -= dr[d];\n        c -= dc[d];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Move to target location\nvoid move_to(int tr, int tc) {\n    if (cur_r == tr && cur_c == tc) return;\n    \n    vector<int> path = find_path(cur_r, cur_c, tr, tc);\n    for (int d : path) {\n        operations.push_back(string(1, dir_char[d]));\n        cur_r += dr[d];\n        cur_c += dc[d];\n    }\n}\n\n// Load soil from current position\nvoid load_soil(int amount) {\n    if (amount <= 0) return;\n    operations.push_back(\"+\" + to_string(amount));\n    grid[cur_r][cur_c] -= amount;\n    loaded += amount;\n}\n\n// Unload soil to current position  \nvoid unload_soil(int amount) {\n    if (amount <= 0 || loaded <= 0) return;\n    amount = min(amount, loaded);\n    operations.push_back(\"-\" + to_string(amount));\n    grid[cur_r][cur_c] += amount;\n    loaded -= amount;\n}\n\nint manhattan_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    // Read grid\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    // Process soil movements using a greedy nearest-neighbor approach\n    while (operations.size() < MAX_OPS - 1000) {\n        bool found = false;\n        \n        // Find the closest positive-negative pair\n        int best_sr = -1, best_sc = -1, best_dr = -1, best_dc = -1;\n        int best_dist = INF;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] > 0) {\n                    // Find nearest negative cell to this positive cell\n                    for (int di = 0; di < N; di++) {\n                        for (int dj = 0; dj < N; dj++) {\n                            if (grid[di][dj] < 0) {\n                                int dist = manhattan_dist(i, j, di, dj);\n                                // Prefer closer pairs and also consider current position\n                                int total_dist = manhattan_dist(cur_r, cur_c, i, j) + dist;\n                                if (total_dist < best_dist) {\n                                    best_dist = total_dist;\n                                    best_sr = i; best_sc = j;\n                                    best_dr = di; best_dc = dj;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (best_sr == -1) break;\n        \n        // Transport soil from source to destination\n        move_to(best_sr, best_sc);\n        int amount = min(grid[best_sr][best_sc], -grid[best_dr][best_dc]);\n        load_soil(amount);\n        \n        move_to(best_dr, best_dc);\n        unload_soil(amount);\n        \n        found = true;\n        \n        // Check if we're done\n        bool all_zero = true;\n        for (int i = 0; i < N && all_zero; i++) {\n            for (int j = 0; j < N && all_zero; j++) {\n                if (grid[i][j] != 0) all_zero = false;\n            }\n        }\n        if (all_zero) break;\n        \n        if (!found) break;\n    }\n    \n    // Output operations\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 <random>\n#include <numeric>\n#include <set>\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));\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    random_device rd;\n    mt19937 gen(rd());\n    \n    for (int t = 0; t < T; t++) {\n        // Calculate values and trait strengths for each seed\n        vector<int> seed_values(seed_count);\n        vector<vector<int>> trait_ranks(M);\n        \n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += X[i][j];\n                trait_ranks[j].push_back(X[i][j]);\n            }\n        }\n        \n        // Find median values for each trait\n        vector<int> trait_medians(M);\n        for (int j = 0; j < M; j++) {\n            sort(trait_ranks[j].begin(), trait_ranks[j].end());\n            trait_medians[j] = trait_ranks[j][seed_count/2];\n        }\n        \n        // Score seeds with bonus for balanced excellence\n        vector<pair<double, int>> seed_scores;\n        for (int i = 0; i < seed_count; i++) {\n            double score = seed_values[i];\n            \n            // Add bonus for seeds that are strong in multiple traits\n            int strong_traits = 0;\n            double min_trait = 1000000;\n            for (int j = 0; j < M; j++) {\n                if (X[i][j] > trait_medians[j]) strong_traits++;\n                min_trait = min(min_trait, (double)X[i][j]);\n            }\n            \n            // Bonus for balanced seeds (high minimum trait)\n            score += min_trait * 0.5;\n            \n            // Bonus for being strong in many traits\n            score += strong_traits * 10;\n            \n            seed_scores.push_back({score, i});\n        }\n        \n        // Sort seeds by score\n        sort(seed_scores.begin(), seed_scores.end(), greater<pair<double,int>>());\n        \n        // Create placement grid\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        vector<bool> used(seed_count, false);\n        \n        // Strategy changes based on generation\n        if (t < T/3) {\n            // Early generations: Focus on diversity and exploration\n            // Select diverse high-value seeds\n            vector<int> selected;\n            set<int> used_seeds;\n            \n            // First, take top seeds\n            int elite_count = N*N/3;\n            for (int i = 0; i < elite_count && selected.size() < N*N; i++) {\n                int sid = seed_scores[i].second;\n                selected.push_back(sid);\n                used_seeds.insert(sid);\n            }\n            \n            // Then add diverse seeds\n            for (int i = elite_count; i < seed_count && selected.size() < N*N; i++) {\n                int sid = seed_scores[i].second;\n                if (used_seeds.find(sid) == used_seeds.end()) {\n                    // Check if this seed adds diversity\n                    bool adds_diversity = false;\n                    for (int j = 0; j < M; j++) {\n                        bool is_best = true;\n                        for (int sel : selected) {\n                            if (X[sel][j] >= X[sid][j]) {\n                                is_best = false;\n                                break;\n                            }\n                        }\n                        if (is_best) {\n                            adds_diversity = true;\n                            break;\n                        }\n                    }\n                    if (adds_diversity || selected.size() < N*N - 5) {\n                        selected.push_back(sid);\n                        used_seeds.insert(sid);\n                    }\n                }\n            }\n            \n            // Fill remaining with top seeds\n            for (int i = 0; i < seed_count && selected.size() < N*N; i++) {\n                int sid = seed_scores[i].second;\n                if (used_seeds.find(sid) == used_seeds.end()) {\n                    selected.push_back(sid);\n                    used_seeds.insert(sid);\n                }\n            }\n            \n            // Place seeds in a pattern that maximizes breeding opportunities\n            // Checkerboard pattern with best seeds\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    A[i][j] = selected[idx++];\n                }\n            }\n            \n        } else if (t < 2*T/3) {\n            // Middle generations: Focus on creating super seeds\n            // Group similar high-value seeds together\n            \n            // Take top N*N seeds\n            vector<int> selected;\n            for (int i = 0; i < N*N; i++) {\n                selected.push_back(seed_scores[i].second);\n            }\n            \n            // Place best seeds in center, working outward\n            vector<pair<int, pair<int,int>>> positions;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    int dist_to_center = abs(i - N/2) + abs(j - N/2);\n                    positions.push_back({dist_to_center, {i, j}});\n                }\n            }\n            sort(positions.begin(), positions.end());\n            \n            for (int idx = 0; idx < N*N; idx++) {\n                A[positions[idx].second.first][positions[idx].second.second] = selected[idx];\n            }\n            \n        } else {\n            // Late generations: Intensification - focus on best seeds\n            // Place absolute best seeds with maximum breeding opportunities\n            \n            vector<int> selected;\n            for (int i = 0; i < N*N; i++) {\n                selected.push_back(seed_scores[i].second);\n            }\n            \n            // Create clusters of top seeds\n            // Place best 4 seeds in 2x2 blocks for maximum breeding\n            int idx = 0;\n            for (int bi = 0; bi < N/2; bi++) {\n                for (int bj = 0; bj < N/2; bj++) {\n                    for (int di = 0; di < 2; di++) {\n                        for (int dj = 0; dj < 2; dj++) {\n                            A[bi*2 + di][bj*2 + dj] = selected[idx++];\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Output placement\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                } else {\n                    cout << endl;\n                }\n            }\n        }\n        cout.flush();\n        \n        // Read new generation of seeds\n        X.clear();\n        X.resize(seed_count, vector<int>(M));\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {0, 1, 0, -1};\nconst int dy[] = {1, 0, -1, 0};\nconst char dirChar[] = {'R', 'D', 'L', 'U'};\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator==(const Point& p) const { return x == p.x && y == p.y; }\n    int dist(const Point& p) const { return abs(x - p.x) + abs(y - p.y); }\n};\n\nstruct Arm {\n    int V;\n    vector<int> parent;\n    vector<int> length;\n    vector<int> direction;  // 0=right, 1=down, 2=left, 3=up\n    Point root;\n    vector<bool> isLeaf;\n    vector<Point> positions;\n    \n    void calculatePositions() {\n        positions.resize(V);\n        positions[0] = root;\n        for (int v = 1; v < V; v++) {\n            Point p = positions[parent[v]];\n            positions[v] = Point(p.x + dx[direction[v]] * length[v],\n                                p.y + dy[direction[v]] * length[v]);\n        }\n    }\n    \n    bool isValid(int N) {\n        for (auto& p : positions) {\n            if (p.x < 0 || p.x >= N || p.y < 0 || p.y >= N) {\n                for (int i = 1; i < V; i++) {\n                    if (isLeaf[i] && positions[i] == p) return false;\n                }\n            }\n        }\n        return true;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> grid(N), target(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    for (int i = 0; i < N; i++) cin >> target[i];\n    \n    vector<Point> sources, targets;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (grid[i][j] == '1') sources.push_back(Point(i, j));\n            if (target[i][j] == '1') targets.push_back(Point(i, j));\n        }\n    }\n    \n    // Design arm: star pattern with center and multiple arms\n    Arm arm;\n    arm.V = min(V, 7);\n    arm.parent.resize(arm.V);\n    arm.length.resize(arm.V);\n    arm.direction.resize(arm.V, 0);\n    arm.isLeaf.resize(arm.V, true);\n    arm.positions.resize(arm.V);\n    \n    arm.parent[0] = -1;\n    arm.isLeaf[0] = false;\n    \n    // Create arms extending from root\n    for (int i = 1; i < arm.V; i++) {\n        arm.parent[i] = 0;\n        arm.length[i] = min(3, (i + 1) / 2);\n        arm.direction[i] = (i - 1) % 4;\n    }\n    \n    arm.root = Point(N/2, N/2);\n    \n    // Output arm design\n    cout << arm.V << \"\\n\";\n    for (int i = 1; i < arm.V; i++) {\n        cout << arm.parent[i] << \" \" << arm.length[i] << \"\\n\";\n    }\n    cout << arm.root.x << \" \" << arm.root.y << \"\\n\";\n    \n    // Simulation\n    vector<bool> sourceDone(M, false);\n    vector<bool> targetDone(M, false);\n    vector<int> holding(arm.V, -1);\n    vector<string> operations;\n    \n    auto currentGrid = grid;\n    \n    for (int turn = 0; turn < 50000; turn++) {\n        if (count(targetDone.begin(), targetDone.end(), true) == M) break;\n        \n        arm.calculatePositions();\n        string op(2 * arm.V, '.');\n        \n        // Try to pick up or place takoyaki\n        for (int v = 1; v < arm.V; v++) {\n            if (!arm.isLeaf[v]) continue;\n            \n            Point pos = arm.positions[v];\n            if (pos.x < 0 || pos.x >= N || pos.y < 0 || pos.y >= N) continue;\n            \n            if (holding[v] == -1) {\n                // Try to pick up\n                for (int i = 0; i < M; i++) {\n                    if (!sourceDone[i] && sources[i] == pos && currentGrid[pos.x][pos.y] == '1') {\n                        op[arm.V + v] = 'P';\n                        holding[v] = i;\n                        sourceDone[i] = true;\n                        currentGrid[pos.x][pos.y] = '0';\n                        break;\n                    }\n                }\n            } else {\n                // Try to place\n                for (int i = 0; i < M; i++) {\n                    if (!targetDone[i] && targets[i] == pos && currentGrid[pos.x][pos.y] == '0') {\n                        op[arm.V + v] = 'P';\n                        targetDone[i] = true;\n                        currentGrid[pos.x][pos.y] = '1';\n                        holding[v] = -1;\n                        break;\n                    }\n                }\n            }\n        }\n        \n        // Find goal\n        Point goal(-1, -1);\n        int minDist = INT_MAX;\n        \n        // Look for source to pick up\n        for (int i = 0; i < M; i++) {\n            if (!sourceDone[i]) {\n                int d = arm.root.dist(sources[i]);\n                if (d < minDist) {\n                    minDist = d;\n                    goal = sources[i];\n                }\n            }\n        }\n        \n        // Look for target to deliver\n        for (int v = 1; v < arm.V; v++) {\n            if (holding[v] != -1) {\n                for (int i = 0; i < M; i++) {\n                    if (!targetDone[i]) {\n                        int d = arm.root.dist(targets[i]);\n                        if (d < minDist - 2) {\n                            minDist = d;\n                            goal = targets[i];\n                        }\n                    }\n                }\n                break;\n            }\n        }\n        \n        // Move towards goal\n        if (goal.x != -1) {\n            int newX = arm.root.x;\n            int newY = arm.root.y;\n            \n            if (goal.x < arm.root.x && arm.root.x > 0) {\n                newX--;\n                op[0] = 'U';\n            } else if (goal.x > arm.root.x && arm.root.x < N-1) {\n                newX++;\n                op[0] = 'D';\n            } else if (goal.y < arm.root.y && arm.root.y > 0) {\n                newY--;\n                op[0] = 'L';\n            } else if (goal.y > arm.root.y && arm.root.y < N-1) {\n                newY++;\n                op[0] = 'R';\n            }\n            \n            if (op[0] != '.') {\n                arm.root.x = newX;\n                arm.root.y = newY;\n            }\n        }\n        \n        // Adjust arm directions\n        if (turn % 5 == 0) {\n            for (int v = 1; v < arm.V; v++) {\n                if (goal.x != -1) {\n                    Point pos = arm.positions[v];\n                    int bestDir = arm.direction[v];\n                    int bestDist = pos.dist(goal);\n                    \n                    for (int d = 0; d < 4; d++) {\n                        Point newPos(arm.positions[arm.parent[v]].x + dx[d] * arm.length[v],\n                                   arm.positions[arm.parent[v]].y + dy[d] * arm.length[v]);\n                        int dist = newPos.dist(goal);\n                        if (dist < bestDist) {\n                            bestDist = dist;\n                            bestDir = d;\n                        }\n                    }\n                    \n                    if (bestDir != arm.direction[v]) {\n                        int diff = (bestDir - arm.direction[v] + 4) % 4;\n                        if (diff == 1) {\n                            op[v] = 'R';\n                            arm.direction[v] = bestDir;\n                        } else if (diff == 3) {\n                            op[v] = 'L';\n                            arm.direction[v] = bestDir;\n                        }\n                    }\n                }\n            }\n        }\n        \n        operations.push_back(op);\n    }\n    \n    for (const auto& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\nconst int GRID_SIZE = 100; // Divide space into 100x100 grid\nconst int CELL_SIZE = 1001; // Cell size for grid\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nclass Solution {\nprivate:\n    int N;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    vector<vector<int>> grid;\n    \npublic:\n    void solve() {\n        cin >> N;\n        mackerels.resize(N);\n        sardines.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> mackerels[i].x >> mackerels[i].y;\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> sardines[i].x >> sardines[i].y;\n        }\n        \n        // Build grid with net scores\n        buildGrid();\n        \n        // Find best rectangle using 2D max subarray\n        auto [x1, y1, x2, y2] = findBestRectangleGrid();\n        \n        // Fine-tune the boundaries\n        fineTuneBoundaries(x1, y1, x2, y2);\n        \n        // Output as polygon\n        cout << \"4\\n\";\n        cout << x1 << \" \" << y1 << \"\\n\";\n        cout << x2 << \" \" << y1 << \"\\n\";\n        cout << x2 << \" \" << y2 << \"\\n\";\n        cout << x1 << \" \" << y2 << \"\\n\";\n    }\n    \nprivate:\n    void buildGrid() {\n        grid.assign(GRID_SIZE, vector<int>(GRID_SIZE, 0));\n        \n        // Count mackerels in each cell\n        for (const auto& p : mackerels) {\n            int gx = min(p.x / CELL_SIZE, GRID_SIZE - 1);\n            int gy = min(p.y / CELL_SIZE, GRID_SIZE - 1);\n            grid[gx][gy]++;\n        }\n        \n        // Subtract sardines in each cell\n        for (const auto& p : sardines) {\n            int gx = min(p.x / CELL_SIZE, GRID_SIZE - 1);\n            int gy = min(p.y / CELL_SIZE, GRID_SIZE - 1);\n            grid[gx][gy]--;\n        }\n    }\n    \n    tuple<int, int, int, int> findBestRectangleGrid() {\n        int best_score = 0;\n        int best_x1 = 0, best_y1 = 0, best_x2 = 10000, best_y2 = 10000;\n        \n        // Use 2D Kadane's algorithm for maximum subarray\n        for (int left = 0; left < GRID_SIZE; left++) {\n            vector<int> temp(GRID_SIZE, 0);\n            \n            for (int right = left; right < GRID_SIZE; right++) {\n                // Check if rectangle would be too large\n                int width = (right - left + 1) * CELL_SIZE;\n                if (width > 200000) break; // Half of max edge length\n                \n                // Add current column to temp\n                for (int i = 0; i < GRID_SIZE; i++) {\n                    temp[i] += grid[right][i];\n                }\n                \n                // Apply 1D Kadane on temp\n                int current_sum = 0;\n                int max_sum = 0;\n                int start = 0, end = -1;\n                int temp_start = 0;\n                \n                for (int i = 0; i < GRID_SIZE; i++) {\n                    current_sum += temp[i];\n                    \n                    if (current_sum > max_sum) {\n                        max_sum = current_sum;\n                        start = temp_start;\n                        end = i;\n                    }\n                    \n                    if (current_sum < 0) {\n                        current_sum = 0;\n                        temp_start = i + 1;\n                    }\n                    \n                    // Check height constraint\n                    int height = (i - temp_start + 1) * CELL_SIZE;\n                    if (height > 200000) { // Half of max edge length\n                        current_sum = temp[i];\n                        temp_start = i;\n                    }\n                }\n                \n                if (max_sum > best_score) {\n                    best_score = max_sum;\n                    best_x1 = left * CELL_SIZE;\n                    best_y1 = start * CELL_SIZE;\n                    best_x2 = min((right + 1) * CELL_SIZE, MAX_COORD);\n                    best_y2 = min((end + 1) * CELL_SIZE, MAX_COORD);\n                }\n            }\n        }\n        \n        return {best_x1, best_y1, best_x2, best_y2};\n    }\n    \n    void fineTuneBoundaries(int& x1, int& y1, int& x2, int& y2) {\n        // Quick calculation of current score\n        auto calcScore = [&](int x1, int y1, int x2, int y2) {\n            int score = 0;\n            for (const auto& p : mackerels) {\n                if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                    score++;\n                }\n            }\n            for (const auto& p : sardines) {\n                if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                    score--;\n                }\n            }\n            return score;\n        };\n        \n        int current_score = calcScore(x1, y1, x2, y2);\n        \n        // Try small adjustments to boundaries\n        int step = 500;\n        for (int iter = 0; iter < 5; iter++) {\n            bool improved = false;\n            \n            // Try adjusting each boundary\n            for (int dx : {-step, 0, step}) {\n                for (int dy : {-step, 0, step}) {\n                    if (dx == 0 && dy == 0) continue;\n                    \n                    // Adjust x1\n                    if (x1 + dx >= 0 && x1 + dx < x2) {\n                        int new_score = calcScore(x1 + dx, y1, x2, y2);\n                        if (new_score > current_score) {\n                            x1 += dx;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                    \n                    // Adjust x2\n                    if (x2 + dx <= MAX_COORD && x2 + dx > x1 && \n                        2 * ((x2 + dx - x1) + (y2 - y1)) <= 400000) {\n                        int new_score = calcScore(x1, y1, x2 + dx, y2);\n                        if (new_score > current_score) {\n                            x2 += dx;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                    \n                    // Adjust y1\n                    if (y1 + dy >= 0 && y1 + dy < y2) {\n                        int new_score = calcScore(x1, y1 + dy, x2, y2);\n                        if (new_score > current_score) {\n                            y1 += dy;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                    \n                    // Adjust y2\n                    if (y2 + dy <= MAX_COORD && y2 + dy > y1 && \n                        2 * ((x2 - x1) + (y2 + dy - y1)) <= 400000) {\n                        int new_score = calcScore(x1, y1, x2, y2 + dy);\n                        if (new_score > current_score) {\n                            y2 += dy;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            \n            if (!improved) break;\n            step = max(100, step / 2);\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int idx;\n    int obs_w, obs_h;  // Observed dimensions\n    double est_w, est_h;  // Estimated true dimensions\n    int count_obs;  // Number of observations\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nclass Packer {\nprivate:\n    int N, T;\n    double sigma;\n    vector<Rectangle> rects;\n    vector<vector<pair<int, int>>> all_measurements; // Store measurements for each rect\n    \n    vector<Placement> createBottomLeftPacking(const vector<bool>& use_rect, const vector<bool>& rotations) {\n        vector<Placement> result;\n        \n        for (int i = 0; i < N; i++) {\n            if (!use_rect[i]) continue;\n            \n            // Determine best placement for this rectangle\n            int best_b = -1;\n            char best_d = 'U';\n            \n            if (result.empty()) {\n                // First rectangle goes at origin\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n            } else {\n                // Try to find good placement\n                // Strategy: alternate between U and L placements for better packing\n                int placement_idx = result.size();\n                \n                if (placement_idx % 2 == 0) {\n                    // Try to place using U (to the right)\n                    best_d = 'U';\n                    // Reference the last placed rectangle for horizontal placement\n                    best_b = placement_idx - 1;\n                } else {\n                    // Try to place using L (above)\n                    best_d = 'L';\n                    // Reference a recent rectangle\n                    best_b = max(0, placement_idx - 2);\n                }\n                \n                result.push_back({i, rotations[i] ? 1 : 0, best_b, best_d});\n            }\n        }\n        \n        return result;\n    }\n    \n    vector<Placement> createStripPacking(const vector<bool>& use_rect, const vector<bool>& rotations) {\n        vector<Placement> result;\n        \n        for (int i = 0; i < N; i++) {\n            if (!use_rect[i]) continue;\n            \n            if (result.empty()) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n            } else {\n                // Create horizontal strips\n                result.push_back({i, rotations[i] ? 1 : 0, (int)result.size() - 1, 'U'});\n            }\n        }\n        \n        return result;\n    }\n    \n    vector<Placement> createColumnPacking(const vector<bool>& use_rect, const vector<bool>& rotations) {\n        vector<Placement> result;\n        \n        for (int i = 0; i < N; i++) {\n            if (!use_rect[i]) continue;\n            \n            if (result.empty()) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'L'});\n            } else {\n                // Create vertical columns\n                result.push_back({i, rotations[i] ? 1 : 0, (int)result.size() - 1, 'L'});\n            }\n        }\n        \n        return result;\n    }\n    \n    pair<int, int> query(const vector<Placement>& placements) {\n        cout << placements.size() << endl;\n        for (const auto& p : placements) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << endl;\n        }\n        cout.flush();\n        \n        int W, H;\n        cin >> W >> H;\n        \n        // Update measurements for placed rectangles\n        for (const auto& p : placements) {\n            all_measurements[p.p].push_back({W, H});\n            rects[p.p].count_obs++;\n        }\n        \n        return {W, H};\n    }\n    \n    void updateEstimates() {\n        // Update size estimates based on multiple observations\n        for (int i = 0; i < N; i++) {\n            if (rects[i].count_obs > 1) {\n                // Use weighted average with more weight on recent observations\n                double weight_sum = 0;\n                double weighted_w = 0, weighted_h = 0;\n                \n                for (int j = 0; j < rects[i].count_obs; j++) {\n                    double weight = 1.0; // Equal weight for now\n                    weight_sum += weight;\n                }\n                \n                // Keep most of the observed value but adjust slightly\n                rects[i].est_w = rects[i].obs_w * 0.9 + rects[i].est_w * 0.1;\n                rects[i].est_h = rects[i].obs_h * 0.9 + rects[i].est_h * 0.1;\n            }\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> T >> sigma;\n        rects.resize(N);\n        all_measurements.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            rects[i].idx = i;\n            cin >> rects[i].obs_w >> rects[i].obs_h;\n            rects[i].est_w = rects[i].obs_w;\n            rects[i].est_h = rects[i].obs_h;\n            rects[i].count_obs = 0;\n        }\n        \n        for (int turn = 0; turn < T; turn++) {\n            vector<bool> use_rect(N, true);  // Use all rectangles\n            vector<bool> rotations(N, false);\n            \n            // Determine rotation strategy\n            for (int i = 0; i < N; i++) {\n                // Rotate tall rectangles in early turns, wide rectangles in later turns\n                if (turn < T / 3) {\n                    // Make rectangles more uniform by rotating tall ones\n                    rotations[i] = (rects[i].est_h > rects[i].est_w * 1.5);\n                } else if (turn < 2 * T / 3) {\n                    // Try to minimize height - rotate wide rectangles\n                    rotations[i] = (rects[i].est_w > rects[i].est_h);\n                } else {\n                    // Try to minimize width - rotate tall rectangles\n                    rotations[i] = (rects[i].est_h > rects[i].est_w);\n                }\n            }\n            \n            // Choose packing strategy based on turn\n            vector<Placement> placements;\n            \n            if (turn % 3 == 0) {\n                placements = createBottomLeftPacking(use_rect, rotations);\n            } else if (turn % 3 == 1) {\n                placements = createStripPacking(use_rect, rotations);\n            } else {\n                placements = createColumnPacking(use_rect, rotations);\n            }\n            \n            query(placements);\n            updateEstimates();\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.solve();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass ForestOptimizer {\n    int N, M, H;\n    vector<int> beauty;\n    vector<vector<int>> adj;\n    vector<pair<int,int>> coords;\n    \n    struct Solution {\n        vector<int> parent;\n        long long score;\n    };\n    \n    long long calculateScore(const vector<int>& parent) {\n        long long score = 1;\n        for (int i = 0; i < N; i++) {\n            int depth = 0;\n            int curr = i;\n            while (parent[curr] != -1) {\n                depth++;\n                curr = parent[curr];\n            }\n            score += (long long)(depth + 1) * beauty[i];\n        }\n        return score;\n    }\n    \n    long long evaluateSubtreeScore(int root, const vector<bool>& used, int maxDepth) {\n        if (used[root]) return 0;\n        \n        vector<bool> visited = used;\n        visited[root] = true;\n        queue<pair<int,int>> q;\n        q.push({root, 0});\n        \n        long long score = beauty[root];\n        \n        while (!q.empty()) {\n            auto [u, depth] = q.front();\n            q.pop();\n            \n            if (depth >= maxDepth) continue;\n            \n            vector<int> candidates;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    candidates.push_back(v);\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                return beauty[a] > beauty[b];\n            });\n            \n            for (int v : candidates) {\n                visited[v] = true;\n                score += (long long)(depth + 2) * beauty[v];\n                q.push({v, depth + 1});\n            }\n        }\n        \n        return score;\n    }\n    \n    Solution buildForestWithStrategy(function<bool(int,int)> comparator) {\n        vector<int> parent(N, -1);\n        vector<int> depth(N, -1);\n        vector<bool> visited(N, false);\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), comparator);\n        \n        for (int root : order) {\n            if (visited[root]) continue;\n            \n            depth[root] = 0;\n            visited[root] = true;\n            \n            priority_queue<pair<int,int>> pq;\n            pq.push({beauty[root], root});\n            \n            while (!pq.empty()) {\n                auto [_, u] = pq.top();\n                pq.pop();\n                \n                if (depth[u] >= H) continue;\n                \n                for (int v : adj[u]) {\n                    if (!visited[v]) {\n                        parent[v] = u;\n                        depth[v] = depth[u] + 1;\n                        visited[v] = true;\n                        pq.push({beauty[v] * (H - depth[v]), v});\n                    }\n                }\n            }\n        }\n        \n        return {parent, calculateScore(parent)};\n    }\n    \n    Solution buildForestWithEvaluation() {\n        vector<int> parent(N, -1);\n        vector<bool> used(N, false);\n        vector<int> depth(N, -1);\n        \n        while (true) {\n            int bestRoot = -1;\n            long long bestScore = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (!used[i]) {\n                    long long score = evaluateSubtreeScore(i, used, H);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestRoot = i;\n                    }\n                }\n            }\n            \n            if (bestRoot == -1) break;\n            \n            used[bestRoot] = true;\n            depth[bestRoot] = 0;\n            \n            queue<int> q;\n            q.push(bestRoot);\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                if (depth[u] >= H) continue;\n                \n                vector<int> candidates;\n                for (int v : adj[u]) {\n                    if (!used[v]) {\n                        candidates.push_back(v);\n                    }\n                }\n                \n                sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                    return beauty[a] > beauty[b];\n                });\n                \n                for (int v : candidates) {\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    used[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        \n        return {parent, calculateScore(parent)};\n    }\n    \n    Solution localSearch(Solution initial) {\n        vector<int> parent = initial.parent;\n        long long currentScore = initial.score;\n        \n        // Try reassigning leaf nodes\n        for (int iter = 0; iter < 100; iter++) {\n            bool improved = false;\n            \n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                \n                // Check if v is a leaf\n                bool isLeaf = true;\n                for (int u = 0; u < N; u++) {\n                    if (parent[u] == v) {\n                        isLeaf = false;\n                        break;\n                    }\n                }\n                \n                if (!isLeaf) continue;\n                \n                int oldParent = parent[v];\n                \n                // Try reassigning to different parents\n                for (int newParent : adj[v]) {\n                    if (newParent == oldParent) continue;\n                    \n                    // Check depth constraint\n                    int newDepth = 0;\n                    int curr = newParent;\n                    while (parent[curr] != -1) {\n                        newDepth++;\n                        curr = parent[curr];\n                    }\n                    \n                    if (newDepth >= H) continue;\n                    \n                    parent[v] = newParent;\n                    long long newScore = calculateScore(parent);\n                    \n                    if (newScore > currentScore) {\n                        currentScore = newScore;\n                        improved = true;\n                    } else {\n                        parent[v] = oldParent;\n                    }\n                }\n            }\n            \n            if (!improved) break;\n        }\n        \n        return {parent, currentScore};\n    }\n    \npublic:\n    ForestOptimizer(int n, int m, int h) : N(n), M(m), H(h) {\n        beauty.resize(N);\n        adj.resize(N);\n        coords.resize(N);\n    }\n    \n    void input() {\n        for (int i = 0; i < N; i++) {\n            cin >> beauty[i];\n        }\n        \n        for (int i = 0; i < M; i++) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> coords[i].first >> coords[i].second;\n        }\n    }\n    \n    vector<int> solve() {\n        Solution best = {{}, 0};\n        \n        // Strategy 1: Pure beauty greedy\n        auto sol1 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] > beauty[b];\n        });\n        if (sol1.score > best.score) best = sol1;\n        \n        // Strategy 2: Beauty * degree\n        auto sol2 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] * (int)adj[a].size() > beauty[b] * (int)adj[b].size();\n        });\n        if (sol2.score > best.score) best = sol2;\n        \n        // Strategy 3: Evaluation-based\n        auto sol3 = buildForestWithEvaluation();\n        if (sol3.score > best.score) best = sol3;\n        \n        // Strategy 4: Beauty / (degree + 1) for better root selection\n        auto sol4 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] * 1.0 / (adj[a].size() + 1) > beauty[b] * 1.0 / (adj[b].size() + 1);\n        });\n        if (sol4.score > best.score) best = sol4;\n        \n        // Apply local search to best solution\n        best = localSearch(best);\n        \n        return best.parent;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    ForestOptimizer optimizer(N, M, H);\n    optimizer.input();\n    \n    vector<int> result = optimizer.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> operations;\n    \n    // Process by batches - try to remove multiple Oni at once\n    while (true) {\n        bool found = false;\n        int best_efficiency = INT_MAX;\n        char best_dir = ' ';\n        int best_line = -1;\n        vector<pair<int,int>> best_targets;\n        \n        // Check all columns for upward removal\n        for (int j = 0; j < N; j++) {\n            vector<pair<int,int>> targets;\n            int max_row = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = 0; k < i; k++) {\n                    if (board[k][j] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    targets.push_back({i, j});\n                    max_row = max(max_row, i);\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * (max_row + 1);\n                int efficiency = cost / (int)targets.size();\n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'U';\n                    best_line = j;\n                    best_targets = targets;\n                }\n            }\n        }\n        \n        // Check all columns for downward removal\n        for (int j = 0; j < N; j++) {\n            vector<pair<int,int>> targets;\n            int min_row = N;\n            \n            for (int i = 0; i < N; i++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = i + 1; k < N; k++) {\n                    if (board[k][j] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    targets.push_back({i, j});\n                    min_row = min(min_row, i);\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * (N - min_row);\n                int efficiency = cost / (int)targets.size();\n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'D';\n                    best_line = j;\n                    best_targets = targets;\n                }\n            }\n        }\n        \n        // Check all rows for leftward removal\n        for (int i = 0; i < N; i++) {\n            vector<pair<int,int>> targets;\n            int max_col = -1;\n            \n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = 0; k < j; k++) {\n                    if (board[i][k] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    targets.push_back({i, j});\n                    max_col = max(max_col, j);\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * (max_col + 1);\n                int efficiency = cost / (int)targets.size();\n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'L';\n                    best_line = i;\n                    best_targets = targets;\n                }\n            }\n        }\n        \n        // Check all rows for rightward removal\n        for (int i = 0; i < N; i++) {\n            vector<pair<int,int>> targets;\n            int min_col = N;\n            \n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = j + 1; k < N; k++) {\n                    if (board[i][k] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    targets.push_back({i, j});\n                    min_col = min(min_col, j);\n                }\n            }\n            \n            if (!targets.empty()) {\n                int cost = 2 * (N - min_col);\n                int efficiency = cost / (int)targets.size();\n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'R';\n                    best_line = i;\n                    best_targets = targets;\n                }\n            }\n        }\n        \n        if (best_line == -1) break;\n        \n        // Execute the best batch removal\n        if (best_dir == 'U') {\n            int max_row = 0;\n            for (auto [i, j] : best_targets) {\n                max_row = max(max_row, i);\n            }\n            for (int t = 0; t <= max_row; t++) {\n                operations.push_back({'U', best_line});\n            }\n            for (int t = 0; t <= max_row; t++) {\n                operations.push_back({'D', best_line});\n            }\n        } else if (best_dir == 'D') {\n            int min_row = N;\n            for (auto [i, j] : best_targets) {\n                min_row = min(min_row, i);\n            }\n            for (int t = 0; t < N - min_row; t++) {\n                operations.push_back({'D', best_line});\n            }\n            for (int t = 0; t < N - min_row; t++) {\n                operations.push_back({'U', best_line});\n            }\n        } else if (best_dir == 'L') {\n            int max_col = 0;\n            for (auto [i, j] : best_targets) {\n                max_col = max(max_col, j);\n            }\n            for (int t = 0; t <= max_col; t++) {\n                operations.push_back({'L', best_line});\n            }\n            for (int t = 0; t <= max_col; t++) {\n                operations.push_back({'R', best_line});\n            }\n        } else if (best_dir == 'R') {\n            int min_col = N;\n            for (auto [i, j] : best_targets) {\n                min_col = min(min_col, j);\n            }\n            for (int t = 0; t < N - min_col; t++) {\n                operations.push_back({'R', best_line});\n            }\n            for (int t = 0; t < N - min_col; t++) {\n                operations.push_back({'L', best_line});\n            }\n        }\n        \n        // Mark removed Oni\n        for (auto [i, j] : best_targets) {\n            board[i][j] = '.';\n        }\n    }\n    \n    // Output operations\n    for (auto [dir, pos] : operations) {\n        cout << dir << \" \" << pos << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N), b(N);\n    mt19937 rng(42);\n    \n    // Create a weighted random selection based on targets\n    auto selectNext = [&](const vector<int>& counts, int totalSteps) -> int {\n        vector<double> weights(N);\n        double scale = (double)L / totalSteps;\n        for (int i = 0; i < N; i++) {\n            double expected = T[i] * ((double)totalSteps / L);\n            weights[i] = max(1.0, expected - counts[i] + 1.0);\n        }\n        discrete_distribution<int> dist(weights.begin(), weights.end());\n        return dist(rng);\n    };\n    \n    // Build initial solution greedily\n    vector<int> counts(N, 0);\n    counts[0] = 1;\n    \n    // Simulate forward and build the graph greedily\n    int current = 0;\n    for (int step = 2; step <= min(5000, L); step++) {\n        int next;\n        if (counts[current] % 2 == 1) {\n            // Choose a[current]\n            next = selectNext(counts, step);\n            a[current] = next;\n        } else {\n            // Choose b[current]\n            next = selectNext(counts, step);\n            b[current] = next;\n        }\n        current = next;\n        counts[current]++;\n    }\n    \n    // Fill in any unset values\n    for (int i = 0; i < N; i++) {\n        if (a[i] == 0 && i != 0) {\n            vector<double> prob(N);\n            for (int j = 0; j < N; j++) {\n                prob[j] = T[j] + 1;\n            }\n            discrete_distribution<int> dist(prob.begin(), prob.end());\n            a[i] = dist(rng);\n        }\n        if (b[i] == 0 && i != 0) {\n            vector<double> prob(N);\n            for (int j = 0; j < N; j++) {\n                prob[j] = T[j] + 1;\n            }\n            discrete_distribution<int> dist(prob.begin(), prob.end());\n            b[i] = dist(rng);\n        }\n    }\n    \n    // Quick simulation function\n    auto simulate = [&](int maxSteps) {\n        vector<int> count(N, 0);\n        int curr = 0;\n        count[0]++;\n        \n        for (int step = 2; step <= maxSteps; step++) {\n            if (count[curr] & 1) {\n                curr = a[curr];\n            } else {\n                curr = b[curr];\n            }\n            count[curr]++;\n        }\n        \n        return count;\n    };\n    \n    // Do a limited number of improvement iterations\n    int simLen = min(20000, L);\n    \n    for (int iter = 0; iter < 100; iter++) {\n        auto counts = simulate(simLen);\n        \n        // Find employee with largest error\n        int maxError = 0;\n        int maxErrorEmp = -1;\n        double scale = (double)L / simLen;\n        \n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            int error = abs(projected - T[i]);\n            if (error > maxError) {\n                maxError = error;\n                maxErrorEmp = i;\n            }\n        }\n        \n        if (maxErrorEmp == -1 || maxError < 10) break;\n        \n        // Adjust transitions for this employee\n        int projected = (int)(counts[maxErrorEmp] * scale + 0.5);\n        \n        if (projected < T[maxErrorEmp]) {\n            // Need more visits to maxErrorEmp\n            // Find who's getting too many visits\n            int donor = -1;\n            int maxExcess = 0;\n            for (int i = 0; i < N; i++) {\n                int proj = (int)(counts[i] * scale + 0.5);\n                int excess = proj - T[i];\n                if (excess > maxExcess) {\n                    maxExcess = excess;\n                    donor = i;\n                }\n            }\n            \n            if (donor != -1) {\n                // Make donor point to maxErrorEmp\n                if (rng() % 2 == 0) {\n                    a[donor] = maxErrorEmp;\n                } else {\n                    b[donor] = maxErrorEmp;\n                }\n            }\n        } else {\n            // maxErrorEmp is getting too many visits\n            // Redirect some of its incoming edges\n            if (rng() % 2 == 0) {\n                // Find who needs more visits\n                int needMore = -1;\n                int maxDeficit = 0;\n                for (int i = 0; i < N; i++) {\n                    int proj = (int)(counts[i] * scale + 0.5);\n                    int deficit = T[i] - proj;\n                    if (deficit > maxDeficit) {\n                        maxDeficit = deficit;\n                        needMore = i;\n                    }\n                }\n                if (needMore != -1) {\n                    if (rng() % 2 == 0) {\n                        a[maxErrorEmp] = needMore;\n                    } else {\n                        b[maxErrorEmp] = needMore;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output solution\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n    double uncertainty;\n};\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    \n    UnionFind(int n) : parent(n), size(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (size[px] < size[py]) swap(px, py);\n        parent[py] = px;\n        size[px] += size[py];\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\ndouble dist(const City& a, const City& b) {\n    double dx = a.cx - b.cx;\n    double dy = a.cy - b.cy;\n    return sqrt(dx * dx + dy * dy);\n}\n\ndouble maxPossibleDist(const City& a, const City& b) {\n    double dx = max(abs(a.rx - b.lx), abs(a.lx - b.rx));\n    double dy = max(abs(a.ry - b.ly), abs(a.ly - b.ry));\n    return sqrt(dx * dx + dy * dy);\n}\n\nvector<pair<int, int>> query(const vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v});\n    }\n    return edges;\n}\n\n// K-means++ initialization for better initial centers\nvector<int> kMeansPlusPlus(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<int> centers;\n    vector<double> minDist(n, 1e9);\n    \n    // Choose first center randomly\n    centers.push_back(rand() % n);\n    \n    for (int i = 1; i < k; i++) {\n        // Update distances\n        for (int j = 0; j < n; j++) {\n            double d = dist(cities[j], cities[centers.back()]);\n            minDist[j] = min(minDist[j], d);\n        }\n        \n        // Choose next center with probability proportional to distance squared\n        double sum = 0;\n        for (int j = 0; j < n; j++) sum += minDist[j] * minDist[j];\n        \n        double r = (double)rand() / RAND_MAX * sum;\n        double cumSum = 0;\n        for (int j = 0; j < n; j++) {\n            cumSum += minDist[j] * minDist[j];\n            if (cumSum >= r) {\n                centers.push_back(j);\n                break;\n            }\n        }\n    }\n    \n    return centers;\n}\n\n// Balanced k-means clustering\nvector<vector<int>> balancedKMeans(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<vector<int>> clusters(k);\n    \n    // Initialize centers\n    vector<int> centerIds = kMeansPlusPlus(cities, k, targetSizes);\n    vector<pair<double, double>> centers(k);\n    for (int i = 0; i < k; i++) {\n        centers[i] = {cities[centerIds[i]].cx, cities[centerIds[i]].cy};\n    }\n    \n    // Assign cities to clusters with size constraints\n    for (int iter = 0; iter < 20; iter++) {\n        // Calculate distances to all centers\n        vector<vector<pair<double, int>>> distances(k);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < k; j++) {\n                double dx = cities[i].cx - centers[j].first;\n                double dy = cities[i].cy - centers[j].second;\n                double d = sqrt(dx * dx + dy * dy);\n                distances[j].push_back({d, i});\n            }\n        }\n        \n        // Sort by distance for each cluster\n        for (int i = 0; i < k; i++) {\n            sort(distances[i].begin(), distances[i].end());\n        }\n        \n        // Assign cities greedily with size constraints\n        clusters.assign(k, vector<int>());\n        vector<bool> assigned(n, false);\n        \n        for (int round = 0; round < n; round++) {\n            for (int c = 0; c < k; c++) {\n                if (clusters[c].size() >= targetSizes[c]) continue;\n                \n                for (auto [d, city] : distances[c]) {\n                    if (!assigned[city]) {\n                        clusters[c].push_back(city);\n                        assigned[city] = true;\n                        break;\n                    }\n                }\n                \n                if (clusters[c].size() >= targetSizes[c]) continue;\n            }\n        }\n        \n        // Update centers\n        for (int i = 0; i < k; i++) {\n            if (clusters[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : clusters[i]) {\n                cx += cities[city].cx;\n                cy += cities[city].cy;\n            }\n            centers[i] = {cx / clusters[i].size(), cy / clusters[i].size()};\n        }\n    }\n    \n    return clusters;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<City> cities(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        cities[i].uncertainty = sqrt((cities[i].rx - cities[i].lx) * (cities[i].rx - cities[i].lx) + \n                                    (cities[i].ry - cities[i].ly) * (cities[i].ry - cities[i].ly));\n    }\n    \n    // Use balanced k-means for initial grouping\n    vector<vector<int>> groups = balancedKMeans(cities, M, G);\n    \n    // Ensure exact group sizes\n    for (int i = 0; i < M; i++) {\n        while (groups[i].size() > G[i]) {\n            groups[(i + 1) % M].push_back(groups[i].back());\n            groups[i].pop_back();\n        }\n    }\n    \n    // Process each group to find MST\n    vector<vector<pair<int, int>>> groupEdges(M);\n    map<pair<int, int>, bool> knownEdges;  // Track which edges we know exactly\n    int queriesUsed = 0;\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L && queriesUsed < Q) {\n            // Query entire small group\n            auto edges = query(groups[g]);\n            groupEdges[g] = edges;\n            for (auto& e : edges) {\n                knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n            }\n            queriesUsed++;\n        } else {\n            // Smart querying for large groups\n            UnionFind uf(N);\n            set<pair<int, int>> mstEdges;\n            \n            // Priority queue for potential edges (estimated distance, u, v)\n            priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n            \n            // Add all potential edges\n            for (int i = 0; i < sz; i++) {\n                for (int j = i + 1; j < sz; j++) {\n                    double d = dist(cities[groups[g][i]], cities[groups[g][j]]);\n                    pq.push({d, groups[g][i], groups[g][j]});\n                }\n            }\n            \n            // Process edges and query when uncertain\n            while (!pq.empty() && mstEdges.size() < sz - 1) {\n                auto [d, u, v] = pq.top();\n                pq.pop();\n                \n                if (uf.connected(u, v)) continue;\n                \n                // Check if we know this edge\n                pair<int, int> edge = {min(u, v), max(u, v)};\n                \n                if (!knownEdges.count(edge) && queriesUsed < Q) {\n                    // Query a subset containing this edge and nearby cities\n                    vector<int> subset = {u, v};\n                    \n                    // Add nearby cities up to L\n                    vector<pair<double, int>> neighbors;\n                    for (int c : groups[g]) {\n                        if (c != u && c != v) {\n                            double d1 = dist(cities[u], cities[c]);\n                            double d2 = dist(cities[v], cities[c]);\n                            neighbors.push_back({min(d1, d2), c});\n                        }\n                    }\n                    sort(neighbors.begin(), neighbors.end());\n                    \n                    for (auto [d, c] : neighbors) {\n                        subset.push_back(c);\n                        if (subset.size() >= L) break;\n                    }\n                    \n                    if (subset.size() >= 2) {\n                        auto edges = query(subset);\n                        for (auto& e : edges) {\n                            knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n                            \n                            // Add to MST if it connects our components\n                            if (!uf.connected(e.first, e.second)) {\n                                uf.unite(e.first, e.second);\n                                mstEdges.insert({e.first, e.second});\n                            }\n                        }\n                        queriesUsed++;\n                    }\n                } else {\n                    // Use this edge if no cycle\n                    if (!uf.connected(u, v)) {\n                        uf.unite(u, v);\n                        mstEdges.insert({u, v});\n                    }\n                }\n            }\n            \n            // Ensure connectivity (failsafe)\n            if (mstEdges.size() < sz - 1) {\n                for (int i = 0; i < sz; i++) {\n                    for (int j = i + 1; j < sz; j++) {\n                        if (!uf.connected(groups[g][i], groups[g][j])) {\n                            uf.unite(groups[g][i], groups[g][j]);\n                            mstEdges.insert({groups[g][i], groups[g][j]});\n                            if (mstEdges.size() >= sz - 1) break;\n                        }\n                    }\n                    if (mstEdges.size() >= sz - 1) break;\n                }\n            }\n            \n            groupEdges[g] = vector<pair<int, int>>(mstEdges.begin(), mstEdges.end());\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int c : groups[g]) cout << c << \" \";\n        cout << endl;\n        for (auto& e : groupEdges[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int M = 40;\nconst int INF = 1e9;\n\nstruct Point {\n    int i, j;\n    bool operator==(const Point& other) const {\n        return i == other.i && j == other.j;\n    }\n};\n\nstruct Action {\n    char type, dir;\n};\n\nvector<Action> actions;\nset<pair<int,int>> blocks;\nPoint current;\nvector<Point> targets;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\nbool hasBlock(int i, int j) {\n    return blocks.count({i, j}) > 0;\n}\n\nPoint getNext(Point p, int dir) {\n    return {p.i + di[dir], p.j + dj[dir]};\n}\n\nPoint slideFrom(Point p, int dir) {\n    while (true) {\n        Point next = getNext(p, dir);\n        if (!inBounds(next.i, next.j) || hasBlock(next.i, next.j)) break;\n        p = next;\n    }\n    return p;\n}\n\nvoid addAction(char type, char dir) {\n    actions.push_back({type, dir});\n    \n    int d = 0;\n    for (int i = 0; i < 4; i++) {\n        if (dirs[i] == dir) {\n            d = i;\n            break;\n        }\n    }\n    \n    if (type == 'M') {\n        current = getNext(current, d);\n    } else if (type == 'S') {\n        current = slideFrom(current, d);\n    } else if (type == 'A') {\n        Point next = getNext(current, d);\n        if (hasBlock(next.i, next.j)) {\n            blocks.erase({next.i, next.j});\n        } else {\n            blocks.insert({next.i, next.j});\n        }\n    }\n}\n\n// BFS to find shortest path with current blocks\nvector<Action> findPath(Point start, Point target) {\n    if (start == target) return {};\n    \n    queue<pair<Point, vector<Action>>> q;\n    map<pair<int,int>, int> dist;\n    q.push({start, {}});\n    dist[{start.i, start.j}] = 0;\n    \n    while (!q.empty()) {\n        auto [p, path] = q.front();\n        q.pop();\n        \n        // Try moves\n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(p, d);\n            if (!inBounds(next.i, next.j) || hasBlock(next.i, next.j)) continue;\n            \n            if (!dist.count({next.i, next.j}) || dist[{next.i, next.j}] > path.size() + 1) {\n                dist[{next.i, next.j}] = path.size() + 1;\n                auto newPath = path;\n                newPath.push_back({'M', dirs[d]});\n                if (next == target) return newPath;\n                q.push({next, newPath});\n            }\n        }\n        \n        // Try slides\n        for (int d = 0; d < 4; d++) {\n            Point next = slideFrom(p, d);\n            if (next == p) continue;\n            \n            if (!dist.count({next.i, next.j}) || dist[{next.i, next.j}] > path.size() + 1) {\n                dist[{next.i, next.j}] = path.size() + 1;\n                auto newPath = path;\n                newPath.push_back({'S', dirs[d]});\n                if (next == target) return newPath;\n                q.push({next, newPath});\n            }\n        }\n    }\n    \n    return {};\n}\n\nvoid moveToTarget(Point target) {\n    // First try direct path\n    auto directPath = findPath(current, target);\n    \n    // Try to optimize with strategic block placement for sliding\n    vector<Action> bestPath = directPath;\n    \n    // Check if we can create efficient slide path\n    if (current.i == target.i || current.j == target.j) {\n        // Aligned - try to set up slide\n        int dir = -1;\n        Point blockPos;\n        \n        if (current.i == target.i) {\n            // Horizontal slide\n            if (current.j < target.j) {\n                dir = 2; // Right\n                blockPos = {target.i, target.j + 1};\n            } else {\n                dir = 3; // Left\n                blockPos = {target.i, target.j - 1};\n            }\n        } else {\n            // Vertical slide\n            if (current.i < target.i) {\n                dir = 1; // Down\n                blockPos = {target.i + 1, target.j};\n            } else {\n                dir = 0; // Up\n                blockPos = {target.i - 1, target.j};\n            }\n        }\n        \n        if (inBounds(blockPos.i, blockPos.j) && !hasBlock(blockPos.i, blockPos.j)) {\n            // Temporarily place block\n            blocks.insert({blockPos.i, blockPos.j});\n            Point slideEnd = slideFrom(current, dir);\n            \n            if (slideEnd == target) {\n                // Great! This works with just one slide\n                vector<Action> slidePath;\n                slidePath.push_back({'A', dirs[dir]}); // Place block\n                slidePath.push_back({'S', dirs[dir]}); // Slide\n                \n                if (slidePath.size() < bestPath.size()) {\n                    bestPath = slidePath;\n                }\n            }\n            \n            blocks.erase({blockPos.i, blockPos.j});\n        }\n    }\n    \n    // Execute best path\n    for (auto& action : bestPath) {\n        addAction(action.type, action.dir);\n        if (actions.size() >= 2 * N * M - 10) break;\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    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].i >> targets[i].j;\n    }\n    \n    current = targets[0];\n    \n    // Visit each target in order\n    for (int i = 1; i < m; i++) {\n        moveToTarget(targets[i]);\n        \n        // Remove blocks on target if any\n        if (hasBlock(targets[i].i, targets[i].j)) {\n            for (int d = 0; d < 4; d++) {\n                Point adj = getNext(current, d);\n                if (adj.i == targets[i].i && adj.j == targets[i].j) {\n                    addAction('A', dirs[d]);\n                    break;\n                }\n            }\n        }\n        \n        if (actions.size() >= 2 * N * M - 10) break;\n    }\n    \n    // Output actions\n    for (auto& action : actions) {\n        cout << action.type << \" \" << action.dir << \"\\n\";\n    }\n    \n    return 0;\n}"},"4":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n#include <set>\n\nusing namespace std;\n\nstruct Company {\n    int id;\n    int x, y, r;\n};\n\nstruct Rectangle {\n    int a, b, c, d;\n    \n    int area() const {\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(double px, double py) const {\n        return a < px && px < c && b < py && py < 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\nclass Solver {\nprivate:\n    int n;\n    vector<Company> companies;\n    vector<Rectangle> solution;\n    mt19937 rng;\n    \n    double calculate_satisfaction(int i) {\n        const auto& comp = companies[i];\n        const auto& rect = solution[i];\n        \n        if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) {\n            return 0.0;\n        }\n        \n        int s = rect.area();\n        if (s == 0) return 0.0;\n        \n        double ratio = min(comp.r, s) / (double)max(comp.r, s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool check_overlaps(const Rectangle& rect, int exclude_id = -1) {\n        for (int i = 0; i < n; i++) {\n            if (i == exclude_id) continue;\n            if (solution[i].area() > 0 && solution[i].overlaps(rect)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    Rectangle find_best_rectangle(int idx, int max_attempts = 100) {\n        const auto& comp = companies[idx];\n        int target_area = comp.r;\n        \n        Rectangle best_rect = {comp.x, comp.y, min(10000, comp.x + 1), min(10000, comp.y + 1)};\n        double best_score = 0;\n        \n        // Try to find rectangle with area close to target\n        int sqrt_area = sqrt(target_area);\n        \n        for (int attempt = 0; attempt < max_attempts; attempt++) {\n            int w, h;\n            \n            if (attempt < max_attempts / 2) {\n                // Try systematic sizes\n                double aspect_ratio = 1.0 + (attempt % 10) * 0.2;\n                w = sqrt(target_area * aspect_ratio);\n                h = target_area / max(1, w);\n            } else {\n                // Try random sizes\n                w = max(1, min(10000, (int)(sqrt_area * (0.5 + (rng() % 100) / 50.0))));\n                h = target_area / max(1, w);\n            }\n            \n            w = max(1, min(10000, w));\n            h = max(1, min(10000, h));\n            \n            // Try different positions that include the required point\n            for (int dx = 0; dx <= min(w - 1, comp.x); dx++) {\n                for (int dy = 0; dy <= min(h - 1, comp.y); dy++) {\n                    int a = comp.x - dx;\n                    int b = comp.y - dy;\n                    int c = min(10000, a + w);\n                    int d = min(10000, b + h);\n                    \n                    Rectangle rect = {a, b, c, d};\n                    \n                    if (!rect.contains(comp.x + 0.5, comp.y + 0.5)) continue;\n                    if (check_overlaps(rect, idx)) continue;\n                    \n                    int area = rect.area();\n                    double ratio = min(target_area, area) / (double)max(target_area, area);\n                    double score = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_rect = rect;\n                        if (score > 0.99) return best_rect;  // Good enough\n                    }\n                }\n            }\n        }\n        \n        return best_rect;\n    }\n    \n    void greedy_placement() {\n        // Sort companies by area (largest first)\n        vector<int> order(n);\n        for (int i = 0; i < n; i++) order[i] = i;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return companies[i].r > companies[j].r;\n        });\n        \n        // Initialize all rectangles to empty\n        for (int i = 0; i < n; i++) {\n            solution[i] = {0, 0, 0, 0};\n        }\n        \n        // Place rectangles greedily\n        for (int idx : order) {\n            solution[idx] = find_best_rectangle(idx);\n        }\n    }\n    \n    void local_optimization(int iterations) {\n        double total_score = 0;\n        for (int i = 0; i < n; i++) {\n            total_score += calculate_satisfaction(i);\n        }\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            int idx = rng() % n;\n            Rectangle old_rect = solution[idx];\n            \n            // Try to adjust the rectangle\n            Rectangle new_rect = old_rect;\n            int type = rng() % 8;\n            \n            switch(type) {\n                case 0: if (new_rect.a > 0) new_rect.a--; break;\n                case 1: if (new_rect.b > 0) new_rect.b--; break;\n                case 2: if (new_rect.c < 10000) new_rect.c++; break;\n                case 3: if (new_rect.d < 10000) new_rect.d++; break;\n                case 4: if (new_rect.a < new_rect.c - 1 && new_rect.a < companies[idx].x) new_rect.a++; break;\n                case 5: if (new_rect.b < new_rect.d - 1 && new_rect.b < companies[idx].y) new_rect.b++; break;\n                case 6: if (new_rect.c > new_rect.a + 1 && new_rect.c > companies[idx].x + 1) new_rect.c--; break;\n                case 7: if (new_rect.d > new_rect.b + 1 && new_rect.d > companies[idx].y + 1) new_rect.d--; break;\n            }\n            \n            // Check validity\n            if (!new_rect.contains(companies[idx].x + 0.5, companies[idx].y + 0.5)) continue;\n            if (check_overlaps(new_rect, idx)) continue;\n            \n            // Calculate score change\n            solution[idx] = new_rect;\n            double new_total = 0;\n            for (int i = 0; i < n; i++) {\n                new_total += calculate_satisfaction(i);\n            }\n            \n            if (new_total > total_score) {\n                total_score = new_total;\n            } else {\n                solution[idx] = old_rect;\n            }\n        }\n    }\n    \npublic:\n    Solver() : rng(chrono::steady_clock::now().time_since_epoch().count()) {}\n    \n    void solve() {\n        cin >> n;\n        companies.resize(n);\n        solution.resize(n);\n        \n        for (int i = 0; i < n; i++) {\n            companies[i].id = i;\n            cin >> companies[i].x >> companies[i].y >> companies[i].r;\n        }\n        \n        greedy_placement();\n        \n        // Local optimization with time limit\n        auto start_time = chrono::steady_clock::now();\n        const auto time_limit = chrono::milliseconds(4500);\n        \n        while (chrono::steady_clock::now() - start_time < time_limit) {\n            local_optimization(100);\n        }\n    }\n    \n    void output() {\n        for (const auto& rect : solution) {\n            cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    solver.output();\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500;\n\nint si, sj;\nint tile[N][N];\nint points[N][N];\nvector<pair<int,int>> tile_squares[MAX_TILES];\nint tile_value[MAX_TILES];\nset<int> tile_neighbors[MAX_TILES];\nint num_tiles;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n    \n    bool operator<(const State& other) const {\n        return score > other.score; // Max heap\n    }\n};\n\nvoid preprocess() {\n    num_tiles = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n            tile_squares[tile[i][j]].push_back({i, j});\n        }\n    }\n    \n    // Calculate tile values\n    for (int t = 0; t < num_tiles; t++) {\n        tile_value[t] = 0;\n        for (auto [i, j] : tile_squares[t]) {\n            tile_value[t] += points[i][j];\n        }\n    }\n    \n    // Find neighboring tiles\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int curr = tile[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int next = tile[ni][nj];\n                    if (next != curr) {\n                        tile_neighbors[curr].insert(next);\n                    }\n                }\n            }\n        }\n    }\n}\n\nint evaluate_position(const bitset<MAX_TILES>& visited, int curr_tile) {\n    int score = 0;\n    int unvisited_neighbors = 0;\n    \n    for (int neighbor : tile_neighbors[curr_tile]) {\n        if (!visited[neighbor]) {\n            score += tile_value[neighbor];\n            unvisited_neighbors++;\n        }\n    }\n    \n    return score + unvisited_neighbors * 10;\n}\n\nState beam_search(int beam_width = 25) {\n    vector<State> current, next;\n    \n    State initial;\n    initial.i = si;\n    initial.j = sj;\n    initial.score = points[si][sj];\n    initial.visited[tile[si][sj]] = true;\n    \n    current.push_back(initial);\n    \n    State best = initial;\n    \n    for (int depth = 0; depth < num_tiles && !current.empty(); depth++) {\n        next.clear();\n        \n        for (const State& state : current) {\n            if (state.score > best.score) {\n                best = state;\n            }\n            \n            vector<tuple<int, int, int, int>> moves; // priority, ni, nj, dir\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = state.i + di[d];\n                int nj = state.j + dj[d];\n                \n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                int next_tile = tile[ni][nj];\n                if (state.visited[next_tile]) continue;\n                \n                int priority = tile_value[next_tile] * 100;\n                \n                // Add bonus for connectivity\n                State temp = state;\n                temp.visited[next_tile] = true;\n                priority += evaluate_position(temp.visited, next_tile);\n                \n                moves.push_back({priority, ni, nj, d});\n            }\n            \n            sort(moves.rbegin(), moves.rend());\n            \n            // Take top moves\n            for (int k = 0; k < min(2, (int)moves.size()); k++) {\n                auto [priority, ni, nj, dir] = moves[k];\n                \n                State new_state = state;\n                new_state.i = ni;\n                new_state.j = nj;\n                new_state.path += dir_char[dir];\n                new_state.score += points[ni][nj];\n                new_state.visited[tile[ni][nj]] = true;\n                \n                next.push_back(new_state);\n            }\n        }\n        \n        // Keep top beam_width states\n        if (next.size() > beam_width) {\n            sort(next.begin(), next.end());\n            next.resize(beam_width);\n        }\n        \n        current = next;\n    }\n    \n    return best;\n}\n\nState greedy_walk(double randomness = 0.0, int lookahead = 2) {\n    State state;\n    state.i = si;\n    state.j = sj;\n    state.score = points[si][sj];\n    state.visited[tile[si][sj]] = true;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    while (true) {\n        vector<tuple<double, int, int, int>> candidates;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            double score = tile_value[next_tile];\n            \n            // Lookahead bonus\n            state.visited[next_tile] = true;\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!state.visited[neighbor]) {\n                    score += tile_value[neighbor] * 0.4;\n                    \n                    // Second level lookahead\n                    if (lookahead >= 2) {\n                        for (int neighbor2 : tile_neighbors[neighbor]) {\n                            if (!state.visited[neighbor2]) {\n                                score += tile_value[neighbor2] * 0.1;\n                            }\n                        }\n                    }\n                }\n            }\n            state.visited[next_tile] = false;\n            \n            candidates.push_back({score, ni, nj, d});\n        }\n        \n        if (candidates.empty()) break;\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        int choice = 0;\n        if (randomness > 0 && candidates.size() > 1) {\n            if (dis(gen) < randomness) {\n                choice = min(1 + (int)(dis(gen) * 2), (int)candidates.size() - 1);\n            }\n        }\n        \n        auto [score, ni, nj, dir] = candidates[choice];\n        \n        state.i = ni;\n        state.j = nj;\n        state.path += dir_char[dir];\n        state.score += points[ni][nj];\n        state.visited[tile[ni][nj]] = true;\n    }\n    \n    return state;\n}\n\nState local_optimization(State initial_state) {\n    // Try to extend the path from the end\n    State state = initial_state;\n    \n    bool improved = true;\n    while (improved) {\n        improved = false;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            state.i = ni;\n            state.j = nj;\n            state.path += dir_char[d];\n            state.score += points[ni][nj];\n            state.visited[next_tile] = true;\n            improved = true;\n            break;\n        }\n    }\n    \n    return state;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess();\n    \n    State best;\n    best.score = 0;\n    \n    auto start = chrono::high_resolution_clock::now();\n    \n    // Try beam search with different parameters\n    State beam1 = beam_search(20);\n    beam1 = local_optimization(beam1);\n    if (beam1.score > best.score) best = beam1;\n    \n    State beam2 = beam_search(30);\n    beam2 = local_optimization(beam2);\n    if (beam2.score > best.score) best = beam2;\n    \n    // Continue with randomized greedy approaches\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count();\n        if (elapsed > 1900) break;\n        \n        State s1 = greedy_walk(0.0, 2);\n        s1 = local_optimization(s1);\n        if (s1.score > best.score) best = s1;\n        \n        State s2 = greedy_walk(0.1, 2);\n        s2 = local_optimization(s2);\n        if (s2.score > best.score) best = s2;\n        \n        State s3 = greedy_walk(0.3, 1);\n        s3 = local_optimization(s3);\n        if (s3.score > best.score) best = s3;\n        \n        State s4 = greedy_walk(0.5, 1);\n        s4 = local_optimization(s4);\n        if (s4.score > best.score) best = s4;\n        \n        if (elapsed < 1000) {\n            State beam3 = beam_search(15);\n            beam3 = local_optimization(beam3);\n            if (beam3.score > best.score) best = beam3;\n        }\n    }\n    \n    cout << best.path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int QUERIES = 1000;\n\nstruct EdgeStats {\n    double sum = 0;\n    double sum_sq = 0;\n    int count = 0;\n    double estimate = 5000;\n    double min_seen = 1e9;\n    double max_seen = 0;\n    \n    void add_observation(double val) {\n        count++;\n        sum += val;\n        sum_sq += val * val;\n        min_seen = min(min_seen, val);\n        max_seen = max(max_seen, val);\n        \n        if (count == 1) {\n            estimate = val;\n        } else {\n            double mean = sum / count;\n            // Adaptive learning rate based on consistency\n            double variance = (sum_sq / count) - (mean * mean);\n            double consistency = 1.0 / (1.0 + variance / (mean * mean + 1));\n            \n            // Higher learning rate when observations are consistent\n            double lr = 0.2 + 0.5 * consistency;\n            lr = min(lr, 1.0 / sqrt(count));\n            \n            estimate = estimate * (1 - lr) + val * lr;\n        }\n        \n        // Keep in reasonable bounds\n        estimate = max(100.0, min(10000.0, estimate));\n    }\n    \n    double get_weight(bool optimistic = false, int phase = 0) const {\n        if (count == 0) return estimate;\n        \n        // In exploration phase, be optimistic for rarely visited edges\n        if (optimistic && count < 5) {\n            double mean = sum / count;\n            double std_dev = sqrt(max(0.0, (sum_sq / count) - mean * mean));\n            // Use lower confidence bound\n            return max(100.0, estimate - 0.5 * std_dev / sqrt(count + 1.0));\n        }\n        \n        return estimate;\n    }\n    \n    double get_variance() const {\n        if (count < 2) return 1e6;\n        double mean = sum / count;\n        return (sum_sq / count) - (mean * mean);\n    }\n};\n\nEdgeStats h_edges[N][N-1];\nEdgeStats v_edges[N-1][N];\n\n// Track patterns in rows/columns\ndouble row_base_estimate[N];\ndouble col_base_estimate[N];\nint row_samples[N] = {0};\nint col_samples[N] = {0};\n\nstruct State {\n    double dist;\n    int i, j;\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\npair<string, vector<pair<bool,pair<int,int>>>> dijkstra(int si, int sj, int ti, int tj, bool optimistic = false) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    \n    priority_queue<State, vector<State>, greater<State>> pq;\n    dist[si][sj] = 0;\n    pq.push({0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (d > dist[i][j] + 1e-9) continue;\n        if (i == ti && j == tj) break;\n        \n        // Try all directions\n        if (i > 0) {\n            double w = v_edges[i-1][j].get_weight(optimistic);\n            if (dist[i][j] + w < dist[i-1][j]) {\n                dist[i-1][j] = dist[i][j] + w;\n                prev[i-1][j] = {i, j};\n                pq.push({dist[i-1][j], i-1, j});\n            }\n        }\n        if (i < N-1) {\n            double w = v_edges[i][j].get_weight(optimistic);\n            if (dist[i][j] + w < dist[i+1][j]) {\n                dist[i+1][j] = dist[i][j] + w;\n                prev[i+1][j] = {i, j};\n                pq.push({dist[i+1][j], i+1, j});\n            }\n        }\n        if (j > 0) {\n            double w = h_edges[i][j-1].get_weight(optimistic);\n            if (dist[i][j] + w < dist[i][j-1]) {\n                dist[i][j-1] = dist[i][j] + w;\n                prev[i][j-1] = {i, j};\n                pq.push({dist[i][j-1], i, j-1});\n            }\n        }\n        if (j < N-1) {\n            double w = h_edges[i][j].get_weight(optimistic);\n            if (dist[i][j] + w < dist[i][j+1]) {\n                dist[i][j+1] = dist[i][j] + w;\n                prev[i][j+1] = {i, j};\n                pq.push({dist[i][j+1], i, j+1});\n            }\n        }\n    }\n    \n    // Reconstruct path and edge list\n    string path = \"\";\n    vector<pair<bool,pair<int,int>>> edges; // bool: true=horizontal, false=vertical\n    \n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto [pi, pj] = prev[ci][cj];\n        \n        if (pi == ci - 1) {\n            path += 'D';\n            edges.push_back({false, {pi, pj}});\n        } else if (pi == ci + 1) {\n            path += 'U';\n            edges.push_back({false, {ci, cj}});\n        } else if (pj == cj - 1) {\n            path += 'R';\n            edges.push_back({true, {pi, pj}});\n        } else if (pj == cj + 1) {\n            path += 'L';\n            edges.push_back({true, {ci, cj}});\n        }\n        \n        ci = pi; cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(edges.begin(), edges.end());\n    \n    return {path, edges};\n}\n\nvoid update_with_feedback(const vector<pair<bool,pair<int,int>>>& edges, int measured) {\n    if (edges.empty()) return;\n    \n    // Calculate total estimated length\n    double total_est = 0;\n    for (auto [is_horiz, pos] : edges) {\n        if (is_horiz) {\n            total_est += h_edges[pos.first][pos.second].estimate;\n        } else {\n            total_est += v_edges[pos.first][pos.second].estimate;\n        }\n    }\n    \n    if (total_est <= 0) return;\n    \n    // Account for noise: measured = actual * [0.9, 1.1]\n    // Best estimate of actual is around measured/1.0\n    // But we should be conservative\n    double ratio = measured / total_est;\n    \n    // Clamp ratio to reasonable bounds (accounting for noise)\n    ratio = max(0.8, min(1.2, ratio));\n    \n    // Update each edge\n    for (auto [is_horiz, pos] : edges) {\n        if (is_horiz) {\n            double new_estimate = h_edges[pos.first][pos.second].estimate * ratio;\n            h_edges[pos.first][pos.second].add_observation(new_estimate);\n            \n            // Update row pattern estimate\n            row_base_estimate[pos.first] = \n                (row_base_estimate[pos.first] * row_samples[pos.first] + new_estimate) / \n                (row_samples[pos.first] + 1);\n            row_samples[pos.first]++;\n        } else {\n            double new_estimate = v_edges[pos.first][pos.second].estimate * ratio;\n            v_edges[pos.first][pos.second].add_observation(new_estimate);\n            \n            // Update column pattern estimate  \n            col_base_estimate[pos.second] = \n                (col_base_estimate[pos.second] * col_samples[pos.second] + new_estimate) / \n                (col_samples[pos.second] + 1);\n            col_samples[pos.second]++;\n        }\n    }\n}\n\n// Apply pattern-based smoothing\nvoid apply_pattern_smoothing(int query_num) {\n    if (query_num < 100) return; // Don't smooth too early\n    \n    // Smooth horizontal edges within rows\n    for (int i = 0; i < N; i++) {\n        if (row_samples[i] < 5) continue;\n        \n        double base = row_base_estimate[i];\n        for (int j = 0; j < N-1; j++) {\n            if (h_edges[i][j].count > 0) {\n                // Gently pull towards row average\n                double pull_strength = 0.1 / (1.0 + h_edges[i][j].count / 10.0);\n                h_edges[i][j].estimate = \n                    h_edges[i][j].estimate * (1 - pull_strength) + base * pull_strength;\n            }\n        }\n    }\n    \n    // Smooth vertical edges within columns\n    for (int j = 0; j < N; j++) {\n        if (col_samples[j] < 5) continue;\n        \n        double base = col_base_estimate[j];\n        for (int i = 0; i < N-1; i++) {\n            if (v_edges[i][j].count > 0) {\n                double pull_strength = 0.1 / (1.0 + v_edges[i][j].count / 10.0);\n                v_edges[i][j].estimate = \n                    v_edges[i][j].estimate * (1 - pull_strength) + base * pull_strength;\n            }\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    // Initialize pattern estimates\n    fill(row_base_estimate, row_base_estimate + N, 5000);\n    fill(col_base_estimate, col_base_estimate + N, 5000);\n    \n    for (int query = 0; query < QUERIES; query++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        // Use optimistic exploration in early phase\n        bool use_optimistic = (query < 300);\n        \n        auto [path, edges] = dijkstra(si, sj, ti, tj, use_optimistic);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int measured_length;\n        cin >> measured_length;\n        \n        update_with_feedback(edges, measured_length);\n        \n        // Apply smoothing periodically\n        if (query > 0 && query % 50 == 0) {\n            apply_pattern_smoothing(query);\n        }\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\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<string> strings(m);\n    for (int i = 0; i < m; i++) {\n        cin >> strings[i];\n    }\n    \n    // Best solution tracking\n    vector<vector<char>> bestGrid(n, vector<char>(n, '.'));\n    int bestMatched = 0;\n    int bestDots = n * n;\n    \n    // Random number generator\n    mt19937 rng(42);\n    \n    // Try multiple random configurations\n    for (int attempt = 0; attempt < 50; attempt++) {\n        vector<vector<char>> grid(n, vector<char>(n, '.'));\n        \n        // Shuffle string order for this attempt\n        vector<int> order(m);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        \n        // Sort by length for first half of attempts, random for second half\n        if (attempt < 25) {\n            sort(order.begin(), order.end(), [&](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        }\n        \n        // Helper functions\n        auto canPlaceH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int col = (c + i) % n;\n                if (grid[r][col] != '.' && grid[r][col] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto canPlaceV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int row = (r + i) % n;\n                if (grid[row][c] != '.' && grid[row][c] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto placeH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[r][(c + i) % n] = s[i];\n            }\n        };\n        \n        auto placeV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[(r + i) % n][c] = s[i];\n            }\n        };\n        \n        // Place strings\n        vector<bool> placed(m, false);\n        \n        for (int idx : order) {\n            const string& s = strings[idx];\n            vector<tuple<int, int, int, int>> positions; // r, c, dir, overlap\n            \n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (canPlaceH(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[r][(c + i) % n] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 0, overlap});\n                    }\n                    if (canPlaceV(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[(r + i) % n][c] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 1, overlap});\n                    }\n                }\n            }\n            \n            if (!positions.empty()) {\n                // Choose position based on strategy\n                int choice;\n                if (attempt < 10) {\n                    // Max overlap\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = 0;\n                } else if (attempt < 20) {\n                    // Random from top positions\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = uniform_int_distribution<int>(0, min(3, (int)positions.size()-1))(rng);\n                } else {\n                    // Pure random\n                    choice = uniform_int_distribution<int>(0, positions.size()-1)(rng);\n                }\n                \n                auto [r, c, dir, overlap] = positions[choice];\n                if (dir == 0) {\n                    placeH(r, c, s);\n                } else {\n                    placeV(r, c, s);\n                }\n                placed[idx] = true;\n            }\n        }\n        \n        // Check all strings against final grid\n        int matched = 0;\n        for (const string& s : strings) {\n            bool found = false;\n            for (int r = 0; r < n && !found; r++) {\n                for (int c = 0; c < n && !found; c++) {\n                    // Check horizontal\n                    bool matchH = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[r][(c + i) % n] != s[i]) {\n                            matchH = false;\n                            break;\n                        }\n                    }\n                    if (matchH) {\n                        found = true;\n                        break;\n                    }\n                    \n                    // Check vertical\n                    bool matchV = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[(r + i) % n][c] != s[i]) {\n                            matchV = false;\n                            break;\n                        }\n                    }\n                    if (matchV) {\n                        found = true;\n                        break;\n                    }\n                }\n            }\n            if (found) matched++;\n        }\n        \n        // Count dots\n        int dots = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == '.') dots++;\n            }\n        }\n        \n        // Update best if better\n        if (matched > bestMatched || (matched == bestMatched && dots < bestDots)) {\n            bestGrid = grid;\n            bestMatched = matched;\n            bestDots = dots;\n        }\n    }\n    \n    // Fill remaining dots intelligently\n    map<char, int> freq;\n    for (const auto& s : strings) {\n        for (char c : s) {\n            freq[c]++;\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (bestGrid[i][j] == '.') {\n                // Look at neighbors\n                map<char, int> neighborFreq;\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (di == 0 && dj == 0) continue;\n                        int ni = (i + di + n) % n;\n                        int nj = (j + dj + n) % n;\n                        if (bestGrid[ni][nj] != '.') {\n                            neighborFreq[bestGrid[ni][nj]]++;\n                        }\n                    }\n                }\n                \n                if (!neighborFreq.empty()) {\n                    char best = 'A';\n                    int bestScore = -1;\n                    for (auto [c, cnt] : neighborFreq) {\n                        int score = cnt * 1000 + freq[c];\n                        if (score > bestScore) {\n                            bestScore = score;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                } else {\n                    // Use most frequent character\n                    char best = 'A';\n                    int maxF = 0;\n                    for (auto [c, f] : freq) {\n                        if (f > maxF) {\n                            maxF = f;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                }\n            }\n        }\n    }\n    \n    // Output the best grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestGrid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\nstring find_path_bfs(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return \"\";\n    \n    queue<pair<int,int>> q;\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    \n    q.push({si, sj});\n    parent[si][sj] = {-1, -1};\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k];\n            int nj = j + dj[k];\n            \n            if (is_road(ni, nj) && parent[ni][nj].first == -1 && !(ni == si && nj == sj)) {\n                parent[ni][nj] = {i, j};\n                parent_dir[ni][nj] = k;\n                q.push({ni, nj});\n                \n                if (ni == ei && nj == ej) {\n                    // Reconstruct path\n                    string path = \"\";\n                    int ci = ei, cj = ej;\n                    while (!(ci == si && cj == sj)) {\n                        path = dir[parent_dir[ci][cj]] + path;\n                        auto [pi, pj] = parent[ci][cj];\n                        ci = pi;\n                        cj = pj;\n                    }\n                    return path;\n                }\n            }\n        }\n    }\n    \n    return \"\";\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n    }\n    \n    // Find horizontal and vertical \"highways\" - rows/columns with many roads\n    vector<int> row_score(N, 0);\n    vector<int> col_score(N, 0);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j)) {\n                row_score[i]++;\n                col_score[j]++;\n            }\n        }\n    }\n    \n    // Create a simple tour that covers high-value rows and columns\n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    // Add waypoints for rows with good visibility\n    for (int i = 0; i < N; i += 3) {\n        if (row_score[i] >= N/4) {\n            // Find a good position in this row\n            for (int j = 0; j < N; j++) {\n                if (is_road(i, j)) {\n                    // Check if this position has good horizontal visibility\n                    int vis = 1;\n                    for (int jj = j-1; jj >= 0 && is_road(i, jj); jj--) vis++;\n                    for (int jj = j+1; jj < N && is_road(i, jj); jj++) vis++;\n                    \n                    if (vis >= N/4) {\n                        waypoints.push_back({i, j});\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Add waypoints for columns with good visibility\n    for (int j = 0; j < N; j += 3) {\n        if (col_score[j] >= N/4) {\n            // Find a good position in this column\n            for (int i = 0; i < N; i++) {\n                if (is_road(i, j)) {\n                    // Check if this position has good vertical visibility\n                    int vis = 1;\n                    for (int ii = i-1; ii >= 0 && is_road(ii, j); ii--) vis++;\n                    for (int ii = i+1; ii < N && is_road(ii, j); ii++) vis++;\n                    \n                    if (vis >= N/4) {\n                        waypoints.push_back({i, j});\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Check coverage and add more waypoints if needed\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    \n    auto mark_visible = [&](int i, int j) {\n        if (!is_road(i, j)) return;\n        covered[i][j] = true;\n        for (int jj = j-1; jj >= 0 && is_road(i, jj); jj--) covered[i][jj] = true;\n        for (int jj = j+1; jj < N && is_road(i, jj); jj++) covered[i][jj] = true;\n        for (int ii = i-1; ii >= 0 && is_road(ii, j); ii--) covered[ii][j] = true;\n        for (int ii = i+1; ii < N && is_road(ii, j); ii++) covered[ii][j] = true;\n    };\n    \n    for (auto [i, j] : waypoints) {\n        mark_visible(i, j);\n    }\n    \n    // Add additional waypoints for uncovered areas\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j) && !covered[i][j]) {\n                waypoints.push_back({i, j});\n                mark_visible(i, j);\n            }\n        }\n    }\n    \n    // Sort waypoints to minimize travel distance (simple TSP heuristic)\n    vector<pair<int,int>> tour;\n    vector<bool> used(waypoints.size(), false);\n    tour.push_back(waypoints[0]);\n    used[0] = true;\n    \n    for (int t = 1; t < waypoints.size(); t++) {\n        int best_idx = -1;\n        int best_dist = 1e9;\n        auto [ci, cj] = tour.back();\n        \n        for (int idx = 0; idx < waypoints.size(); idx++) {\n            if (!used[idx]) {\n                auto [ni, nj] = waypoints[idx];\n                int dist = abs(ni - ci) + abs(nj - cj);  // Manhattan distance heuristic\n                if (dist < best_dist) {\n                    best_dist = dist;\n                    best_idx = idx;\n                }\n            }\n        }\n        \n        if (best_idx != -1) {\n            tour.push_back(waypoints[best_idx]);\n            used[best_idx] = true;\n        }\n    }\n    \n    // Build the actual route\n    string route = \"\";\n    for (int t = 1; t < tour.size(); t++) {\n        string path = find_path_bfs(tour[t-1].first, tour[t-1].second, \n                                    tour[t].first, tour[t].second);\n        route += path;\n    }\n    \n    // Return to start\n    if (!tour.empty() && !(tour.back().first == si && tour.back().second == sj)) {\n        route += find_path_bfs(tour.back().first, tour.back().second, si, sj);\n    }\n    \n    cout << route << endl;\n    \n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> task_total(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> d[i][j];\n            task_total[i] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> dependents(N);\n    vector<vector<int>> dependencies(N);\n    vector<int> dep_count(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        dependents[u].push_back(v);\n        dependencies[v].push_back(u);\n        dep_count[v]++;\n    }\n    \n    // Calculate critical metrics for each task\n    vector<int> descendants(N, 0);\n    vector<int> max_chain(N, 0);\n    vector<bool> visited(N, false);\n    \n    function<pair<int,int>(int)> dfs = [&](int task) -> pair<int,int> {\n        if (visited[task]) return {descendants[task], max_chain[task]};\n        visited[task] = true;\n        \n        int desc = 0;\n        int chain = 0;\n        for (int dep : dependents[task]) {\n            auto [d, c] = dfs(dep);\n            desc += d + 1;\n            chain = max(chain, c);\n        }\n        descendants[task] = desc;\n        max_chain[task] = chain + 1;\n        return {desc, chain + 1};\n    };\n    \n    for (int i = 0; i < N; i++) {\n        if (!visited[i]) dfs(i);\n    }\n    \n    // Initialize skills with smart priors based on task distribution\n    double avg_task_req = 0;\n    for (int i = 0; i < N; i++) avg_task_req += task_total[i];\n    avg_task_req /= N;\n    \n    vector<vector<double>> skill_est(M, vector<double>(K));\n    vector<vector<double>> skill_min(M, vector<double>(K, 0));\n    vector<vector<double>> skill_max(M, vector<double>(K, 100));\n    \n    // Initialize with some variance to encourage exploration\n    mt19937 rng(42);\n    uniform_real_distribution<> init_dist(30, 50);\n    for (int m = 0; m < M; m++) {\n        for (int k = 0; k < K; k++) {\n            skill_est[m][k] = init_dist(rng);\n        }\n    }\n    \n    vector<int> completed_count(M, 0);\n    vector<double> member_efficiency(M, 1.0);\n    vector<set<pair<int,int>>> observations(M); // (task, actual_days)\n    \n    vector<int> task_state(N, -1);\n    vector<int> member_task(M, -1);\n    vector<int> start_day(M, 0);\n    vector<int> remaining_deps(N);\n    for (int i = 0; i < N; i++) remaining_deps[i] = dep_count[i];\n    \n    int day = 0;\n    int completed = 0;\n    int total_assigned = 0;\n    \n    while (completed < N && day < 1950) {\n        day++;\n        \n        // Adaptive strategy based on progress\n        double progress_rate = (double)completed / max(1, day);\n        double time_pressure = (double)day / 1950;\n        bool exploration_phase = (total_assigned < M * 5) || (day < 50 && completed_count[0] < 3);\n        \n        // Find available tasks\n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (task_state[i] == -1 && remaining_deps[i] == 0) {\n                available.push_back(i);\n            }\n        }\n        \n        // Priority scoring with adaptive weights\n        vector<pair<double, int>> task_priority;\n        for (int task : available) {\n            double score = 0;\n            \n            // Critical path weight increases with time pressure\n            score += max_chain[task] * (1000 + time_pressure * 1000);\n            \n            // Descendants weight\n            score += descendants[task] * (50 + time_pressure * 50);\n            \n            // Unlocking bonus - tasks that will unlock many others\n            int unlock_count = 0;\n            for (int succ : dependents[task]) {\n                if (remaining_deps[succ] == 1) unlock_count++;\n            }\n            score += unlock_count * 200;\n            \n            // Task difficulty penalty (prefer easier tasks under time pressure)\n            score -= task_total[task] * (0.5 + time_pressure);\n            \n            task_priority.push_back({score, task});\n        }\n        sort(task_priority.rbegin(), task_priority.rend());\n        \n        // Member-task assignment\n        vector<pair<int, int>> assignments;\n        vector<bool> used_member(M, false);\n        \n        for (auto [_, task] : task_priority) {\n            if (assignments.size() >= M) break;\n            \n            vector<pair<double, int>> member_scores;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1 || used_member[m]) continue;\n                \n                // Calculate expected completion time\n                double expected_w = 0;\n                int matching_skills = 0;\n                for (int k = 0; k < K; k++) {\n                    double gap = max(0.0, d[task][k] - skill_est[m][k]);\n                    expected_w += gap;\n                    if (d[task][k] > 0 && skill_est[m][k] >= d[task][k]) {\n                        matching_skills++;\n                    }\n                }\n                \n                double expected_time = (expected_w < 0.01) ? 1 : max(1.0, expected_w);\n                expected_time *= member_efficiency[m];\n                \n                double score = -expected_time * 100;\n                \n                // Skill match bonus\n                score += matching_skills * 10;\n                \n                // Exploration bonus in early game\n                if (exploration_phase) {\n                    if (completed_count[m] == 0) {\n                        score += 1000; // Strong bonus for untested members\n                    } else if (completed_count[m] < 5) {\n                        score += (5 - completed_count[m]) * 50;\n                    }\n                }\n                \n                // Confidence bonus - prefer members we know well for critical tasks\n                if (max_chain[task] > 10 && completed_count[m] > 10) {\n                    score += 20;\n                }\n                \n                // Workload balancing\n                double avg_completed = (double)completed / M;\n                if (completed_count[m] < avg_completed - 5) {\n                    score += (avg_completed - completed_count[m]) * 5;\n                }\n                \n                member_scores.push_back({score, m});\n            }\n            \n            if (!member_scores.empty()) {\n                sort(member_scores.rbegin(), member_scores.rend());\n                int best_member = member_scores[0].second;\n                \n                assignments.push_back({best_member, task});\n                used_member[best_member] = true;\n                member_task[best_member] = task;\n                start_day[best_member] = day;\n                task_state[task] = 0;\n                total_assigned++;\n            }\n        }\n        \n        // Output\n        cout << assignments.size();\n        for (auto [m, t] : assignments) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        // Read completions\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) break;\n        \n        for (int i = 0; i < n_completed; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int task = member_task[m];\n            if (task != -1) {\n                task_state[task] = 1;\n                completed++;\n                \n                int actual_days = day - start_day[m] + 1;\n                observations[m].insert({task, actual_days});\n                \n                for (int dep : dependents[task]) {\n                    remaining_deps[dep]--;\n                }\n                \n                // Update skill estimates with bounded updates\n                double lr = 0.4 / (1 + completed_count[m] * 0.03);\n                \n                if (actual_days == 1) {\n                    // Skills definitely meet all requirements\n                    for (int k = 0; k < K; k++) {\n                        skill_min[m][k] = max(skill_min[m][k], (double)d[task][k]);\n                        if (skill_est[m][k] < d[task][k]) {\n                            skill_est[m][k] = d[task][k] + 1;\n                        }\n                    }\n                } else {\n                    // Estimate w from actual_days\n                    double observed_w = actual_days; // Approximate, ignoring \u00b13 noise\n                    \n                    // Calculate current estimated w\n                    double current_w = 0;\n                    vector<double> gaps(K);\n                    int gap_count = 0;\n                    for (int k = 0; k < K; k++) {\n                        gaps[k] = max(0.0, d[task][k] - skill_est[m][k]);\n                        current_w += gaps[k];\n                        if (gaps[k] > 0) gap_count++;\n                    }\n                    \n                    if (current_w > 0.01 && gap_count > 0) {\n                        // Distribute the error proportionally\n                        double error = observed_w - current_w;\n                        \n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double adjustment = (gaps[k] / current_w) * error * lr;\n                                skill_est[m][k] -= adjustment;\n                                \n                                // Apply bounds\n                                skill_est[m][k] = max(skill_min[m][k], \n                                                     min(skill_max[m][k], skill_est[m][k]));\n                            }\n                        }\n                    }\n                    \n                    // Update efficiency estimate\n                    double expected_days = max(1.0, current_w);\n                    double efficiency_update = actual_days / expected_days;\n                    member_efficiency[m] = 0.9 * member_efficiency[m] + 0.1 * efficiency_update;\n                }\n                \n                // Re-estimate skills using all observations periodically\n                if (completed_count[m] % 10 == 9 && observations[m].size() > 5) {\n                    // Use gradient descent on all observations to refine estimates\n                    for (int iter = 0; iter < 5; iter++) {\n                        vector<double> gradient(K, 0);\n                        double total_error = 0;\n                        \n                        for (auto [t, act_days] : observations[m]) {\n                            double pred_w = 0;\n                            for (int k = 0; k < K; k++) {\n                                pred_w += max(0.0, d[t][k] - skill_est[m][k]);\n                            }\n                            double pred_days = (pred_w < 0.01) ? 1 : max(1.0, pred_w);\n                            double error = pred_days - act_days;\n                            total_error += error * error;\n                            \n                            if (pred_w > 0.01) {\n                                for (int k = 0; k < K; k++) {\n                                    if (d[t][k] > skill_est[m][k]) {\n                                        gradient[k] -= error * (1.0 / observations[m].size());\n                                    }\n                                }\n                            }\n                        }\n                        \n                        // Update with small step\n                        for (int k = 0; k < K; k++) {\n                            skill_est[m][k] += gradient[k] * 0.1;\n                            skill_est[m][k] = max(skill_min[m][k], \n                                                 min(skill_max[m][k], skill_est[m][k]));\n                        }\n                    }\n                }\n                \n                completed_count[m]++;\n                member_task[m] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n    double score;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    vector<Order> orders(1000);\n    \n    // Read all orders\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        orders[i].id = i + 1;\n        \n        // Score based on proximity to center and delivery distance\n        int dist_from_center_pickup = manhattan(400, 400, orders[i].ax, orders[i].ay);\n        int dist_from_center_delivery = manhattan(400, 400, orders[i].cx, orders[i].cy);\n        int delivery_dist = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n        \n        // Prefer orders close to center with reasonable delivery distances\n        orders[i].score = dist_from_center_pickup + dist_from_center_delivery + delivery_dist * 0.3;\n    }\n    \n    // Sort orders by score (lower is better)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    \n    // Select the best 50 orders\n    vector<int> selected_ids;\n    vector<pair<int, int>> pickups, deliveries;\n    \n    for (int i = 0; i < 50; i++) {\n        selected_ids.push_back(orders[i].id);\n        pickups.push_back({orders[i].ax, orders[i].ay});\n        deliveries.push_back({orders[i].cx, orders[i].cy});\n    }\n    \n    // Build route using greedy approach with preference for clearing deliveries\n    vector<pair<int, int>> route;\n    route.push_back({400, 400});\n    \n    vector<bool> picked(50, false);\n    vector<bool> delivered(50, false);\n    int num_delivered = 0;\n    \n    while (num_delivered < 50) {\n        int cur_x = route.back().first;\n        int cur_y = route.back().second;\n        \n        int best_dist = INT_MAX;\n        int best_idx = -1;\n        bool best_is_pickup = false;\n        \n        // Count how many items we're currently carrying\n        int carrying = 0;\n        for (int i = 0; i < 50; i++) {\n            if (picked[i] && !delivered[i]) carrying++;\n        }\n        \n        // If carrying many items, prioritize deliveries\n        double delivery_weight = (carrying > 10) ? 0.7 : 1.0;\n        \n        // Consider pickups\n        for (int i = 0; i < 50; i++) {\n            if (picked[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, pickups[i].first, pickups[i].second);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = i;\n                best_is_pickup = true;\n            }\n        }\n        \n        // Consider deliveries for items we're carrying\n        for (int i = 0; i < 50; i++) {\n            if (!picked[i] || delivered[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, deliveries[i].first, deliveries[i].second);\n            int weighted_dist = dist * delivery_weight;\n            \n            if (weighted_dist < best_dist) {\n                best_dist = weighted_dist;\n                best_idx = i;\n                best_is_pickup = false;\n            }\n        }\n        \n        if (best_is_pickup) {\n            route.push_back(pickups[best_idx]);\n            picked[best_idx] = true;\n        } else {\n            route.push_back(deliveries[best_idx]);\n            delivered[best_idx] = true;\n            num_delivered++;\n        }\n    }\n    \n    // Return to office\n    route.push_back({400, 400});\n    \n    // Output\n    cout << \"50\";\n    for (int id : selected_ids) {\n        cout << \" \" << id;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        \n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n    \n    int getComponents() {\n        return components;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const 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<pair<int, int>> edges(M);\n    vector<int> distances(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n        int dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        int dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        distances[i] = round(sqrt(dx * dx + dy * dy));\n    }\n    \n    UnionFind uf(N);\n    int edges_accepted = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n        \n        int u = edges[i].first;\n        int v = edges[i].second;\n        int d_i = distances[i];\n        \n        int decision = 0;\n        \n        if (!uf.connected(u, v)) {\n            // Edge connects different components\n            double ratio = (double)l_i / d_i;\n            int remaining_edges = M - i - 1;\n            int edges_needed = uf.getComponents() - 1;\n            \n            // Be selective only if we have plenty of edges left\n            if (edges_needed > 0 && remaining_edges > edges_needed * 3 && ratio > 2.8) {\n                // Very bad edge and we have plenty of opportunities left\n                decision = 0;\n            } else {\n                // Accept the edge - either it's good enough or we need it for connectivity\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            }\n        }\n        // Reject edges that would create cycles (already connected)\n        \n        cout << decision << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Position& other) const {\n        return x < other.x || (x == other.x && y < other.y);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> walls;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dirChar[4] = {'U', 'D', 'L', 'R'};\n    const char blockChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) const {\n        return x >= 1 && x <= GRID_SIZE && y >= 1 && y <= GRID_SIZE;\n    }\n    \n    bool canMakeWall(int x, int y) const {\n        if (!isValid(x, y) || walls[x][y]) return false;\n        \n        // Check no pets or humans at this position\n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return false;\n        }\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        // Check no pets adjacent to this position\n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny)) {\n                for (const auto& p : petPos) {\n                    if (p.x == nx && p.y == ny) return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    int manhattanDist(int x1, int y1, int x2, int y2) const {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    double getMinPetDistance(int x, int y) const {\n        double minDist = 1e9;\n        for (const auto& p : petPos) {\n            minDist = min(minDist, (double)manhattanDist(x, y, p.x, p.y));\n        }\n        return minDist;\n    }\n    \n    Position findGatheringPoint() const {\n        // Find best corner or edge position\n        vector<pair<Position, int>> candidates;\n        \n        // Add corners\n        candidates.push_back({{3, 3}, 100});\n        candidates.push_back({{3, 28}, 100});\n        candidates.push_back({{28, 3}, 100});\n        candidates.push_back({{28, 28}, 100});\n        \n        // Add edge centers\n        candidates.push_back({{3, 15}, 50});\n        candidates.push_back({{28, 15}, 50});\n        candidates.push_back({{15, 3}, 50});\n        candidates.push_back({{15, 28}, 50});\n        \n        Position best = {15, 15};\n        double bestScore = -1e9;\n        \n        for (const auto& [pos, bonus] : candidates) {\n            double score = bonus;\n            \n            // Distance from pets\n            for (const auto& p : petPos) {\n                int dist = manhattanDist(pos.x, pos.y, p.x, p.y);\n                if (petType[p.x - 1] == 4) { // Dog - weight more\n                    score += dist * 3;\n                } else {\n                    score += dist;\n                }\n            }\n            \n            // Distance from humans (negative to attract)\n            for (const auto& h : humanPos) {\n                score -= manhattanDist(pos.x, pos.y, h.x, h.y);\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                best = pos;\n            }\n        }\n        \n        return best;\n    }\n    \npublic:\n    void solve() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n        }\n        \n        walls.assign(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        \n        for (int turn = 0; turn < MAX_TURNS; turn++) {\n            string actions(M, '.');\n            Position gatherPoint = findGatheringPoint();\n            \n            // First pass: decide on wall building\n            set<Position> wallsToBuild;\n            vector<bool> buildingWall(M, false);\n            \n            for (int i = 0; i < M; i++) {\n                const Position& human = humanPos[i];\n                \n                // Skip wall building in very early game\n                if (turn < 20) continue;\n                \n                // Try to build walls\n                int bestDir = -1;\n                double bestScore = -1e9;\n                \n                for (int d = 0; d < 4; d++) {\n                    int wx = human.x + dx[d];\n                    int wy = human.y + dy[d];\n                    \n                    if (canMakeWall(wx, wy) && !wallsToBuild.count({wx, wy})) {\n                        double score = 0;\n                        \n                        // Distance from pets\n                        score += getMinPetDistance(wx, wy) * 2;\n                        \n                        // Connect to existing walls\n                        int wallCount = 0;\n                        for (int dd = 0; dd < 4; dd++) {\n                            int nwx = wx + dx[dd];\n                            int nwy = wy + dy[dd];\n                            if (isValid(nwx, nwy) && walls[nwx][nwy]) {\n                                wallCount++;\n                            }\n                        }\n                        score += wallCount * 10;\n                        \n                        // Build on perimeter\n                        if (manhattanDist(wx, wy, gatherPoint.x, gatherPoint.y) >= 3 && \n                            manhattanDist(wx, wy, gatherPoint.x, gatherPoint.y) <= 5) {\n                            score += 20;\n                        }\n                        \n                        if (score > bestScore && score > 5) {\n                            bestScore = score;\n                            bestDir = d;\n                        }\n                    }\n                }\n                \n                if (bestDir != -1) {\n                    int wx = human.x + dx[bestDir];\n                    int wy = human.y + dy[bestDir];\n                    actions[i] = blockChar[bestDir];\n                    wallsToBuild.insert({wx, wy});\n                    buildingWall[i] = true;\n                }\n            }\n            \n            // Second pass: decide on movement for those not building walls\n            for (int i = 0; i < M; i++) {\n                if (buildingWall[i]) continue;\n                \n                const Position& human = humanPos[i];\n                \n                // Early game: move towards gathering point\n                if (turn < 60) {\n                    int dist = manhattanDist(human.x, human.y, gatherPoint.x, gatherPoint.y);\n                    if (dist > 3) {\n                        int bestDir = -1;\n                        int minDist = dist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            \n                            // Check if we can move there\n                            if (isValid(nx, ny) && !walls[nx][ny] && !wallsToBuild.count({nx, ny})) {\n                                int newDist = manhattanDist(nx, ny, gatherPoint.x, gatherPoint.y);\n                                if (newDist < minDist) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                            continue;\n                        }\n                    }\n                }\n                \n                // Escape from pets if too close\n                double minPetDist = getMinPetDistance(human.x, human.y);\n                if (minPetDist <= 2) {\n                    int bestDir = -1;\n                    double maxDist = minPetDist;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = human.x + dx[d];\n                        int ny = human.y + dy[d];\n                        \n                        if (isValid(nx, ny) && !walls[nx][ny] && !wallsToBuild.count({nx, ny})) {\n                            double newDist = getMinPetDistance(nx, ny);\n                            if (newDist > maxDist) {\n                                maxDist = newDist;\n                                bestDir = d;\n                            }\n                        }\n                    }\n                    \n                    if (bestDir != -1) {\n                        actions[i] = dirChar[bestDir];\n                    }\n                }\n            }\n            \n            cout << actions << endl;\n            cout.flush();\n            \n            // Parse actual walls being built from final actions\n            set<Position> actualWallsBuilt;\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = humanPos[i].x + dx[d];\n                            int wy = humanPos[i].y + dy[d];\n                            if (isValid(wx, wy)) {\n                                actualWallsBuilt.insert({wx, wy});\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Apply human actions\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                Position& human = humanPos[i];\n                \n                if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    for (int d = 0; d < 4; d++) {\n                        if (dirChar[d] == action) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            // Check against actual walls being built this turn\n                            if (isValid(nx, ny) && !walls[nx][ny] && !actualWallsBuilt.count({nx, ny})) {\n                                human.x = nx;\n                                human.y = ny;\n                            }\n                            break;\n                        }\n                    }\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            if (isValid(wx, wy)) {\n                                walls[wx][wy] = true;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Read pet movements\n            for (int i = 0; i < N; i++) {\n                string petMove;\n                cin >> petMove;\n                \n                for (char c : petMove) {\n                    if (c != '.') {\n                        for (int d = 0; d < 4; d++) {\n                            if (dirChar[d] == c) {\n                                petPos[i].x += dx[d];\n                                petPos[i].y += dy[d];\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    // Build wall information\n    vector<vector<bool>> canGoRight(20, vector<bool>(20, false));\n    vector<vector<bool>> canGoDown(20, vector<bool>(20, false));\n    \n    for (int i = 0; i < 20; i++) {\n        for (int j = 0; j < 19; j++) {\n            if (h[i][j] == '0') {\n                canGoRight[i][j] = true;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 19; i++) {\n        for (int j = 0; j < 20; j++) {\n            if (v[i][j] == '0') {\n                canGoDown[i][j] = true;\n            }\n        }\n    }\n    \n    // BFS to find shortest path\n    queue<pair<int,int>> q;\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> parent(20, vector<pair<int,int>>(20, {-1, -1}));\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        // Check all 4 directions\n        if (j < 19 && canGoRight[i][j] && dist[i][j+1] == -1) {\n            dist[i][j+1] = dist[i][j] + 1;\n            parent[i][j+1] = {i, j};\n            q.push({i, j+1});\n        }\n        if (j > 0 && canGoRight[i][j-1] && dist[i][j-1] == -1) {\n            dist[i][j-1] = dist[i][j] + 1;\n            parent[i][j-1] = {i, j};\n            q.push({i, j-1});\n        }\n        if (i < 19 && canGoDown[i][j] && dist[i+1][j] == -1) {\n            dist[i+1][j] = dist[i][j] + 1;\n            parent[i+1][j] = {i, j};\n            q.push({i+1, j});\n        }\n        if (i > 0 && canGoDown[i-1][j] && dist[i-1][j] == -1) {\n            dist[i-1][j] = dist[i][j] + 1;\n            parent[i-1][j] = {i, j};\n            q.push({i-1, j});\n        }\n    }\n    \n    // Reconstruct shortest path\n    string shortestPath;\n    int ci = ti, cj = tj;\n    vector<pair<int,int>> pathCoords;\n    \n    while (ci != si || cj != sj) {\n        pathCoords.push_back({ci, cj});\n        auto [pi, pj] = parent[ci][cj];\n        \n        // Determine the move\n        if (ci - pi == 1) shortestPath = \"D\" + shortestPath;\n        else if (ci - pi == -1) shortestPath = \"U\" + shortestPath;\n        else if (cj - pj == 1) shortestPath = \"R\" + shortestPath;\n        else if (cj - pj == -1) shortestPath = \"L\" + shortestPath;\n        \n        ci = pi;\n        cj = pj;\n    }\n    \n    // Strategy: repeat each move based on p value to ensure robustness\n    string result;\n    int baseRepeat = 1;\n    \n    // Adjust repetition based on p\n    if (p >= 0.4) baseRepeat = 3;\n    else if (p >= 0.3) baseRepeat = 2;\n    else if (p >= 0.2) baseRepeat = 2;\n    else baseRepeat = 1;\n    \n    // First, add the path with repetitions for each move\n    for (char move : shortestPath) {\n        for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n            result += move;\n        }\n    }\n    \n    // If we have space left, repeat the entire path for extra robustness\n    int pathLen = shortestPath.length() * baseRepeat;\n    while (result.length() + pathLen <= 200) {\n        for (char move : shortestPath) {\n            for (int r = 0; r < baseRepeat && result.length() < 200; r++) {\n                result += move;\n            }\n        }\n    }\n    \n    // Fill remaining space with the shortest path\n    int idx = 0;\n    while (result.length() < 200 && result.length() < 200) {\n        result += shortestPath[idx % shortestPath.length()];\n        idx++;\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint rotations[N][N];\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nint rotate_tile(int tile) {\n    if (tile <= 3) return (tile + 1) % 4;\n    if (tile == 4) return 5;\n    if (tile == 5) return 4;\n    if (tile == 6) return 7;\n    return 6;\n}\n\nint get_tile_state(int i, int j) {\n    int t = tiles[i][j];\n    for (int r = 0; r < rotations[i][j]; r++) {\n        t = rotate_tile(t);\n    }\n    return t;\n}\n\nint trace_path(int si, int sj, int sd, vector<vector<vector<bool>>>& visited) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;\n        \n        int tile_state = get_tile_state(i, j);\n        int d2 = to[tile_state][d];\n        if (d2 == -1) return 0;\n        \n        int ni = i + di[d2];\n        int nj = j + dj[d2];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return 0;\n        \n        i = ni;\n        j = nj;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (length > N * N * 4) return 0; // Prevent infinite loops\n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\nvector<int> find_all_loops() {\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    vector<int> loops;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = trace_path(i, j, d, visited);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    // Mark all positions in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ci][cj][cd] = true;\n                        int tile_state = get_tile_state(ci, cj);\n                        int d2 = to[tile_state][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    return loops;\n}\n\nint calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    sort(loops.rbegin(), loops.rend());\n    return loops[0] * loops[1];\n}\n\n// Try to connect tiles greedily\nvoid greedy_init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; r++) {\n                rotations[i][j] = r;\n                int connections = 0;\n                int tile_state = get_tile_state(i, j);\n                \n                // Count valid connections to neighbors\n                for (int d = 0; d < 4; d++) {\n                    int d2 = to[tile_state][d];\n                    if (d2 == -1) continue;\n                    \n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    \n                    int neighbor_state = get_tile_state(ni, nj);\n                    int return_dir = (d2 + 2) % 4;\n                    if (to[neighbor_state][return_dir] != -1) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rotations[i][j] = best_rot;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rot_dist(0, 3);\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    // Start with greedy initialization\n    greedy_init();\n    \n    int best_score = calculate_score();\n    int best_rotations[N][N];\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    auto start_time = chrono::steady_clock::now();\n    int iteration = 0;\n    int no_improve = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        iteration++;\n        \n        // Multi-restart strategy\n        if (no_improve > 10000) {\n            // Random restart\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n            no_improve = 0;\n        }\n        \n        // Try different neighborhood moves\n        int move_type = rng() % 3;\n        vector<pair<pair<int,int>, int>> changes;\n        \n        if (move_type == 0) {\n            // Single tile change\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            int old_rot = rotations[i][j];\n            int new_rot = rot_dist(rng);\n            if (new_rot == old_rot) continue;\n            changes.push_back({{i, j}, old_rot});\n            rotations[i][j] = new_rot;\n        } else if (move_type == 1) {\n            // Change 2x2 block\n            int i = rng() % (N-1);\n            int j = rng() % (N-1);\n            for (int di = 0; di < 2; di++) {\n                for (int dj = 0; dj < 2; dj++) {\n                    changes.push_back({{i+di, j+dj}, rotations[i+di][j+dj]});\n                    rotations[i+di][j+dj] = rot_dist(rng);\n                }\n            }\n        } else {\n            // Change a row or column\n            if (rng() % 2 == 0) {\n                int i = pos_dist(rng);\n                for (int j = 0; j < N; j++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            } else {\n                int j = pos_dist(rng);\n                for (int i = 0; i < N; i++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n        }\n        \n        int new_score = calculate_score();\n        \n        if (new_score > best_score) {\n            best_score = new_score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n            no_improve = 0;\n        } else {\n            // Revert changes with some probability\n            double temp = max(1.0, 50.0 * (1.0 - iteration / 100000.0));\n            if (prob_dist(rng) >= exp((new_score - best_score) / temp)) {\n                for (auto& [pos, old_val] : changes) {\n                    rotations[pos.first][pos.second] = old_val;\n                }\n            }\n            no_improve++;\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\npair<int, int> empty_pos;\nvector<char> answer;\nmt19937 rng(42);\n\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int opposite_dir[] = {1, 0, 3, 2};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n                return;\n            }\n        }\n    }\n}\n\nvoid make_move(int dir) {\n    int nx = empty_pos.first + dx[dir];\n    int ny = empty_pos.second + dy[dir];\n    if (in_bounds(nx, ny)) {\n        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        empty_pos = {nx, ny};\n        answer.push_back(dir_char[dir]);\n    }\n}\n\nstruct UnionFind {\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    int get_size(int x) { return size[find(x)]; }\n};\n\nint get_tree_size() {\n    // Map positions to indices\n    map<pair<int,int>, int> pos_to_id;\n    int id = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != 0) {\n                pos_to_id[{i,j}] = id++;\n            }\n        }\n    }\n    \n    if (id == 0) return 0;\n    \n    UnionFind uf(id);\n    vector<set<int>> adj(id);\n    int edge_count = 0;\n    \n    // Build graph\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 cur_id = pos_to_id[{i,j}];\n            \n            // Check down\n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    int next_id = pos_to_id[{i+1,j}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n            \n            // Check right\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    int next_id = pos_to_id[{i,j+1}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find largest tree (connected component without cycles)\n    int max_tree = 0;\n    map<int, vector<int>> components;\n    for (int i = 0; i < id; i++) {\n        components[uf.find(i)].push_back(i);\n    }\n    \n    for (auto& [root, comp] : components) {\n        int comp_edges = 0;\n        set<pair<int,int>> counted;\n        for (int v : comp) {\n            for (int u : adj[v]) {\n                if (counted.insert({min(u,v), max(u,v)}).second) {\n                    comp_edges++;\n                }\n            }\n        }\n        \n        // It's a tree if edges = vertices - 1\n        if (comp_edges == (int)comp.size() - 1) {\n            max_tree = max(max_tree, (int)comp.size());\n        }\n    }\n    \n    return max_tree;\n}\n\n// BFS to move empty square to target position\nvector<int> move_empty_to(pair<int,int> target) {\n    if (empty_pos == target) return {};\n    \n    queue<pair<pair<int,int>, vector<int>>> q;\n    set<pair<int,int>> visited;\n    q.push({empty_pos, {}});\n    visited.insert(empty_pos);\n    \n    while (!q.empty()) {\n        auto [pos, path] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = pos.first + dx[dir];\n            int ny = pos.second + dy[dir];\n            if (!in_bounds(nx, ny) || visited.count({nx, ny})) continue;\n            \n            vector<int> new_path = path;\n            new_path.push_back(dir);\n            \n            if (make_pair(nx, ny) == target) {\n                return new_path;\n            }\n            \n            visited.insert({nx, ny});\n            q.push({{nx, ny}, new_path});\n        }\n    }\n    return {};\n}\n\n// Evaluate board state\ndouble evaluate_board() {\n    int tree_size = get_tree_size();\n    int connected_edges = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    connected_edges++;\n                }\n            }\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    connected_edges++;\n                }\n            }\n        }\n    }\n    \n    return tree_size * 1000.0 + connected_edges;\n}\n\nvoid solve() {\n    int best_tree = get_tree_size();\n    auto best_board = board;\n    auto best_empty = empty_pos;\n    int stagnation = 0;\n    \n    while (answer.size() < T * 0.95 && best_tree < N * N - 1) {\n        double temp = 1.0 - (double)answer.size() / T;\n        \n        if (stagnation > 50) {\n            // Strategic restart: try to connect largest components\n            int depth = min(5, (int)(T - answer.size()) / 10);\n            \n            // Try multiple random sequences and pick the best\n            auto save_board = board;\n            auto save_empty = empty_pos;\n            int save_ans_size = answer.size();\n            \n            double best_eval = evaluate_board();\n            vector<int> best_moves;\n            \n            for (int attempt = 0; attempt < 10; attempt++) {\n                board = save_board;\n                empty_pos = save_empty;\n                vector<int> moves;\n                \n                for (int m = 0; m < depth; m++) {\n                    vector<int> dirs;\n                    for (int d = 0; d < 4; d++) {\n                        if (in_bounds(empty_pos.first + dx[d], empty_pos.second + dy[d])) {\n                            if (moves.empty() || d != opposite_dir[moves.back()]) {\n                                dirs.push_back(d);\n                            }\n                        }\n                    }\n                    if (!dirs.empty()) {\n                        int dir = dirs[rng() % dirs.size()];\n                        moves.push_back(dir);\n                        int nx = empty_pos.first + dx[dir];\n                        int ny = empty_pos.second + dy[dir];\n                        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                        empty_pos = {nx, ny};\n                    }\n                }\n                \n                double eval = evaluate_board();\n                if (eval > best_eval) {\n                    best_eval = eval;\n                    best_moves = moves;\n                }\n            }\n            \n            board = save_board;\n            empty_pos = save_empty;\n            for (int dir : best_moves) {\n                make_move(dir);\n            }\n            \n            stagnation = 0;\n        }\n        \n        // Try deeper lookahead\n        int lookahead = min(3, (int)(T - answer.size()) / 20);\n        \n        function<pair<double, vector<int>>(int, int, vector<int>&)> search = \n            [&](int depth, int last_dir, vector<int>& path) -> pair<double, vector<int>> {\n            \n            if (depth == 0) {\n                return {evaluate_board(), path};\n            }\n            \n            double best_score = -1e9;\n            vector<int> best_path;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                if (last_dir != -1 && dir == opposite_dir[last_dir]) continue;\n                \n                int nx = empty_pos.first + dx[dir];\n                int ny = empty_pos.second + dy[dir];\n                if (!in_bounds(nx, ny)) continue;\n                \n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                auto old_empty = empty_pos;\n                empty_pos = {nx, ny};\n                path.push_back(dir);\n                \n                auto [score, sub_path] = search(depth - 1, dir, path);\n                \n                if (score > best_score || \n                    (score == best_score && (rng() % 100) < temp * 50)) {\n                    best_score = score;\n                    best_path = sub_path;\n                }\n                \n                path.pop_back();\n                empty_pos = old_empty;\n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n            }\n            \n            return {best_score, best_path};\n        };\n        \n        vector<int> empty_path;\n        auto [score, path] = search(lookahead, -1, empty_path);\n        \n        if (!path.empty()) {\n            make_move(path[0]);\n            \n            int new_tree = get_tree_size();\n            if (new_tree > best_tree) {\n                best_tree = new_tree;\n                best_board = board;\n                best_empty = empty_pos;\n                stagnation = 0;\n            } else {\n                stagnation++;\n            }\n        } else {\n            stagnation++;\n        }\n    }\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            if (line[j] >= '0' && line[j] <= '9') {\n                board[i][j] = line[j] - '0';\n            } else {\n                board[i][j] = line[j] - 'a' + 10;\n            }\n        }\n    }\n    \n    find_empty();\n    solve();\n    \n    for (char c : answer) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst double RADIUS = 10000.0;\nconst double EPS = 1e-9;\nconst double TIME_LIMIT = 2.8;\n\nstruct Point {\n    double x, y;\n    Point(double x = 0, double y = 0) : x(x), y(y) {}\n    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }\n    double cross(const Point& p) const { return x * p.y - y * p.x; }\n    double norm2() const { return x * x + y * y; }\n};\n\nstruct Line {\n    int px, py, qx, qy;\n    Line(int px = 0, int py = 0, int qx = 0, int qy = 0) : px(px), py(py), qx(qx), qy(qy) {}\n    \n    int side(const Point& p) const {\n        double dx1 = qx - px;\n        double dy1 = qy - py;\n        double dx2 = p.x - px;\n        double dy2 = p.y - py;\n        double v = dx1 * dy2 - dy1 * dx2;\n        if (v > EPS) return 1;\n        if (v < -EPS) return -1;\n        return 0;\n    }\n};\n\nint N, K;\nvector<int> a(11);\nvector<Point> strawberries;\nvector<Line> lines;\nvector<Line> bestLines;\nint bestScore = 0;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool insideCircle(const Point& p) {\n    return p.norm2() < RADIUS * RADIUS - EPS;\n}\n\nint calculateScore() {\n    // Calculate region for each strawberry\n    map<vector<int>, int> regionCount;\n    \n    for (int i = 0; i < N; i++) {\n        if (!insideCircle(strawberries[i])) continue;\n        \n        vector<int> sideVector;\n        bool onLine = false;\n        \n        for (const Line& line : lines) {\n            int s = line.side(strawberries[i]);\n            if (s == 0) {\n                onLine = true;\n                break;\n            }\n            sideVector.push_back(s);\n        }\n        \n        if (!onLine) {\n            regionCount[sideVector]++;\n        }\n    }\n    \n    // Count pieces with each number of strawberries\n    vector<int> b(11, 0);\n    for (auto& [region, cnt] : regionCount) {\n        if (cnt <= 10) b[cnt]++;\n    }\n    \n    // Calculate score\n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(a[d], b[d]);\n    }\n    \n    return score;\n}\n\nLine randomLine() {\n    uniform_int_distribution<int> coord_dist(-20000, 20000);\n    \n    int px = coord_dist(rng);\n    int py = coord_dist(rng);\n    int qx = coord_dist(rng);\n    int qy = coord_dist(rng);\n    \n    // Ensure two different points\n    while (px == qx && py == qy) {\n        qx = coord_dist(rng);\n        qy = coord_dist(rng);\n    }\n    \n    return Line(px, py, qx, qy);\n}\n\nLine targetedLine() {\n    // Create lines based on strawberry positions\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    int i = idx_dist(rng);\n    int j = idx_dist(rng);\n    while (i == j) j = idx_dist(rng);\n    \n    double dx = strawberries[j].x - strawberries[i].x;\n    double dy = strawberries[j].y - strawberries[i].y;\n    \n    // Random angle variation\n    uniform_real_distribution<double> angle_dist(-0.5, 0.5);\n    double angle = atan2(dy, dx) + angle_dist(rng);\n    \n    // Random offset from midpoint\n    uniform_real_distribution<double> offset_dist(-2000, 2000);\n    double mx = (strawberries[i].x + strawberries[j].x) / 2 + offset_dist(rng);\n    double my = (strawberries[i].y + strawberries[j].y) / 2 + offset_dist(rng);\n    \n    // Create perpendicular line\n    int px = (int)mx;\n    int py = (int)my;\n    int qx = px + (int)(10000 * cos(angle + M_PI/2));\n    int qy = py + (int)(10000 * sin(angle + M_PI/2));\n    \n    return Line(px, py, qx, qy);\n}\n\nLine smartLine() {\n    // Try to create lines that separate clusters\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    \n    // Pick a random strawberry\n    int center = idx_dist(rng);\n    \n    // Find nearby strawberries\n    vector<pair<double, int>> dists;\n    for (int i = 0; i < N; i++) {\n        if (i != center) {\n            double d = (strawberries[i] - strawberries[center]).norm2();\n            dists.push_back({d, i});\n        }\n    }\n    sort(dists.begin(), dists.end());\n    \n    // Try to separate at a gap\n    uniform_int_distribution<int> gap_dist(1, min(10, (int)dists.size() - 1));\n    int gap_idx = gap_dist(rng);\n    \n    int idx1 = dists[gap_idx - 1].second;\n    int idx2 = dists[gap_idx].second;\n    \n    // Create a line between these two points\n    double mx = (strawberries[idx1].x + strawberries[idx2].x) / 2;\n    double my = (strawberries[idx1].y + strawberries[idx2].y) / 2;\n    \n    double dx = strawberries[idx2].x - strawberries[idx1].x;\n    double dy = strawberries[idx2].y - strawberries[idx1].y;\n    \n    // Perpendicular direction\n    double angle = atan2(dy, dx) + M_PI/2;\n    \n    int px = (int)mx;\n    int py = (int)my;\n    int qx = px + (int)(15000 * cos(angle));\n    int qy = py + (int)(15000 * sin(angle));\n    \n    return Line(px, py, qx, qy);\n}\n\nvoid solve() {\n    double startTime = clock();\n    lines.clear();\n    bestLines.clear();\n    bestScore = 0;\n    \n    // Phase 1: Greedy initialization\n    for (int iter = 0; iter < min(20, K); iter++) {\n        if ((clock() - startTime) / CLOCKS_PER_SEC > TIME_LIMIT * 0.25) break;\n        \n        Line bestLine = randomLine();\n        int bestImprovement = -1;\n        int currentScore = calculateScore();\n        \n        // Try multiple candidate lines\n        for (int trial = 0; trial < 40; trial++) {\n            Line candidate;\n            int strategy = trial % 3;\n            if (strategy == 0) candidate = randomLine();\n            else if (strategy == 1) candidate = targetedLine();\n            else candidate = smartLine();\n            \n            lines.push_back(candidate);\n            int newScore = calculateScore();\n            lines.pop_back();\n            \n            if (newScore - currentScore > bestImprovement) {\n                bestImprovement = newScore - currentScore;\n                bestLine = candidate;\n            }\n        }\n        \n        if (bestImprovement >= 0) {\n            lines.push_back(bestLine);\n        }\n    }\n    \n    // Phase 2: Simulated annealing\n    int currentScore = calculateScore();\n    bestLines = lines;\n    bestScore = currentScore;\n    \n    double temp = 10.0;\n    int iter = 0;\n    int stagnation = 0;\n    \n    while ((clock() - startTime) / CLOCKS_PER_SEC < TIME_LIMIT) {\n        iter++;\n        \n        // Update temperature\n        if (iter % 500 == 0) {\n            double elapsed = (clock() - startTime) / CLOCKS_PER_SEC;\n            temp = 10.0 * (1.0 - elapsed / TIME_LIMIT);\n            \n            // Check stagnation\n            if (currentScore == bestScore) {\n                stagnation++;\n                if (stagnation > 10) {\n                    // Shake things up\n                    temp *= 2;\n                    stagnation = 0;\n                }\n            } else {\n                stagnation = 0;\n            }\n        }\n        \n        // Choose operation\n        uniform_real_distribution<double> op_dist(0, 1);\n        double op = op_dist(rng);\n        \n        bool accepted = false;\n        \n        if (op < 0.35 && lines.size() < K) {\n            // Add a line\n            Line newLine;\n            uniform_int_distribution<int> strategy_dist(0, 2);\n            int strategy = strategy_dist(rng);\n            if (strategy == 0) newLine = randomLine();\n            else if (strategy == 1) newLine = targetedLine();\n            else newLine = smartLine();\n            \n            lines.push_back(newLine);\n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                accepted = true;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.pop_back();\n            }\n        } else if (op < 0.6 && lines.size() > 5) {\n            // Remove a line\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line removed = lines[idx];\n            lines.erase(lines.begin() + idx);\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                accepted = true;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.insert(lines.begin() + idx, removed);\n            }\n        } else if (lines.size() > 0) {\n            // Modify a line\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line old = lines[idx];\n            \n            // Choose modification type\n            if (rng() % 4 == 0) {\n                // Small perturbation\n                uniform_int_distribution<int> perturb_dist(-2000, 2000);\n                lines[idx].px += perturb_dist(rng);\n                lines[idx].py += perturb_dist(rng);\n                lines[idx].qx += perturb_dist(rng);\n                lines[idx].qy += perturb_dist(rng);\n            } else {\n                // Replace with new line\n                uniform_int_distribution<int> strategy_dist(0, 2);\n                int strategy = strategy_dist(rng);\n                if (strategy == 0) lines[idx] = randomLine();\n                else if (strategy == 1) lines[idx] = targetedLine();\n                else lines[idx] = smartLine();\n            }\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                accepted = true;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines[idx] = old;\n            }\n        }\n    }\n    \n    lines = bestLines;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    \n    solve();\n    \n    cout << lines.size() << \"\\n\";\n    for (const Line& line : lines) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return tie(x, y) < tie(p.x, p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n    Point operator-(const Point& p) const {\n        return Point(x - p.x, y - p.y);\n    }\n};\n\nint N, M;\nset<Point> dots;\nset<pair<Point, Point>> usedEdges;\nclock_t startTime;\n\nint weight(int x, int y) {\n    int c = (N - 1) / 2;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\ndouble getElapsedTime() {\n    return (double)(clock() - startTime) / CLOCKS_PER_SEC;\n}\n\nint dot(Point a, Point b) {\n    return a.x * b.x + a.y * b.y;\n}\n\nbool isRectangle(Point p1, Point p2, Point p3, Point p4) {\n    // Check if p1-p2-p3-p4 forms a rectangle\n    Point v12 = p2 - p1;\n    Point v23 = p3 - p2;\n    Point v34 = p4 - p3;\n    Point v41 = p1 - p4;\n    \n    // For a rectangle, opposite sides must be equal and adjacent sides perpendicular\n    if (v12.x == v34.x && v12.y == v34.y && \n        v23.x == v41.x && v23.y == v41.y &&\n        dot(v12, v23) == 0) {\n        return true;\n    }\n    \n    return false;\n}\n\nvector<Point> getAllPointsOnSegment(Point a, Point b) {\n    vector<Point> points;\n    int dx = (b.x > a.x) ? 1 : (b.x < a.x) ? -1 : 0;\n    int dy = (b.y > a.y) ? 1 : (b.y < a.y) ? -1 : 0;\n    \n    Point curr = a;\n    while (!(curr == b)) {\n        points.push_back(curr);\n        curr.x += dx;\n        curr.y += dy;\n    }\n    points.push_back(b);\n    return points;\n}\n\nbool tryRectangle(Point newDot, vector<Point>& existingDots, vector<int>& output) {\n    if (dots.count(newDot)) return false;\n    if (newDot.x < 0 || newDot.x >= N || newDot.y < 0 || newDot.y >= N) return false;\n    \n    // Try all permutations of 3 existing dots\n    sort(existingDots.begin(), existingDots.end());\n    do {\n        Point p2 = existingDots[0];\n        Point p3 = existingDots[1]; \n        Point p4 = existingDots[2];\n        \n        if (!isRectangle(newDot, p2, p3, p4)) continue;\n        \n        // Check perimeter has no other dots\n        vector<pair<Point, Point>> edges = {\n            {newDot, p2}, {p2, p3}, {p3, p4}, {p4, newDot}\n        };\n        \n        bool valid = true;\n        set<Point> corners = {newDot, p2, p3, p4};\n        \n        for (auto& edge : edges) {\n            auto points = getAllPointsOnSegment(edge.first, edge.second);\n            for (auto& pt : points) {\n                if (!corners.count(pt) && dots.count(pt)) {\n                    valid = false;\n                    break;\n                }\n            }\n            if (!valid) break;\n        }\n        \n        if (!valid) continue;\n        \n        // Check edges not already used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            if (usedEdges.count({a, b})) {\n                valid = false;\n                break;\n            }\n        }\n        \n        if (!valid) continue;\n        \n        // Found valid rectangle\n        output = {newDot.x, newDot.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y};\n        \n        // Mark edges as used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            usedEdges.insert({a, b});\n        }\n        \n        return true;\n        \n    } while (next_permutation(existingDots.begin(), existingDots.end()));\n    \n    return false;\n}\n\nint main() {\n    startTime = clock();\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert(Point(x, y));\n    }\n    \n    vector<vector<int>> result;\n    int center = (N - 1) / 2;\n    \n    while (getElapsedTime() < 4.0) {\n        bool found = false;\n        \n        // Try positions from center outward\n        for (int dist = 0; dist <= N && !found; dist++) {\n            for (int x = max(0, center - dist); x <= min(N - 1, center + dist) && !found; x++) {\n                for (int y = max(0, center - dist); y <= min(N - 1, center + dist) && !found; y++) {\n                    if (abs(x - center) != dist && abs(y - center) != dist) continue;\n                    \n                    Point newDot(x, y);\n                    if (dots.count(newDot)) continue;\n                    \n                    // Try to form rectangle with 3 existing dots\n                    vector<Point> dotVec(dots.begin(), dots.end());\n                    int n = dotVec.size();\n                    \n                    // Try combinations of 3 dots\n                    for (int i = 0; i < n && !found; i++) {\n                        for (int j = i + 1; j < n && !found; j++) {\n                            for (int k = j + 1; k < n && !found; k++) {\n                                vector<Point> threeDots = {dotVec[i], dotVec[j], dotVec[k]};\n                                vector<int> output;\n                                \n                                if (tryRectangle(newDot, threeDots, output)) {\n                                    dots.insert(newDot);\n                                    result.push_back(output);\n                                    found = true;\n                                }\n                                \n                                if (getElapsedTime() > 4.0) break;\n                            }\n                            if (getElapsedTime() > 4.0) break;\n                        }\n                        if (getElapsedTime() > 4.0) break;\n                    }\n                }\n            }\n        }\n        \n        if (!found) break;\n    }\n    \n    cout << result.size() << endl;\n    for (auto& r : result) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << \" \";\n            cout << r[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int TOTAL = 100;\n\nstruct Board {\n    int grid[N][N]; // 0 = empty, 1-3 = candy flavors\n    \n    Board() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void place(int pos, int flavor) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tiltForward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = 0;\n            for (int i = 0; i < N; i++) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltBackward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = N-1;\n            for (int i = N-1; i >= 0; i--) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tiltLeft() {\n        for (int i = 0; i < N; i++) {\n            int writePos = 0;\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltRight() {\n        for (int i = 0; i < N; i++) {\n            int writePos = N-1;\n            for (int j = N-1; j >= 0; j--) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') tiltForward();\n        else if (dir == 'B') tiltBackward();\n        else if (dir == 'L') tiltLeft();\n        else if (dir == 'R') tiltRight();\n    }\n    \n    // Get connected component sizes and info\n    tuple<vector<vector<int>>, int, vector<int>> analyzeComponents() {\n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        \n        vector<vector<int>> componentSizes(4); // index 0 unused, 1-3 for flavors\n        int totalComponents = 0;\n        vector<int> largestComponent(4, 0);\n        \n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int flavor = grid[i][j];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    componentSizes[flavor].push_back(size);\n                    largestComponent[flavor] = max(largestComponent[flavor], size);\n                    totalComponents++;\n                }\n            }\n        }\n        return {componentSizes, totalComponents, largestComponent};\n    }\n    \n    // Enhanced evaluation function\n    double evaluate(int t, const vector<int>& allFlavors) {\n        auto [componentSizes, totalComponents, largestComponent] = analyzeComponents();\n        \n        double score = 0;\n        \n        // Main scoring: sum of squares\n        for (int flavor = 1; flavor <= 3; flavor++) {\n            for (int size : componentSizes[flavor]) {\n                score += size * size * 1000;\n            }\n        }\n        \n        // Penalty for fragmentation\n        score -= totalComponents * 200;\n        \n        // Bonus for large components\n        for (int flavor = 1; flavor <= 3; flavor++) {\n            score += largestComponent[flavor] * largestComponent[flavor] * 50;\n        }\n        \n        // Consider compactness (candies should be close together)\n        double compactness = calculateCompactness();\n        score += compactness * 100;\n        \n        // Look ahead bonus: prefer consolidating flavors that will appear soon\n        if (t < TOTAL - 1) {\n            vector<int> upcomingCount(4, 0);\n            for (int i = t + 1; i < min(t + 15, TOTAL); i++) {\n                upcomingCount[allFlavors[i]]++;\n            }\n            \n            for (int flavor = 1; flavor <= 3; flavor++) {\n                if (upcomingCount[flavor] > 0 && largestComponent[flavor] > 0) {\n                    // Bonus for having a large component of a flavor that will appear soon\n                    score += largestComponent[flavor] * upcomingCount[flavor] * 30;\n                }\n            }\n        }\n        \n        return score;\n    }\n    \n    double calculateCompactness() {\n        double totalDist = 0;\n        int count = 0;\n        \n        for (int flavor = 1; flavor <= 3; flavor++) {\n            vector<pair<int, int>> positions;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] == flavor) {\n                        positions.push_back({i, j});\n                    }\n                }\n            }\n            \n            if (positions.size() <= 1) continue;\n            \n            // Calculate average distance between same-flavor candies\n            for (size_t i = 0; i < positions.size(); i++) {\n                for (size_t j = i + 1; j < positions.size(); j++) {\n                    int dist = abs(positions[i].first - positions[j].first) + \n                              abs(positions[i].second - positions[j].second);\n                    totalDist += dist;\n                    count++;\n                }\n            }\n        }\n        \n        // Lower distance is better, so return negative\n        return count > 0 ? -totalDist / count : 0;\n    }\n    \n    // Count adjacent pairs of same flavor\n    int countAdjacentPairs() {\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (i + 1 < N && grid[i+1][j] == grid[i][j]) count++;\n                    if (j + 1 < N && grid[i][j+1] == grid[i][j]) count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(TOTAL);\n    for (int i = 0; i < TOTAL; i++) {\n        cin >> flavors[i];\n    }\n    \n    Board board;\n    \n    for (int t = 0; t < TOTAL; t++) {\n        int pos;\n        cin >> pos;\n        \n        board.place(pos, flavors[t]);\n        \n        if (t == TOTAL - 1) break;\n        \n        char dirs[] = {'F', 'B', 'L', 'R'};\n        char bestDir = 'F';\n        double bestScore = -1e9;\n        \n        // Evaluate each direction\n        for (char dir : dirs) {\n            Board tempBoard = board;\n            tempBoard.tilt(dir);\n            \n            double score;\n            if (t < 10) {\n                // Very early game: prioritize adjacent pairs\n                score = tempBoard.countAdjacentPairs() * 1000.0;\n                auto [comp, total, largest] = tempBoard.analyzeComponents();\n                score -= total * 10; // Still prefer fewer components\n            } else {\n                // Use full evaluation\n                score = tempBoard.evaluate(t, flavors);\n            }\n            \n            // Tie-breaking: prefer certain directions based on board state\n            if (abs(score - bestScore) < 0.01) {\n                // If scores are very close, prefer to keep board compact\n                if (dir == 'L' || dir == 'F') score += 0.001;\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestDir = dir;\n            }\n        }\n        \n        board.tilt(bestDir);\n        cout << bestDir << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass Graph {\n    int N;\n    vector<vector<int>> adj;\n    \npublic:\n    Graph(int n) : N(n), adj(n, vector<int>(n, 0)) {}\n    \n    void setEdge(int i, int j, int val) {\n        adj[i][j] = adj[j][i] = val;\n    }\n    \n    string toString() const {\n        string s;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void fromString(const string& s) {\n        int idx = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1' ? 1 : 0);\n            }\n        }\n    }\n    \n    vector<double> getFullInvariants() const {\n        vector<double> inv;\n        \n        // 1. Edge count\n        int edges = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                edges += adj[i][j];\n            }\n        }\n        inv.push_back(edges);\n        \n        // 2. Degree sequence statistics\n        vector<int> degrees(N, 0);\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        \n        // Sort degrees for invariance\n        vector<int> deg_sorted = degrees;\n        sort(deg_sorted.begin(), deg_sorted.end());\n        \n        // Add multiple degree statistics\n        for(int i = 0; i < min(10, N); i++) {\n            inv.push_back(deg_sorted[i]);\n            inv.push_back(deg_sorted[N-1-i]);\n        }\n        \n        // 3. Triangle count\n        int triangles = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                for(int k = j + 1; k < N; k++) {\n                    triangles += adj[i][j] * adj[j][k] * adj[k][i];\n                }\n            }\n        }\n        inv.push_back(triangles);\n        \n        // 4. Degree squared sum\n        double deg_sq = 0;\n        for(int d : degrees) {\n            deg_sq += d * d;\n        }\n        inv.push_back(deg_sq);\n        \n        // 5. 4-cliques\n        int cliques4 = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i+1; j < N; j++) {\n                for(int k = j+1; k < N; k++) {\n                    for(int l = k+1; l < N; l++) {\n                        if(adj[i][j] && adj[i][k] && adj[i][l] &&\n                           adj[j][k] && adj[j][l] && adj[k][l]) {\n                            cliques4++;\n                        }\n                    }\n                }\n            }\n        }\n        inv.push_back(cliques4);\n        \n        // 6. Common neighbors distribution\n        map<int, int> common_neigh_dist;\n        for(int i = 0; i < N; i++) {\n            for(int j = i+1; j < N; j++) {\n                int common = 0;\n                for(int k = 0; k < N; k++) {\n                    if(k != i && k != j) {\n                        common += adj[i][k] * adj[j][k];\n                    }\n                }\n                common_neigh_dist[common]++;\n            }\n        }\n        \n        // Add common neighbor statistics\n        for(int c = 0; c <= min(10, N-2); c++) {\n            inv.push_back(common_neigh_dist[c]);\n        }\n        \n        // 7. Degree correlation\n        double deg_corr = 0;\n        int edge_cnt = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i+1; j < N; j++) {\n                if(adj[i][j]) {\n                    deg_corr += degrees[i] * degrees[j];\n                    edge_cnt++;\n                }\n            }\n        }\n        if(edge_cnt > 0) deg_corr /= edge_cnt;\n        inv.push_back(deg_corr);\n        \n        // 8. Path count of length 3\n        int paths3 = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                if(i != j && adj[i][j]) {\n                    for(int k = 0; k < N; k++) {\n                        if(k != i && k != j && adj[j][k]) {\n                            for(int l = 0; l < N; l++) {\n                                if(l != i && l != j && l != k && adj[k][l]) {\n                                    paths3++;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        inv.push_back(paths3 / 6.0); // Divide by 6 to account for overcounting\n        \n        return inv;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Optimize N more aggressively for score\n    int N;\n    if(M <= 15) {\n        N = 6;  // Very small for small M\n    } else if(M <= 30) {\n        if(eps <= 0.15) N = 8;\n        else if(eps <= 0.25) N = 10;\n        else N = 12;\n    } else if(M <= 50) {\n        if(eps <= 0.15) N = 10;\n        else if(eps <= 0.25) N = 14;\n        else N = 18;\n    } else {\n        if(eps <= 0.15) N = 14;\n        else if(eps <= 0.25) N = 20;\n        else N = 28;\n    }\n    \n    vector<Graph> graphs;\n    \n    // Generate M maximally separated graphs\n    for(int idx = 0; idx < M; idx++) {\n        Graph g(N);\n        \n        // Use edge density as primary differentiator\n        double base_density = (double)idx / max(1, M - 1);\n        \n        // Add variation pattern based on index\n        int pattern = idx % 7;\n        double density_variation = 0.0;\n        \n        // Add small perturbations to avoid identical densities\n        if(pattern == 0) density_variation = 0.00;\n        else if(pattern == 1) density_variation = 0.02;\n        else if(pattern == 2) density_variation = -0.02;\n        else if(pattern == 3) density_variation = 0.01;\n        else if(pattern == 4) density_variation = -0.01;\n        else if(pattern == 5) density_variation = 0.03;\n        else density_variation = -0.03;\n        \n        double final_density = max(0.0, min(1.0, base_density + density_variation));\n        int target_edges = (int)(final_density * N * (N - 1) / 2);\n        \n        // Generate edges with specific patterns\n        set<pair<int,int>> edges;\n        mt19937 gen(idx * 12345 + 67890);\n        \n        // Start with a base structure depending on index\n        if(idx % 5 == 0 && N > 3) {\n            // Path structure\n            for(int i = 0; i < N-1 && edges.size() < target_edges; i++) {\n                edges.insert({i, i+1});\n            }\n        } else if(idx % 5 == 1 && N > 4) {\n            // Star structure\n            for(int i = 1; i < N && edges.size() < target_edges; i++) {\n                edges.insert({0, i});\n            }\n        } else if(idx % 5 == 2 && N > 3) {\n            // Cycle structure\n            for(int i = 0; i < N && edges.size() < target_edges; i++) {\n                edges.insert({i, (i+1)%N});\n            }\n        } else if(idx % 5 == 3 && N > 5) {\n            // Bipartite-ish\n            for(int i = 0; i < N/2 && edges.size() < target_edges; i++) {\n                for(int j = N/2; j < N && edges.size() < target_edges; j++) {\n                    if((i + j * 3) % ((idx % 7) + 2) == 0) {\n                        edges.insert({i, j});\n                    }\n                }\n            }\n        } else {\n            // Complete subgraph\n            int k = min(N, (int)(sqrt(target_edges * 2) + 1));\n            for(int i = 0; i < k && edges.size() < target_edges; i++) {\n                for(int j = i+1; j < k && edges.size() < target_edges; j++) {\n                    edges.insert({i, j});\n                }\n            }\n        }\n        \n        // Add random edges to reach target, using deterministic randomness\n        vector<pair<int,int>> all_edges;\n        for(int i = 0; i < N; i++) {\n            for(int j = i+1; j < N; j++) {\n                all_edges.push_back({i, j});\n            }\n        }\n        shuffle(all_edges.begin(), all_edges.end(), gen);\n        \n        for(auto [u, v] : all_edges) {\n            if(edges.size() >= target_edges) break;\n            edges.insert({u, v});\n        }\n        \n        // Build graph\n        for(auto [u, v] : edges) {\n            g.setEdge(u, v, 1);\n        }\n        \n        graphs.push_back(g);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for(const auto& g : graphs) {\n        cout << g.toString() << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute invariants\n    vector<vector<double>> invariants;\n    for(const auto& g : graphs) {\n        invariants.push_back(g.getFullInvariants());\n    }\n    \n    // Process queries\n    for(int q = 0; q < 100; q++) {\n        string h_str;\n        cin >> h_str;\n        \n        Graph h(N);\n        h.fromString(h_str);\n        auto h_inv = h.getFullInvariants();\n        \n        // Find best match using weighted scoring\n        int best = 0;\n        double best_score = -1e18;\n        \n        for(int i = 0; i < M; i++) {\n            double score = 0;\n            \n            // Use different weights for different invariants\n            for(size_t j = 0; j < min(h_inv.size(), invariants[i].size()); j++) {\n                double weight = 1.0;\n                if(j == 0) weight = 5.0;  // Edge count is most important\n                else if(j <= 20) weight = 2.0;  // Degree sequence\n                else if(j == 21) weight = 3.0;  // Triangles\n                \n                double diff = abs(h_inv[j] - invariants[i][j]);\n                double norm = max(1.0, abs(invariants[i][j]) + 1.0);\n                score -= weight * diff / norm;\n            }\n            \n            if(score > best_score) {\n                best_score = score;\n                best = i;\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    double cx, cy;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<int> assignment;\nmt19937 rng(42);\n\nconst int INF = 1000000000;\n\nvector<int> dijkstra(int s, const vector<bool>& usable, const vector<vector<pair<int, int>>>& graph) {\n    vector<int> dist(N, INF);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            if (!usable[eid]) continue;\n            int w = edges[eid].w;\n            \n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    return dist;\n}\n\ndouble evaluateFrustration(const vector<vector<int>>& sampled_dist, \n                          const vector<int>& sample_vertices,\n                          const vector<vector<pair<int, int>>>& graph) {\n    double total = 0;\n    \n    // Validate assignment\n    vector<int> counts(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        counts[assignment[i]]++;\n    }\n    for (int d = 1; d <= D; d++) {\n        if (counts[d] > K) return 1e18; // Invalid assignment\n    }\n    \n    vector<vector<int>> day_edges(D + 1);\n    for (int i = 0; i < M; i++) {\n        day_edges[assignment[i]].push_back(i);\n    }\n    \n    for (int day = 1; day <= D; day++) {\n        vector<bool> usable(M, true);\n        for (int e : day_edges[day]) {\n            usable[e] = false;\n        }\n        \n        double day_frustration = 0;\n        \n        for (int idx = 0; idx < sample_vertices.size(); idx++) {\n            int s = sample_vertices[idx];\n            auto dist = dijkstra(s, usable, graph);\n            \n            // Sample targets\n            int step = max(1, N / 15);\n            for (int t = 0; t < N; t += step) {\n                if (s != t) {\n                    day_frustration += (dist[t] - sampled_dist[idx][t]);\n                }\n            }\n        }\n        \n        total += day_frustration;\n    }\n    \n    return total / (D * sample_vertices.size() * (N / max(1, N/15)));\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Compute edge centers\n    for (int i = 0; i < M; i++) {\n        edges[i].cx = (coords[edges[i].u].first + coords[edges[i].v].first) / 2.0;\n        edges[i].cy = (coords[edges[i].u].second + coords[edges[i].v].second) / 2.0;\n    }\n    \n    // Build graph\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    // Sample vertices for evaluation (fewer samples)\n    int sample_size = min(20, N);\n    vector<int> sample_vertices;\n    for (int i = 0; i < sample_size; i++) {\n        sample_vertices.push_back((i * N) / sample_size);\n    }\n    \n    // Compute original distances\n    vector<bool> all_usable(M, true);\n    vector<vector<int>> sampled_dist(sample_size);\n    for (int i = 0; i < sample_size; i++) {\n        sampled_dist[i] = dijkstra(sample_vertices[i], all_usable, graph);\n    }\n    \n    // Initial assignment - simple round-robin with spatial sorting\n    assignment.resize(M);\n    vector<pair<double, int>> edge_positions;\n    for (int i = 0; i < M; i++) {\n        // Sort by position (simple spatial ordering)\n        edge_positions.push_back({edges[i].cx + edges[i].cy * 1000, i});\n    }\n    sort(edge_positions.begin(), edge_positions.end());\n    \n    // Round-robin assignment\n    int day = 1;\n    vector<int> day_counts(D + 1, 0);\n    for (auto [pos, eid] : edge_positions) {\n        // Find day with minimum edges\n        int best_day = 1;\n        for (int d = 1; d <= D; d++) {\n            if (day_counts[d] < day_counts[best_day]) {\n                best_day = d;\n            }\n        }\n        assignment[eid] = best_day;\n        day_counts[best_day]++;\n    }\n    \n    // Simulated annealing\n    double current_score = evaluateFrustration(sampled_dist, sample_vertices, graph);\n    double best_score = current_score;\n    vector<int> best_assignment = assignment;\n    \n    double T = 5.0;\n    uniform_real_distribution<double> prob(0, 1);\n    uniform_int_distribution<int> edge_dist(0, M-1);\n    \n    // Maintain day counts\n    fill(day_counts.begin(), day_counts.end(), 0);\n    for (int i = 0; i < M; i++) {\n        day_counts[assignment[i]]++;\n    }\n    \n    int iterations = 0;\n    int last_improvement = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        if (elapsed > 5000) break;\n        \n        iterations++;\n        \n        // Try a swap\n        int e1 = edge_dist(rng);\n        int e2 = edge_dist(rng);\n        \n        if (e1 == e2 || assignment[e1] == assignment[e2]) continue;\n        \n        // Save old state\n        int old_day1 = assignment[e1];\n        int old_day2 = assignment[e2];\n        \n        // Make swap\n        assignment[e1] = old_day2;\n        assignment[e2] = old_day1;\n        \n        // No need to update counts for swap (count remains same)\n        \n        double new_score = evaluateFrustration(sampled_dist, sample_vertices, graph);\n        double delta = new_score - current_score;\n        \n        if (delta < 0 || prob(rng) < exp(-delta / T)) {\n            current_score = new_score;\n            if (current_score < best_score) {\n                best_score = current_score;\n                best_assignment = assignment;\n                last_improvement = iterations;\n            }\n        } else {\n            // Revert\n            assignment[e1] = old_day1;\n            assignment[e2] = old_day2;\n        }\n        \n        // Adaptive cooling\n        if (iterations % 100 == 0) {\n            T *= 0.98;\n            \n            // Reset if stuck\n            if (iterations - last_improvement > 1000) {\n                T = 2.0;\n                last_improvement = iterations;\n            }\n        }\n    }\n    \n    assignment = best_assignment;\n    \n    // Final validation\n    fill(day_counts.begin(), day_counts.end(), 0);\n    for (int i = 0; i < M; i++) {\n        day_counts[assignment[i]]++;\n    }\n    \n    for (int d = 1; d <= D; d++) {\n        if (day_counts[d] > K) {\n            // Emergency fix: move excess edges to other days\n            while (day_counts[d] > K) {\n                // Find edge in day d\n                for (int i = 0; i < M; i++) {\n                    if (assignment[i] == d) {\n                        // Find day with space\n                        for (int new_d = 1; new_d <= D; new_d++) {\n                            if (day_counts[new_d] < K) {\n                                assignment[i] = new_d;\n                                day_counts[d]--;\n                                day_counts[new_d]++;\n                                break;\n                            }\n                        }\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nvoid read_input() {\n    cin >> D;\n    f1.resize(D); r1.resize(D);\n    f2.resize(D); r2.resize(D);\n    \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\nvector<vector<vector<int>>> construct_object(vector<string>& f, vector<string>& r) {\n    vector<vector<vector<int>>> obj(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(f[z][x] == '1' && r[z][y] == '1') {\n                    obj[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    return obj;\n}\n\nvoid create_connected_block(vector<vector<vector<int>>>& obj, \n                           vector<vector<vector<bool>>>& used,\n                           int sx, int sy, int sz,\n                           vector<int>& result,\n                           int block_id,\n                           int max_size = 8) {\n    queue<tuple<int,int,int>> q;\n    q.push({sx, sy, sz});\n    used[sx][sy][sz] = true;\n    result[sx * D * D + sy * D + sz] = block_id;\n    int count = 1;\n    \n    int dx[] = {1,-1,0,0,0,0};\n    int dy[] = {0,0,1,-1,0,0};\n    int dz[] = {0,0,0,0,1,-1};\n    \n    while(!q.empty() && count < max_size) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        for(int d = 0; d < 6; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            int nz = z + dz[d];\n            \n            if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n               obj[nx][ny][nz] == 1 && !used[nx][ny][nz] && count < max_size) {\n                used[nx][ny][nz] = true;\n                result[nx * D * D + ny * D + nz] = block_id;\n                q.push({nx, ny, nz});\n                count++;\n            }\n        }\n    }\n}\n\nvoid create_and_output() {\n    auto obj1 = construct_object(f1, r1);\n    auto obj2 = construct_object(f2, r2);\n    \n    vector<int> b1(D * D * D, 0);\n    vector<int> b2(D * D * D, 0);\n    \n    vector<vector<vector<bool>>> used1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> used2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    int block_id = 0;\n    \n    // First, create shared blocks for positions that exist in both objects\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && obj2[x][y][z] == 1 && \n                   !used1[x][y][z] && !used2[x][y][z]) {\n                    block_id++;\n                    \n                    // Create a shared block starting from this position\n                    // Try to expand it as a connected component\n                    queue<tuple<int,int,int>> q;\n                    q.push({x, y, z});\n                    used1[x][y][z] = true;\n                    used2[x][y][z] = true;\n                    b1[x * D * D + y * D + z] = block_id;\n                    b2[x * D * D + y * D + z] = block_id;\n                    \n                    int count = 1;\n                    int dx[] = {1,-1,0,0,0,0};\n                    int dy[] = {0,0,1,-1,0,0};\n                    int dz[] = {0,0,0,0,1,-1};\n                    \n                    while(!q.empty() && count < 4) {  // Limit shared blocks to size 4\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        \n                        for(int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            \n                            if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                               obj1[nx][ny][nz] == 1 && obj2[nx][ny][nz] == 1 &&\n                               !used1[nx][ny][nz] && !used2[nx][ny][nz] && count < 4) {\n                                used1[nx][ny][nz] = true;\n                                used2[nx][ny][nz] = true;\n                                b1[nx * D * D + ny * D + nz] = block_id;\n                                b2[nx * D * D + ny * D + nz] = block_id;\n                                q.push({nx, ny, nz});\n                                count++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Fill remaining cells in obj1 with connected blocks\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && !used1[x][y][z]) {\n                    block_id++;\n                    create_connected_block(obj1, used1, x, y, z, b1, block_id, 6);\n                }\n            }\n        }\n    }\n    \n    // Fill remaining cells in obj2 with connected blocks\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj2[x][y][z] == 1 && !used2[x][y][z]) {\n                    block_id++;\n                    create_connected_block(obj2, used2, x, y, z, b2, block_id, 6);\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << block_id << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b1[i];\n    }\n    cout << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b2[i];\n    }\n    cout << endl;\n}\n\nint main() {\n    read_input();\n    create_and_output();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nclass Solution {\n    int N, M, K;\n    vector<pair<int, int>> vertices;\n    vector<Edge> edges;\n    vector<vector<pair<int, pair<int, long long>>>> adj;\n    vector<pair<int, int>> residents;\n    vector<vector<int>> resident_dist;\n    vector<vector<int>> covering_vertices; // For each resident, which vertices can cover it\n    \n    // Dijkstra from source\n    pair<vector<long long>, vector<int>> dijkstra(int source) {\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> parent_edge(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        \n        dist[source] = 0;\n        pq.push({0, source});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            \n            if (d > dist[u]) continue;\n            \n            for (auto [v, info] : adj[u]) {\n                long long w = info.second;\n                if (dist[u] + w < dist[v]) {\n                    dist[v] = dist[u] + w;\n                    parent_edge[v] = info.first;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        return {dist, parent_edge};\n    }\n    \n    // Get minimum spanning tree of a set of vertices\n    pair<long long, vector<int>> getMSTCost(const set<int>& terminals) {\n        if (terminals.empty() || (terminals.size() == 1 && *terminals.begin() == 0)) {\n            return {0, vector<int>(M, 0)};\n        }\n        \n        // Use MST heuristic for Steiner tree\n        // First, compute shortest paths between all terminal pairs\n        map<pair<int,int>, long long> terminal_dist;\n        map<pair<int,int>, vector<int>> terminal_paths;\n        \n        for (int t : terminals) {\n            auto [dist, parent_edge] = dijkstra(t);\n            for (int s : terminals) {\n                if (s != t && dist[s] != LLONG_MAX) {\n                    terminal_dist[{min(t,s), max(t,s)}] = dist[s];\n                    // Build path\n                    vector<int> path;\n                    int curr = s;\n                    while (parent_edge[curr] != -1) {\n                        path.push_back(parent_edge[curr]);\n                        int e = parent_edge[curr];\n                        curr = (edges[e].u == curr) ? edges[e].v : edges[e].u;\n                    }\n                    terminal_paths[{min(t,s), max(t,s)}] = path;\n                }\n            }\n        }\n        \n        // Build MST of terminals\n        vector<int> edge_used(M, 0);\n        set<int> connected;\n        connected.insert(0);\n        \n        long long total_cost = 0;\n        \n        while (connected.size() < terminals.size()) {\n            long long min_cost = LLONG_MAX;\n            pair<int,int> best_pair;\n            \n            for (int u : connected) {\n                for (int v : terminals) {\n                    if (connected.find(v) == connected.end()) {\n                        auto key = make_pair(min(u,v), max(u,v));\n                        if (terminal_dist.count(key) && terminal_dist[key] < min_cost) {\n                            min_cost = terminal_dist[key];\n                            best_pair = key;\n                        }\n                    }\n                }\n            }\n            \n            if (min_cost == LLONG_MAX) break;\n            \n            // Add edges from path\n            for (int e : terminal_paths[best_pair]) {\n                edge_used[e] = 1;\n                total_cost += edges[e].w;\n            }\n            connected.insert(best_pair.first);\n            connected.insert(best_pair.second);\n        }\n        \n        // Remove redundant edges\n        for (int i = 0; i < M; i++) {\n            if (edge_used[i]) {\n                edge_used[i] = 0;\n                // Check if still connected\n                set<int> reachable;\n                function<void(int)> dfs = [&](int u) {\n                    reachable.insert(u);\n                    for (auto [v, info] : adj[u]) {\n                        if (edge_used[info.first] && reachable.find(v) == reachable.end()) {\n                            dfs(v);\n                        }\n                    }\n                };\n                dfs(0);\n                \n                bool all_connected = true;\n                for (int t : terminals) {\n                    if (reachable.find(t) == reachable.end()) {\n                        all_connected = false;\n                        break;\n                    }\n                }\n                \n                if (!all_connected) {\n                    edge_used[i] = 1;\n                } else {\n                    total_cost -= edges[i].w;\n                }\n            }\n        }\n        \n        return {total_cost, edge_used};\n    }\n    \n    long long computeCost(const vector<int>& powers, const vector<int>& edge_used) {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) {\n            cost += (long long)powers[i] * powers[i];\n        }\n        for (int i = 0; i < M; i++) {\n            if (edge_used[i]) cost += edges[i].w;\n        }\n        return cost;\n    }\n    \n    bool allResidentsCovered(const set<int>& active, const vector<int>& powers) {\n        for (int r = 0; r < K; r++) {\n            bool covered = false;\n            for (int v : active) {\n                if (resident_dist[r][v] <= powers[v]) {\n                    covered = true;\n                    break;\n                }\n            }\n            if (!covered) return false;\n        }\n        return true;\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> M >> K;\n        \n        vertices.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> vertices[i].first >> vertices[i].second;\n        }\n        \n        edges.resize(M);\n        adj.resize(N);\n        \n        for (int i = 0; i < M; i++) {\n            cin >> edges[i].u >> edges[i].v >> edges[i].w;\n            edges[i].u--; edges[i].v--;\n            edges[i].id = i;\n            adj[edges[i].u].push_back({edges[i].v, {i, edges[i].w}});\n            adj[edges[i].v].push_back({edges[i].u, {i, edges[i].w}});\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].first >> residents[i].second;\n        }\n        \n        // Precompute distances\n        resident_dist.resize(K, vector<int>(N));\n        covering_vertices.resize(K);\n        \n        for (int r = 0; r < K; r++) {\n            for (int v = 0; v < N; v++) {\n                long long dx = residents[r].first - vertices[v].first;\n                long long dy = residents[r].second - vertices[v].second;\n                resident_dist[r][v] = (int)ceil(sqrt(dx * dx + dy * dy));\n                if (resident_dist[r][v] <= 5000) {\n                    covering_vertices[r].push_back(v);\n                }\n            }\n        }\n        \n        // Initial greedy solution\n        set<int> active_vertices;\n        active_vertices.insert(0);\n        vector<int> vertex_power(N, 0);\n        vector<bool> covered(K, false);\n        \n        auto [dist_from_0, _] = dijkstra(0);\n        \n        // Greedy set cover\n        while (count(covered.begin(), covered.end(), false) > 0) {\n            double best_efficiency = 1e18;\n            int best_v = -1;\n            int best_power = 0;\n            \n            for (int v = 0; v < N; v++) {\n                if (dist_from_0[v] == LLONG_MAX) continue;\n                \n                int new_covered = 0;\n                int req_power = vertex_power[v];\n                \n                for (int r = 0; r < K; r++) {\n                    if (!covered[r] && resident_dist[r][v] <= 5000) {\n                        new_covered++;\n                        req_power = max(req_power, resident_dist[r][v]);\n                    }\n                }\n                \n                if (new_covered > 0 && req_power <= 5000) {\n                    set<int> temp_active = active_vertices;\n                    temp_active.insert(v);\n                    auto [mst_cost, _] = getMSTCost(temp_active);\n                    \n                    long long power_increase = (long long)req_power * req_power - \n                                             (long long)vertex_power[v] * vertex_power[v];\n                    long long edge_increase = mst_cost;\n                    for (int a : active_vertices) {\n                        if (a != v) {\n                            auto [prev_cost, _] = getMSTCost({0, a});\n                            edge_increase -= prev_cost;\n                        }\n                    }\n                    edge_increase = max(0LL, edge_increase);\n                    \n                    double efficiency = (power_increase + edge_increase) / (double)new_covered;\n                    \n                    if (efficiency < best_efficiency) {\n                        best_efficiency = efficiency;\n                        best_v = v;\n                        best_power = req_power;\n                    }\n                }\n            }\n            \n            if (best_v == -1) break;\n            \n            active_vertices.insert(best_v);\n            vertex_power[best_v] = best_power;\n            \n            for (int r = 0; r < K; r++) {\n                if (resident_dist[r][best_v] <= best_power) {\n                    covered[r] = true;\n                }\n            }\n        }\n        \n        // Try to remove vertices\n        vector<int> vertices_to_check(active_vertices.begin(), active_vertices.end());\n        for (int v : vertices_to_check) {\n            if (v == 0) continue;\n            \n            set<int> temp_active = active_vertices;\n            temp_active.erase(v);\n            \n            // Check if all residents still covered\n            bool all_covered = true;\n            for (int r = 0; r < K; r++) {\n                bool r_covered = false;\n                for (int u : temp_active) {\n                    if (resident_dist[r][u] <= vertex_power[u]) {\n                        r_covered = true;\n                        break;\n                    }\n                }\n                if (!r_covered) {\n                    all_covered = false;\n                    break;\n                }\n            }\n            \n            if (all_covered) {\n                active_vertices = temp_active;\n                vertex_power[v] = 0;\n            }\n        }\n        \n        // Minimize powers using binary search\n        for (int v : active_vertices) {\n            if (vertex_power[v] == 0) continue;\n            \n            int left = 0, right = vertex_power[v];\n            int best_power = vertex_power[v];\n            \n            while (left < right) {\n                int mid = (left + right) / 2;\n                \n                // Check if this power works\n                vector<int> temp_power = vertex_power;\n                temp_power[v] = mid;\n                \n                if (allResidentsCovered(active_vertices, temp_power)) {\n                    best_power = mid;\n                    right = mid;\n                } else {\n                    left = mid + 1;\n                }\n            }\n            \n            vertex_power[v] = best_power;\n        }\n        \n        // Build final MST\n        auto [final_cost, edge_used] = getMSTCost(active_vertices);\n        \n        // Clear power for non-connected vertices\n        set<int> connected;\n        function<void(int)> dfs = [&](int u) {\n            connected.insert(u);\n            for (auto [v, info] : adj[u]) {\n                if (edge_used[info.first] && connected.find(v) == connected.end()) {\n                    dfs(v);\n                }\n            }\n        };\n        dfs(0);\n        \n        for (int v = 0; v < N; v++) {\n            if (connected.find(v) == connected.end()) {\n                vertex_power[v] = 0;\n            }\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            cout << vertex_power[i] << (i == N-1 ? \"\\n\" : \" \");\n        }\n        for (int i = 0; i < M; i++) {\n            cout << edge_used[i] << (i == M-1 ? \"\\n\" : \" \");\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nvector<vector<int>> pyramid(N);\nvector<tuple<int,int,int,int>> moves;\n\nvoid swapBalls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    moves.push_back({x1, y1, x2, y2});\n}\n\n// Count violations for a specific position\nint positionViolations(int x, int y) {\n    int violations = 0;\n    if (x < N - 1) {\n        if (pyramid[x][y] > pyramid[x + 1][y]) violations++;\n        if (pyramid[x][y] > pyramid[x + 1][y + 1]) violations++;\n    }\n    return violations;\n}\n\n// Count total violations\nint countViolations() {\n    int violations = 0;\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            violations += positionViolations(x, y);\n        }\n    }\n    return violations;\n}\n\n// Heapify from a position downward\nvoid heapifyDown(int x, int y) {\n    if (x >= N - 1) return;\n    \n    int leftChild = pyramid[x + 1][y];\n    int rightChild = pyramid[x + 1][y + 1];\n    \n    // Find minimum among parent and children\n    if (pyramid[x][y] > leftChild && leftChild <= rightChild) {\n        swapBalls(x, y, x + 1, y);\n        heapifyDown(x + 1, y);\n    } else if (pyramid[x][y] > rightChild) {\n        swapBalls(x, y, x + 1, y + 1);\n        heapifyDown(x + 1, y + 1);\n    }\n}\n\n// Try to bubble up small values\nvoid bubbleUp(int x, int y) {\n    if (x == 0) return;\n    \n    // Check possible parent positions\n    vector<pair<int,int>> parents;\n    if (y > 0) parents.push_back({x - 1, y - 1});\n    if (y < x) parents.push_back({x - 1, y});\n    \n    for (auto [px, py] : parents) {\n        if (px >= 0 && py >= 0 && py <= px) {\n            if (pyramid[x][y] < pyramid[px][py]) {\n                // Check if swap would not create new violations\n                int currentViolations = positionViolations(px, py);\n                swapBalls(x, y, px, py);\n                int newViolations = positionViolations(px, py);\n                \n                if (newViolations <= currentViolations) {\n                    bubbleUp(px, py);\n                    return;\n                } else {\n                    // Revert if it made things worse\n                    swapBalls(x, y, px, py);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x + 1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Phase 1: Initial heapify from bottom-up\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            heapifyDown(x, y);\n        }\n    }\n    \n    // Phase 2: Find small values in lower levels and bubble them up\n    vector<tuple<int, int, int>> valuePositions;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            valuePositions.push_back({pyramid[x][y], x, y});\n        }\n    }\n    sort(valuePositions.begin(), valuePositions.end());\n    \n    // Try to move smallest values upward\n    for (int i = 0; i < min(100, (int)valuePositions.size()); i++) {\n        auto [val, x, y] = valuePositions[i];\n        // Find current position of this value\n        bool found = false;\n        for (int cx = 0; cx < N && !found; cx++) {\n            for (int cy = 0; cy <= cx && !found; cy++) {\n                if (pyramid[cx][cy] == val) {\n                    bubbleUp(cx, cy);\n                    found = true;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Final cleanup - fix remaining violations\n    int maxCleanupIter = 1000;\n    for (int iter = 0; iter < maxCleanupIter && moves.size() < 9500; iter++) {\n        if (countViolations() == 0) break;\n        \n        bool improved = false;\n        for (int x = 0; x < N - 1; x++) {\n            for (int y = 0; y <= x; y++) {\n                if (pyramid[x][y] > pyramid[x + 1][y]) {\n                    swapBalls(x, y, x + 1, y);\n                    heapifyDown(x + 1, y);\n                    improved = true;\n                }\n                if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                    swapBalls(x, y, x + 1, y + 1);\n                    heapifyDown(x + 1, y + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Output\n    cout << moves.size() << endl;\n    for (auto [x1, y1, x2, y2] : moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {-1, 0, 1, 0};\nconst int dy[] = {0, 1, 0, -1};\n\nstruct Container {\n    int number;\n    int x, y;\n};\n\nclass Warehouse {\n    int D, N;\n    int entrance_x, entrance_y;\n    vector<vector<int>> grid; // -1: obstacle, -2: empty, >=0: container number\n    vector<Container> containers;\n    vector<pair<int,int>> obstacles;\n    \npublic:\n    Warehouse() {\n        cin >> D >> N;\n        entrance_x = 0;\n        entrance_y = (D - 1) / 2;\n        \n        grid.resize(D, vector<int>(D, -2));\n        \n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n            grid[x][y] = -1;\n            obstacles.push_back({x, y});\n        }\n    }\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < D && y >= 0 && y < D;\n    }\n    \n    bool isReachable(int tx, int ty) {\n        if (!isValid(tx, ty) || grid[tx][ty] == -1) return false;\n        if (tx == entrance_x && ty == entrance_y) return true;\n        \n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        q.push({entrance_x, entrance_y});\n        visited[entrance_x][entrance_y] = true;\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                if (!isValid(nx, ny) || visited[nx][ny]) continue;\n                if (grid[nx][ny] != -2 && !(nx == tx && ny == ty)) continue;\n                \n                if (nx == tx && ny == ty) return true;\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return false;\n    }\n    \n    int getDistance(int x, int y) {\n        if (!isReachable(x, y)) return INT_MAX;\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n        q.push({entrance_x, entrance_y});\n        dist[entrance_x][entrance_y] = 0;\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front();\n            q.pop();\n            \n            if (cx == x && cy == y) return dist[x][y];\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = cx + dx[dir];\n                int ny = cy + dy[dir];\n                \n                if (!isValid(nx, ny) || grid[nx][ny] != -2) continue;\n                if (dist[nx][ny] != INT_MAX) continue;\n                \n                dist[nx][ny] = dist[cx][cy] + 1;\n                q.push({nx, ny});\n            }\n        }\n        \n        return INT_MAX;\n    }\n    \n    pair<int,int> placeContainer(int container_num) {\n        // Find all reachable empty positions\n        vector<pair<int, pair<int,int>>> candidates;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == entrance_x && j == entrance_y) continue;\n                if (grid[i][j] != -2) continue;\n                \n                int dist = getDistance(i, j);\n                if (dist != INT_MAX) {\n                    candidates.push_back({dist, {i, j}});\n                }\n            }\n        }\n        \n        if (candidates.empty()) {\n            // Should not happen in valid test cases\n            return {0, 0};\n        }\n        \n        // Sort by distance\n        sort(candidates.begin(), candidates.end());\n        \n        // Place based on container number relative to total containers\n        int total_containers = D * D - 1 - N;\n        int idx = (container_num * candidates.size()) / total_containers;\n        idx = min(idx, (int)candidates.size() - 1);\n        \n        // Try to place at the calculated index, but also consider nearby positions\n        // to avoid blocking\n        int best_idx = idx;\n        int range = min(5, (int)candidates.size());\n        \n        for (int offset = 0; offset < range; offset++) {\n            for (int sign : {1, -1}) {\n                int test_idx = idx + sign * offset;\n                if (test_idx >= 0 && test_idx < candidates.size()) {\n                    auto [x, y] = candidates[test_idx].second;\n                    \n                    // Check if this placement would block fewer cells\n                    int blocked_count = 0;\n                    grid[x][y] = container_num; // Temporarily place\n                    \n                    for (int i = 0; i < D; i++) {\n                        for (int j = 0; j < D; j++) {\n                            if (grid[i][j] == -2 && !isReachable(i, j)) {\n                                blocked_count++;\n                            }\n                        }\n                    }\n                    \n                    grid[x][y] = -2; // Remove temporary placement\n                    \n                    if (blocked_count <= 2) { // Acceptable blocking\n                        best_idx = test_idx;\n                        goto found;\n                    }\n                }\n            }\n        }\n        \n        found:\n        auto [px, py] = candidates[best_idx].second;\n        grid[px][py] = container_num;\n        containers.push_back({container_num, px, py});\n        \n        return {px, py};\n    }\n    \n    vector<pair<int,int>> getRetrievalOrder() {\n        vector<pair<int,int>> result;\n        vector<bool> retrieved(containers.size(), false);\n        \n        while (result.size() < containers.size()) {\n            int best_idx = -1;\n            int best_number = INT_MAX;\n            \n            // Find the smallest numbered container that's accessible\n            for (int i = 0; i < containers.size(); i++) {\n                if (retrieved[i]) continue;\n                \n                if (isReachable(containers[i].x, containers[i].y)) {\n                    if (containers[i].number < best_number) {\n                        best_number = containers[i].number;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx == -1) {\n                // Should not happen, but fallback to any accessible container\n                for (int i = 0; i < containers.size(); i++) {\n                    if (retrieved[i]) continue;\n                    if (isReachable(containers[i].x, containers[i].y)) {\n                        best_idx = i;\n                        break;\n                    }\n                }\n            }\n            \n            retrieved[best_idx] = true;\n            grid[containers[best_idx].x][containers[best_idx].y] = -2;\n            result.push_back({containers[best_idx].x, containers[best_idx].y});\n        }\n        \n        return result;\n    }\n    \n    void run() {\n        int total_containers = D * D - 1 - N;\n        \n        // Place containers as they arrive\n        for (int i = 0; i < total_containers; i++) {\n            int container_num;\n            cin >> container_num;\n            \n            auto [x, y] = placeContainer(container_num);\n            cout << x << \" \" << y << endl;\n            cout.flush();\n        }\n        \n        // Determine retrieval order\n        auto retrieval_order = getRetrievalOrder();\n        for (auto [x, y] : retrieval_order) {\n            cout << x << \" \" << y << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Warehouse warehouse;\n    warehouse.run();\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\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    // Extract adjacency information\n    set<pair<int, int>> adjacencies;\n    \n    // Check internal adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            // Check right neighbor\n            if (j + 1 < n && grid[i][j] != grid[i][j+1]) {\n                int c1 = min(grid[i][j], grid[i][j+1]);\n                int c2 = max(grid[i][j], grid[i][j+1]);\n                adjacencies.insert({c1, c2});\n            }\n            \n            // Check bottom neighbor\n            if (i + 1 < n && grid[i][j] != grid[i+1][j]) {\n                int c1 = min(grid[i][j], grid[i+1][j]);\n                int c2 = max(grid[i][j], grid[i+1][j]);\n                adjacencies.insert({c1, c2});\n            }\n        }\n    }\n    \n    // Check boundary adjacencies (with color 0)\n    set<int> boundaryWards;\n    for (int i = 0; i < n; i++) {\n        boundaryWards.insert(grid[0][i]);\n        boundaryWards.insert(grid[n-1][i]);\n        boundaryWards.insert(grid[i][0]);\n        boundaryWards.insert(grid[i][n-1]);\n    }\n    \n    for (int ward : boundaryWards) {\n        adjacencies.insert({0, ward});\n    }\n    \n    // Build adjacency list\n    vector<vector<int>> adj(m + 1);\n    for (auto [c1, c2] : adjacencies) {\n        adj[c1].push_back(c2);\n        adj[c2].push_back(c1);\n    }\n    \n    // Create a compact grid representation\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    vector<bool> placed(m + 1, false);\n    placed[0] = true; // Color 0 is implicitly placed\n    \n    // Direction vectors\n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    // Start with boundary wards\n    queue<int> toPlace;\n    for (int ward : boundaryWards) {\n        toPlace.push(ward);\n        placed[ward] = true;\n    }\n    \n    // Place boundary wards near edges\n    int idx = 0;\n    for (int ward : boundaryWards) {\n        if (idx < n/4) {\n            result[1][2 + idx * 2] = ward;\n        } else if (idx < n/2) {\n            result[2 + (idx - n/4) * 2][n-2] = ward;\n        } else if (idx < 3*n/4) {\n            result[n-2][n-3 - (idx - n/2) * 2] = ward;\n        } else {\n            result[n-3 - (idx - 3*n/4) * 2][1] = ward;\n        }\n        idx++;\n        if (idx * 2 >= n) break;\n    }\n    \n    // BFS to place remaining wards based on adjacencies\n    while (!toPlace.empty()) {\n        int ward = toPlace.front();\n        toPlace.pop();\n        \n        for (int neighbor : adj[ward]) {\n            if (!placed[neighbor] && neighbor != 0) {\n                // Find a position adjacent to ward's position\n                bool found = false;\n                for (int i = 0; i < n && !found; i++) {\n                    for (int j = 0; j < n && !found; j++) {\n                        if (result[i][j] == ward) {\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 && result[ni][nj] == 0) {\n                                    result[ni][nj] = neighbor;\n                                    placed[neighbor] = true;\n                                    toPlace.push(neighbor);\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place any remaining wards\n    for (int ward = 1; ward <= m; ward++) {\n        if (!placed[ward]) {\n            // Find empty position, preferably near its neighbors\n            bool found = false;\n            for (int i = 1; i < n-1 && !found; i++) {\n                for (int j = 1; j < n-1 && !found; j++) {\n                    if (result[i][j] == 0) {\n                        result[i][j] = ward;\n                        placed[ward] = true;\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Ensure all required adjacencies exist by expanding regions if needed\n    for (auto [c1, c2] : adjacencies) {\n        if (c1 == 0) continue; // Boundary adjacencies handled by placement\n        \n        // Check if adjacency exists\n        bool adjacent = false;\n        for (int i = 0; i < n && !adjacent; i++) {\n            for (int j = 0; j < n && !adjacent; j++) {\n                if (result[i][j] == c1) {\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 && result[ni][nj] == c2) {\n                            adjacent = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If not adjacent, try to make them adjacent\n        if (!adjacent) {\n            // Find positions of c1 and c2 and try to grow one toward the other\n            vector<pair<int,int>> pos1, pos2;\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (result[i][j] == c1) pos1.push_back({i, j});\n                    if (result[i][j] == c2) pos2.push_back({i, j});\n                }\n            }\n            \n            if (!pos1.empty() && !pos2.empty()) {\n                // Try to extend c1 toward c2\n                int minDist = n * n;\n                int bestX = -1, bestY = -1;\n                for (auto [x1, y1] : pos1) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x1 + dx[d];\n                        int ny = y1 + dy[d];\n                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                            for (auto [x2, y2] : pos2) {\n                                int dist = abs(nx - x2) + abs(ny - y2);\n                                if (dist < minDist) {\n                                    minDist = dist;\n                                    bestX = nx;\n                                    bestY = ny;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (bestX != -1) {\n                    result[bestX][bestY] = c1;\n                }\n            }\n        }\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<double> weight_estimate;\nvector<double> weight_lower, weight_upper;\nvector<vector<int>> comparison_matrix; // -1: i<j, 0: unknown, 1: i>j\n\nchar query(vector<int> left, vector<int> right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid update_bounds_from_comparison(const vector<int>& left, const vector<int>& right, char result) {\n    double left_min = 0, left_max = 0;\n    double right_min = 0, right_max = 0;\n    \n    for (int i : left) {\n        left_min += weight_lower[i];\n        left_max += weight_upper[i];\n    }\n    for (int i : right) {\n        right_min += weight_lower[i];\n        right_max += weight_upper[i];\n    }\n    \n    if (result == '<') {\n        // left_max < right_min ideally\n        if (left_max >= right_min) {\n            double ratio = right_min / left_max;\n            for (int i : left) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : right) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else if (result == '>') {\n        // right_max < left_min ideally\n        if (right_max >= left_min) {\n            double ratio = left_min / right_max;\n            for (int i : right) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : left) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else { // '='\n        // Weights should be equal\n        double avg = (left_min + left_max + right_min + right_max) / 4;\n        double per_item_left = avg / left.size();\n        double per_item_right = avg / right.size();\n        \n        for (int i : left) {\n            weight_estimate[i] = per_item_left;\n            weight_lower[i] = per_item_left * 0.8;\n            weight_upper[i] = per_item_left * 1.2;\n        }\n        for (int i : right) {\n            weight_estimate[i] = per_item_right;\n            weight_lower[i] = per_item_right * 0.8;\n            weight_upper[i] = per_item_right * 1.2;\n        }\n    }\n}\n\ndouble calculate_variance(const vector<vector<int>>& groups) {\n    vector<double> group_sums(D, 0);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            group_sums[g] += weight_estimate[item];\n        }\n    }\n    \n    double mean = 0;\n    for (double s : group_sums) mean += s;\n    mean /= D;\n    \n    double variance = 0;\n    for (double s : group_sums) {\n        variance += (s - mean) * (s - mean);\n    }\n    return variance / D;\n}\n\nvoid local_search(vector<int>& assignment) {\n    vector<double> group_sums(D, 0);\n    vector<vector<int>> groups(D);\n    \n    for (int i = 0; i < N; i++) {\n        groups[assignment[i]].push_back(i);\n        group_sums[assignment[i]] += weight_estimate[i];\n    }\n    \n    bool improved = true;\n    int iterations = 0;\n    while (improved && iterations < 100) {\n        improved = false;\n        iterations++;\n        \n        for (int g1 = 0; g1 < D; g1++) {\n            for (int g2 = g1 + 1; g2 < D; g2++) {\n                // Try swapping items between groups\n                for (int i : groups[g1]) {\n                    for (int j : groups[g2]) {\n                        double curr_diff = abs(group_sums[g1] - group_sums[g2]);\n                        double new_sum_g1 = group_sums[g1] - weight_estimate[i] + weight_estimate[j];\n                        double new_sum_g2 = group_sums[g2] - weight_estimate[j] + weight_estimate[i];\n                        double new_diff = abs(new_sum_g1 - new_sum_g2);\n                        \n                        if (new_diff < curr_diff) {\n                            // Perform swap\n                            assignment[i] = g2;\n                            assignment[j] = g1;\n                            group_sums[g1] = new_sum_g1;\n                            group_sums[g2] = new_sum_g2;\n                            \n                            // Update groups\n                            groups[g1].erase(find(groups[g1].begin(), groups[g1].end(), i));\n                            groups[g1].push_back(j);\n                            groups[g2].erase(find(groups[g2].begin(), groups[g2].end(), j));\n                            groups[g2].push_back(i);\n                            \n                            improved = true;\n                            break;\n                        }\n                    }\n                    if (improved) break;\n                }\n                if (improved) break;\n            }\n            if (improved) break;\n        }\n    }\n}\n\nvoid solve() {\n    cin >> N >> D >> Q;\n    \n    weight_estimate.resize(N, 1000.0);\n    weight_lower.resize(N, 100.0);\n    weight_upper.resize(N, 10000.0);\n    comparison_matrix.resize(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Phase 1: Strategic individual comparisons\n    vector<pair<double, pair<int, int>>> uncertain_pairs;\n    \n    // First, do some initial random sampling to get rough estimates\n    for (int round = 0; round < 3 && queries_used < Q / 3; round++) {\n        for (int i = 0; i < N && queries_used < Q / 3; i++) {\n            int j = (i + 1 + round * 7) % N;\n            if (i != j && comparison_matrix[i][j] == 0) {\n                char result = query({i}, {j});\n                queries_used++;\n                \n                if (result == '<') {\n                    comparison_matrix[i][j] = -1;\n                    comparison_matrix[j][i] = 1;\n                    weight_estimate[i] *= 0.85;\n                    weight_estimate[j] *= 1.15;\n                } else if (result == '>') {\n                    comparison_matrix[i][j] = 1;\n                    comparison_matrix[j][i] = -1;\n                    weight_estimate[i] *= 1.15;\n                    weight_estimate[j] *= 0.85;\n                } else {\n                    weight_estimate[i] = weight_estimate[j] = (weight_estimate[i] + weight_estimate[j]) / 2;\n                }\n                \n                update_bounds_from_comparison({i}, {j}, result);\n            }\n        }\n    }\n    \n    // Phase 2: Group comparisons for refinement\n    while (queries_used < Q * 2 / 3) {\n        vector<pair<double, int>> sorted_items;\n        for (int i = 0; i < N; i++) {\n            sorted_items.push_back({weight_estimate[i], i});\n        }\n        sort(sorted_items.begin(), sorted_items.end());\n        \n        // Compare different percentiles\n        int size = max(2, N / 10);\n        vector<int> light, heavy, mid_low, mid_high;\n        \n        for (int i = 0; i < size && i < N/2; i++) {\n            light.push_back(sorted_items[i].second);\n            heavy.push_back(sorted_items[N - 1 - i].second);\n        }\n        \n        int mid = N / 2;\n        for (int i = max(0, mid - size/2); i < mid && i < N; i++) {\n            mid_low.push_back(sorted_items[i].second);\n        }\n        for (int i = mid; i < min(N, mid + size/2); i++) {\n            mid_high.push_back(sorted_items[i].second);\n        }\n        \n        if (!light.empty() && !heavy.empty()) {\n            char result = query(light, heavy);\n            queries_used++;\n            update_bounds_from_comparison(light, heavy, result);\n        }\n        \n        if (queries_used < Q * 2 / 3 && !mid_low.empty() && !mid_high.empty()) {\n            char result = query(mid_low, mid_high);\n            queries_used++;\n            update_bounds_from_comparison(mid_low, mid_high, result);\n        }\n    }\n    \n    // Initial partitioning\n    vector<pair<double, int>> final_sorted;\n    for (int i = 0; i < N; i++) {\n        final_sorted.push_back({weight_estimate[i], i});\n    }\n    sort(final_sorted.begin(), final_sorted.end(), greater<pair<double, int>>());\n    \n    vector<double> group_sums(D, 0);\n    vector<int> assignment(N);\n    \n    // Greedy assignment\n    for (auto [weight, item] : final_sorted) {\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < group_sums[min_group]) {\n                min_group = g;\n            }\n        }\n        assignment[item] = min_group;\n        group_sums[min_group] += weight;\n    }\n    \n    // Local search optimization\n    local_search(assignment);\n    \n    // Phase 3: Use remaining queries to verify and refine partition\n    vector<vector<int>> final_groups(D);\n    for (int i = 0; i < N; i++) {\n        final_groups[assignment[i]].push_back(i);\n    }\n    \n    while (queries_used < Q && D > 1) {\n        // Compare pairs of groups to verify balance\n        for (int g1 = 0; g1 < D && queries_used < Q; g1++) {\n            for (int g2 = g1 + 1; g2 < D && queries_used < Q; g2++) {\n                if (!final_groups[g1].empty() && !final_groups[g2].empty()) {\n                    // Sample from each group\n                    int sample_size = min(5, min((int)final_groups[g1].size(), (int)final_groups[g2].size()));\n                    vector<int> sample1, sample2;\n                    \n                    for (int i = 0; i < sample_size; i++) {\n                        sample1.push_back(final_groups[g1][i % final_groups[g1].size()]);\n                        sample2.push_back(final_groups[g2][i % final_groups[g2].size()]);\n                    }\n                    \n                    char result = query(sample1, sample2);\n                    queries_used++;\n                    update_bounds_from_comparison(sample1, sample2, result);\n                }\n            }\n        }\n    }\n    \n    // Final local search with updated estimates\n    if (queries_used >= Q * 0.9) {\n        local_search(assignment);\n    }\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}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        int stack_size = n / m;\n        for (int j = 0; j < stack_size; j++) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        // Find current position of target box\n        int target_stack = -1;\n        int target_pos = -1;\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    target_stack = i;\n                    target_pos = j;\n                    break;\n                }\n            }\n            if (target_stack != -1) break;\n        }\n        \n        // If target is not at the top, move boxes above it\n        if (target_pos < (int)stacks[target_stack].size() - 1) {\n            // Collect boxes to be moved\n            vector<int> boxes_to_move;\n            for (int j = target_pos + 1; j < (int)stacks[target_stack].size(); j++) {\n                boxes_to_move.push_back(stacks[target_stack][j]);\n            }\n            \n            // Find the minimum box number among boxes to be moved\n            int min_box = *min_element(boxes_to_move.begin(), boxes_to_move.end());\n            \n            // Find best destination stack\n            int best_dest = -1;\n            int best_score = INT_MAX;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == target_stack) continue;\n                \n                int score = 0;\n                \n                if (stacks[i].empty()) {\n                    // Empty stack is excellent\n                    score = -10000;\n                    // Extra bonus if moving low-numbered boxes to empty\n                    if (min_box <= target + 10) {\n                        score -= 5000;\n                    }\n                } else {\n                    int stack_size = stacks[i].size();\n                    int top_box = stacks[i].back();\n                    \n                    // Base penalty for stack size\n                    score = stack_size * 200;\n                    \n                    // Strong preference for stacks with high-numbered top boxes\n                    if (top_box > target + 50) {\n                        score -= 3000;\n                    } else if (top_box > target + 30) {\n                        score -= 1500;\n                    }\n                    \n                    // Penalty if we're blocking soon-needed boxes\n                    for (int box : stacks[i]) {\n                        if (box <= target + 10) {\n                            score += 500;\n                        }\n                    }\n                    \n                    // Extra penalty if putting low boxes on low boxes\n                    if (min_box <= target + 20 && top_box <= target + 40) {\n                        score += 2000;\n                    }\n                }\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_dest = i;\n                }\n            }\n            \n            // Move all boxes above target to the best destination\n            // The first box in boxes_to_move is the one directly above target\n            operations.push_back({boxes_to_move[0], best_dest + 1});\n            \n            // Update stacks\n            stacks[target_stack].resize(target_pos + 1);\n            for (int box : boxes_to_move) {\n                stacks[best_dest].push_back(box);\n            }\n        }\n        \n        // Carry out the target\n        operations.push_back({target, 0});\n        stacks[target_stack].pop_back();\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nconst int MAX_LENGTH = 100000;\nconst int DIJ[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\nconst char DIR[4] = {'R', 'D', 'L', 'U'};\n\nbool canMove(int i, int j, int dir) {\n    int di = DIJ[dir][0], dj = DIJ[dir][1];\n    int i2 = i + di, j2 = j + dj;\n    \n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    \n    if (di == 0) {\n        return v[i][min(j, j2)] == '0';\n    } else {\n        return h[min(i, i2)][j] == '0';\n    }\n}\n\n// BFS to find shortest path\nvector<int> findPath(int si, int sj, int ei, int ej) {\n    queue<tuple<int, int, vector<int>>> q;\n    set<pair<int, int>> vis;\n    q.push({si, sj, {}});\n    vis.insert({si, sj});\n    \n    while (!q.empty()) {\n        auto [ci, cj, path] = q.front();\n        q.pop();\n        \n        if (ci == ei && cj == ej) {\n            return path;\n        }\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            if (vis.count({ni, nj})) continue;\n            vis.insert({ni, nj});\n            auto newPath = path;\n            newPath.push_back(dir);\n            q.push({ni, nj, newPath});\n        }\n    }\n    return {};\n}\n\nint main() {\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    d.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N - 1; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\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    // Create base route visiting all squares using DFS\n    vector<int> route;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        for (int dir = 0; dir < 4; dir++) {\n            int di = DIJ[dir][0], dj = DIJ[dir][1];\n            int i2 = i + di, j2 = j + dj;\n            \n            if (i2 >= 0 && i2 < N && j2 >= 0 && j2 < N && !visited[i2][j2] && canMove(i, j, dir)) {\n                route.push_back(dir);\n                dfs(i2, j2);\n                route.push_back((dir + 2) % 4);\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Use remaining moves to revisit high-dirt squares\n    if (route.size() < MAX_LENGTH) {\n        // Create priority queue of squares by dirt value\n        priority_queue<tuple<int, int, int>> pq;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != 0 || j != 0) { // Don't add origin\n                    pq.push({d[i][j], i, j});\n                }\n            }\n        }\n        \n        int curI = 0, curJ = 0;\n        \n        // Add extra visits to high-dirt squares\n        while (!pq.empty() && route.size() < MAX_LENGTH - 1000) {\n            auto [dirt, ti, tj] = pq.top();\n            pq.pop();\n            \n            // Find path to target square and back\n            auto pathTo = findPath(curI, curJ, ti, tj);\n            auto pathBack = findPath(ti, tj, 0, 0);\n            \n            if (!pathTo.empty() && !pathBack.empty() && \n                route.size() + pathTo.size() + pathBack.size() <= MAX_LENGTH) {\n                for (int dir : pathTo) route.push_back(dir);\n                for (int dir : pathBack) route.push_back(dir);\n                curI = 0;\n                curJ = 0;\n                \n                // Re-add high-dirt squares for multiple visits\n                if (dirt > 100 && route.size() < MAX_LENGTH - 5000) {\n                    pq.push({dirt / 2, ti, tj});\n                }\n            }\n        }\n    }\n    \n    // Convert route to string\n    string result;\n    for (int dir : route) {\n        result += DIR[dir];\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int i, j;\n};\n\nint manhattan(Position a, Position b) {\n    return abs(a.i - b.i) + abs(a.j - b.j) + 1;\n}\n\nclass SuperstringBuilder {\nprivate:\n    vector<string> words;\n    vector<vector<int>> overlap;\n    int n;\n    \n    int computeOverlap(const string& a, const string& b) {\n        int maxLen = min(a.length(), b.length());\n        for (int len = maxLen; len >= 1; len--) {\n            if (a.substr(a.length() - len) == b.substr(0, len)) {\n                return len;\n            }\n        }\n        return 0;\n    }\n    \n    string mergeTwoStrings(const string& a, const string& b) {\n        int ov = computeOverlap(a, b);\n        return a + b.substr(ov);\n    }\n    \npublic:\n    SuperstringBuilder(vector<string>& w) : words(w), n(w.size()) {\n        overlap.resize(n, vector<int>(n, 0));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (i != j) {\n                    overlap[i][j] = computeOverlap(words[i], words[j]);\n                }\n            }\n        }\n    }\n    \n    // TSP-based approach with branch and bound\n    string buildOptimalSuperstring() {\n        // Remove words that are substrings of others\n        vector<bool> keep(n, true);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (i != j && words[j].find(words[i]) != string::npos) {\n                    keep[i] = false;\n                    break;\n                }\n            }\n        }\n        \n        vector<string> filtered;\n        vector<int> mapping;\n        for (int i = 0; i < n; i++) {\n            if (keep[i]) {\n                filtered.push_back(words[i]);\n                mapping.push_back(i);\n            }\n        }\n        \n        if (filtered.empty()) return \"\";\n        \n        int fn = filtered.size();\n        \n        // For small sets, try all permutations\n        if (fn <= 10) {\n            vector<int> perm(fn);\n            iota(perm.begin(), perm.end(), 0);\n            string best = \"\";\n            \n            do {\n                string current = filtered[perm[0]];\n                for (int i = 1; i < fn; i++) {\n                    int ov = 0;\n                    for (int len = min(current.length(), filtered[perm[i]].length()); len >= 1; len--) {\n                        if (current.substr(current.length() - len) == filtered[perm[i]].substr(0, len)) {\n                            ov = len;\n                            break;\n                        }\n                    }\n                    current += filtered[perm[i]].substr(ov);\n                }\n                if (best.empty() || current.length() < best.length()) {\n                    best = current;\n                }\n            } while (next_permutation(perm.begin(), perm.end()));\n            \n            return best;\n        }\n        \n        // For larger sets, use greedy with multiple restarts\n        string bestResult = \"\";\n        \n        for (int trial = 0; trial < min(20, fn); trial++) {\n            vector<bool> used(fn, false);\n            vector<int> order;\n            \n            // Start with different word each time\n            int start = trial % fn;\n            order.push_back(start);\n            used[start] = true;\n            \n            while (order.size() < fn) {\n                int last = order.back();\n                int bestNext = -1;\n                int bestOverlap = -1;\n                \n                // Find best next word based on overlap\n                for (int i = 0; i < fn; i++) {\n                    if (!used[i]) {\n                        int ov = 0;\n                        string& a = filtered[last];\n                        string& b = filtered[i];\n                        for (int len = min(a.length(), b.length()); len >= 1; len--) {\n                            if (a.substr(a.length() - len) == b.substr(0, len)) {\n                                ov = len;\n                                break;\n                            }\n                        }\n                        if (ov > bestOverlap) {\n                            bestOverlap = ov;\n                            bestNext = i;\n                        }\n                    }\n                }\n                \n                if (bestNext == -1) {\n                    for (int i = 0; i < fn; i++) {\n                        if (!used[i]) {\n                            bestNext = i;\n                            break;\n                        }\n                    }\n                }\n                \n                order.push_back(bestNext);\n                used[bestNext] = true;\n            }\n            \n            // Build result\n            string result = filtered[order[0]];\n            for (int i = 1; i < fn; i++) {\n                int ov = 0;\n                string& a = filtered[order[i-1]];\n                string& b = filtered[order[i]];\n                for (int len = min(a.length(), b.length()); len >= 1; len--) {\n                    if (a.substr(a.length() - len) == b.substr(0, len)) {\n                        ov = len;\n                        break;\n                    }\n                }\n                result += b.substr(ov);\n            }\n            \n            if (bestResult.empty() || result.length() < bestResult.length()) {\n                bestResult = result;\n            }\n        }\n        \n        // Add back any missing original words\n        for (const string& w : words) {\n            if (bestResult.find(w) == string::npos) {\n                // Try to merge it optimally\n                int bestPos = bestResult.length();\n                int bestSaving = 0;\n                \n                for (int pos = 0; pos <= bestResult.length(); pos++) {\n                    int prefixOverlap = 0;\n                    int suffixOverlap = 0;\n                    \n                    if (pos > 0) {\n                        for (int len = min((int)w.length(), pos); len >= 1; len--) {\n                            if (bestResult.substr(pos - len, len) == w.substr(0, len)) {\n                                prefixOverlap = len;\n                                break;\n                            }\n                        }\n                    }\n                    \n                    if (pos < bestResult.length()) {\n                        for (int len = min((int)w.length(), (int)bestResult.length() - pos); len >= 1; len--) {\n                            if (w.substr(w.length() - len) == bestResult.substr(pos, len)) {\n                                suffixOverlap = len;\n                                break;\n                            }\n                        }\n                    }\n                    \n                    int saving = prefixOverlap + suffixOverlap;\n                    if (saving > bestSaving) {\n                        bestSaving = saving;\n                        bestPos = pos;\n                    }\n                }\n                \n                if (bestSaving > 0) {\n                    // Insert with overlap\n                    bestResult = bestResult.substr(0, bestPos) + w + bestResult.substr(bestPos);\n                } else {\n                    // Just append\n                    bestResult += w;\n                }\n            }\n        }\n        \n        return bestResult;\n    }\n};\n\nclass PathOptimizer {\nprivate:\n    vector<vector<Position>> charPositions;\n    Position startPos;\n    \npublic:\n    PathOptimizer(const vector<vector<Position>>& cp, Position sp) \n        : charPositions(cp), startPos(sp) {}\n    \n    vector<pair<int, int>> findOptimalPath(const string& s) {\n        int n = s.length();\n        if (n == 0) return {};\n        \n        // For each position in string, for each keyboard position, store min cost\n        vector<vector<int>> dp(n);\n        vector<vector<int>> parent(n);\n        \n        for (int i = 0; i < n; i++) {\n            int charIdx = s[i] - 'A';\n            int numPos = charPositions[charIdx].size();\n            dp[i].resize(numPos, INT_MAX);\n            parent[i].resize(numPos, -1);\n        }\n        \n        // Initialize first character\n        int firstCharIdx = s[0] - 'A';\n        for (int j = 0; j < charPositions[firstCharIdx].size(); j++) {\n            dp[0][j] = manhattan(startPos, charPositions[firstCharIdx][j]);\n        }\n        \n        // Fill DP table\n        for (int i = 1; i < n; i++) {\n            int currCharIdx = s[i] - 'A';\n            int prevCharIdx = s[i-1] - 'A';\n            \n            for (int j = 0; j < charPositions[currCharIdx].size(); j++) {\n                Position currPos = charPositions[currCharIdx][j];\n                \n                for (int k = 0; k < charPositions[prevCharIdx].size(); k++) {\n                    Position prevPos = charPositions[prevCharIdx][k];\n                    int cost = dp[i-1][k] + manhattan(prevPos, currPos);\n                    \n                    if (cost < dp[i][j]) {\n                        dp[i][j] = cost;\n                        parent[i][j] = k;\n                    }\n                }\n            }\n        }\n        \n        // Find best ending position\n        int bestEnd = 0;\n        int minCost = dp[n-1][0];\n        for (int j = 1; j < dp[n-1].size(); j++) {\n            if (dp[n-1][j] < minCost) {\n                minCost = dp[n-1][j];\n                bestEnd = j;\n            }\n        }\n        \n        // Reconstruct path\n        vector<int> choices(n);\n        choices[n-1] = bestEnd;\n        for (int i = n-1; i > 0; i--) {\n            choices[i-1] = parent[i][choices[i]];\n        }\n        \n        // Build result\n        vector<pair<int, int>> result;\n        for (int i = 0; i < n; i++) {\n            int charIdx = s[i] - 'A';\n            Position pos = charPositions[charIdx][choices[i]];\n            result.push_back({pos.i, pos.j});\n        }\n        \n        return result;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    vector<vector<Position>> charPositions(26);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            charPositions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n    \n    vector<string> words(M);\n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    // Build optimal superstring\n    SuperstringBuilder builder(words);\n    string superstring = builder.buildOptimalSuperstring();\n    \n    // Ensure we don't exceed length limit\n    if (superstring.length() > 4500) {\n        // Fallback to simple concatenation of unique words\n        set<string> uniqueWords(words.begin(), words.end());\n        superstring = \"\";\n        for (const string& w : uniqueWords) {\n            bool isSubstring = false;\n            for (const string& other : uniqueWords) {\n                if (w != other && other.find(w) != string::npos) {\n                    isSubstring = true;\n                    break;\n                }\n            }\n            if (!isSubstring) {\n                superstring += w;\n            }\n        }\n    }\n    \n    // Find optimal typing path\n    PathOptimizer optimizer(charPositions, {si, sj});\n    vector<pair<int, int>> moves = optimizer.findOptimalPath(superstring);\n    \n    // Output moves\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int i, j;\n    bool operator<(const Point& o) const { return tie(i,j) < tie(o.i,o.j); }\n    bool operator==(const Point& o) const { return i == o.i && j == o.j; }\n};\n\nclass OilExplorer {\n    int N, M;\n    double eps;\n    vector<vector<Point>> oilShapes;\n    vector<vector<int>> drilled; // -1=unknown, >=0=drilled value\n    set<Point> confirmedOil;\n    int operationCount = 0;\n    int maxOperations;\n    \n    double getCost(int numSquares) {\n        if (numSquares == 1) return 1.0;\n        return 1.0 / sqrt(numSquares);\n    }\n    \n    int queryDrill(int i, int j) {\n        if (i < 0 || i >= N || j < 0 || j >= N) return 0;\n        if (drilled[i][j] != -1) return drilled[i][j];\n        \n        cout << \"q 1 \" << i << \" \" << j << endl;\n        cout.flush();\n        \n        int v;\n        if (!(cin >> v)) return 0;\n        \n        drilled[i][j] = v;\n        if (v > 0) confirmedOil.insert({i, j});\n        operationCount++;\n        return v;\n    }\n    \n    int queryDivine(const vector<Point>& pts) {\n        if (pts.size() < 2) return 0;\n        \n        cout << \"q \" << pts.size();\n        for (const auto& p : pts) {\n            cout << \" \" << p.i << \" \" << p.j;\n        }\n        cout << endl;\n        cout.flush();\n        \n        int v;\n        if (!(cin >> v)) return 0;\n        \n        operationCount++;\n        return v;\n    }\n    \n    bool submitAnswer() {\n        if (confirmedOil.empty()) {\n            // If no oil found, still need to submit something\n            cout << \"a 0\" << endl;\n        } else {\n            cout << \"a \" << confirmedOil.size();\n            for (const auto& p : confirmedOil) {\n                cout << \" \" << p.i << \" \" << p.j;\n            }\n            cout << endl;\n        }\n        cout.flush();\n        \n        int result;\n        if (!(cin >> result)) return false;\n        return result == 1;\n    }\n    \n    void exploreGrid() {\n        // Phase 1: Coarse grid divination\n        int gridSize = max(3, N/4);\n        vector<vector<Point>> grids;\n        vector<int> gridResults;\n        \n        for (int gi = 0; gi < N; gi += gridSize) {\n            for (int gj = 0; gj < N; gj += gridSize) {\n                vector<Point> grid;\n                for (int i = gi; i < min(N, gi + gridSize); i++) {\n                    for (int j = gj; j < min(N, gj + gridSize); j++) {\n                        if (drilled[i][j] == -1) {\n                            grid.push_back({i, j});\n                        }\n                    }\n                }\n                \n                if (grid.size() >= 2 && operationCount < maxOperations - 50) {\n                    int result = queryDivine(grid);\n                    grids.push_back(grid);\n                    gridResults.push_back(result);\n                }\n            }\n        }\n        \n        // Phase 2: Focus on promising grids\n        for (int g = 0; g < grids.size(); g++) {\n            // Consider noise - explore even if result is low\n            double threshold = grids[g].size() * eps * 2;\n            if (gridResults[g] > threshold || gridResults[g] > 0) {\n                exploreRegion(grids[g], gridResults[g]);\n            }\n        }\n        \n        // Phase 3: Pattern matching and filling gaps\n        fillGapsWithPatternMatching();\n        \n        // Phase 4: Final drilling for uncertain areas\n        finalDrilling();\n    }\n    \n    void exploreRegion(const vector<Point>& region, int hint) {\n        if (region.size() <= 3 || operationCount >= maxOperations - 20) {\n            // Small region - drill directly\n            for (const auto& p : region) {\n                if (drilled[p.i][p.j] == -1 && operationCount < maxOperations - 10) {\n                    queryDrill(p.i, p.j);\n                }\n            }\n            return;\n        }\n        \n        // Binary split\n        vector<Point> left, right;\n        for (size_t i = 0; i < region.size(); i++) {\n            if (i < region.size() / 2) left.push_back(region[i]);\n            else right.push_back(region[i]);\n        }\n        \n        if (left.size() >= 2 && operationCount < maxOperations - 30) {\n            int leftSum = queryDivine(left);\n            if (leftSum > 0 || leftSum > left.size() * eps) {\n                exploreRegion(left, leftSum);\n            }\n        }\n        \n        if (right.size() >= 2 && operationCount < maxOperations - 30) {\n            int rightSum = queryDivine(right);\n            if (rightSum > 0 || rightSum > right.size() * eps) {\n                exploreRegion(right, rightSum);\n            }\n        }\n    }\n    \n    void fillGapsWithPatternMatching() {\n        // Check areas adjacent to confirmed oil\n        set<Point> candidates;\n        for (const auto& oil : confirmedOil) {\n            for (int di = -2; di <= 2; di++) {\n                for (int dj = -2; dj <= 2; dj++) {\n                    int ni = oil.i + di;\n                    int nj = oil.j + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && drilled[ni][nj] == -1) {\n                        candidates.insert({ni, nj});\n                    }\n                }\n            }\n        }\n        \n        // Drill high-priority candidates\n        for (const auto& p : candidates) {\n            if (operationCount >= maxOperations - 10) break;\n            queryDrill(p.i, p.j);\n        }\n    }\n    \n    void finalDrilling() {\n        // Do a final pass with remaining operations\n        for (int i = 0; i < N && operationCount < maxOperations - 5; i++) {\n            for (int j = 0; j < N && operationCount < maxOperations - 5; j++) {\n                if (drilled[i][j] == -1) {\n                    // Check if likely to have oil based on surroundings\n                    int adjacentOil = 0;\n                    for (int di = -1; di <= 1; di++) {\n                        for (int dj = -1; dj <= 1; dj++) {\n                            if (di == 0 && dj == 0) continue;\n                            int ni = i + di, nj = j + dj;\n                            if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                                if (drilled[ni][nj] > 0) adjacentOil++;\n                            }\n                        }\n                    }\n                    \n                    if (adjacentOil >= 2) {\n                        queryDrill(i, j);\n                    }\n                }\n            }\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> M >> eps;\n        \n        oilShapes.resize(M);\n        for (int m = 0; m < M; m++) {\n            int d; \n            cin >> d;\n            oilShapes[m].resize(d);\n            for (int k = 0; k < d; k++) {\n                cin >> oilShapes[m][k].i >> oilShapes[m][k].j;\n            }\n        }\n        \n        maxOperations = 2 * N * N;\n        drilled.assign(N, vector<int>(N, -1));\n        \n        exploreGrid();\n        \n        // Submit answer with retry\n        int attempts = 0;\n        while (!submitAnswer() && attempts < 3 && operationCount < maxOperations) {\n            attempts++;\n            \n            // Drill a few more uncertain squares\n            for (int i = 0; i < N && operationCount < maxOperations - 2; i++) {\n                for (int j = 0; j < N && operationCount < maxOperations - 2; j++) {\n                    if (drilled[i][j] == -1) {\n                        queryDrill(i, j);\n                        break;\n                    }\n                }\n                if (operationCount >= maxOperations - 2) break;\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    OilExplorer explorer;\n    explorer.solve();\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Calculate maximum area requirement for each reservation position\n    vector<int> max_areas(N);\n    for (int k = 0; k < N; k++) {\n        max_areas[k] = 0;\n        for (int d = 0; d < D; d++) {\n            max_areas[k] = max(max_areas[k], a[d][k]);\n        }\n    }\n    \n    // Strategy: Use horizontal strips with heights based on max requirements\n    // This ensures we can always accommodate the area needs\n    \n    vector<int> heights(N);\n    vector<int> y_start(N);\n    \n    // Calculate heights proportional to sqrt of max areas\n    // This gives better aspect ratios\n    vector<double> target_heights(N);\n    double total_target = 0;\n    \n    for (int k = 0; k < N; k++) {\n        // Use sqrt for better aspect ratio\n        target_heights[k] = sqrt((double)max_areas[k]);\n        total_target += target_heights[k];\n    }\n    \n    // Scale to fit in W height\n    int used_height = 0;\n    for (int k = 0; k < N; k++) {\n        if (k == N - 1) {\n            // Last one gets remaining height\n            heights[k] = W - used_height;\n        } else {\n            // Proportional allocation\n            double proportion = target_heights[k] / total_target;\n            heights[k] = max(1, (int)(W * proportion));\n            \n            // Ensure we can fit the max area with width W\n            int min_height = (max_areas[k] + W - 1) / W;\n            heights[k] = max(heights[k], min_height);\n            \n            // Don't exceed available space\n            heights[k] = min(heights[k], W - used_height - (N - k - 1));\n        }\n        \n        y_start[k] = used_height;\n        used_height += heights[k];\n    }\n    \n    // Adjust if we exceeded W (shouldn't happen with proper calculation)\n    if (used_height > W) {\n        // Scale down proportionally\n        double scale = (double)W / used_height;\n        used_height = 0;\n        for (int k = 0; k < N; k++) {\n            if (k == N - 1) {\n                heights[k] = W - used_height;\n            } else {\n                heights[k] = max(1, (int)(heights[k] * scale));\n            }\n            y_start[k] = used_height;\n            used_height += heights[k];\n        }\n    }\n    \n    // Output rectangles for each day\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            // Calculate required width for this day\n            int width = (a[d][k] + heights[k] - 1) / heights[k]; // Ceiling division\n            width = min(width, W); // Cap at grid width\n            \n            // Output: top-left to bottom-right\n            cout << y_start[k] << \" \" << 0 << \" \" \n                 << (y_start[k] + heights[k]) << \" \" << width << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<long long>>> stamps(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    mt19937 rng(42);\n    \n    // Use all K operations\n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        // Try all possible stamps and positions\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                    // Calculate the score for this operation\n                    double score = 0;\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long old_val = board[p + i][q + j];\n                            long long new_val = old_val + stamps[m][i][j];\n                            \n                            // Direct score increase\n                            long long old_mod = old_val % MOD;\n                            long long new_mod = new_val % MOD;\n                            score += new_mod - old_mod;\n                            \n                            // Bonus for getting closer to MOD-1 without going over\n                            if (new_val < MOD) {\n                                // Reward getting closer to MOD-1\n                                double distance_bonus = 1.0 / (1.0 + (MOD - 1 - new_val));\n                                score += distance_bonus * 100000;\n                            } else if (new_val >= MOD && old_val < MOD) {\n                                // Penalty for wrapping around from a high value\n                                score -= (old_mod / 1000.0);\n                            }\n                            \n                            // Small bonus for values in the sweet spot (90-99% of MOD)\n                            if (new_mod > 0.9 * MOD && new_mod < MOD) {\n                                score += 1000;\n                            }\n                        }\n                    }\n                    \n                    // Add small random perturbation to escape local optima\n                    score += uniform_real_distribution<double>(-0.01, 0.01)(rng);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation (even if score is not positive)\n        if (best_m != -1) {\n            operations.push_back({best_m, best_p, best_q});\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n        } else {\n            // If no operation found (shouldn't happen), pick random\n            int m = uniform_int_distribution<int>(0, M-1)(rng);\n            int p = uniform_int_distribution<int>(0, N-3)(rng);\n            int q = uniform_int_distribution<int>(0, N-3)(rng);\n            operations.push_back({m, p, q});\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[p + i][q + j] += stamps[m][i][j];\n                }\n            }\n        }\n    }\n    \n    // Output the operations\n    cout << operations.size() << \"\\n\";\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 2000;\n\nstruct Position {\n    int r, c;\n    bool operator==(const Position& other) const {\n        return r == other.r && c == other.c;\n    }\n};\n\nstruct State {\n    vector<vector<int>> grid; // -1 if empty, container number otherwise\n    vector<Position> crane_pos;\n    vector<int> crane_holding; // -1 if not holding\n    vector<int> next_receive; // next container index to receive at each gate\n    vector<int> next_dispatch; // next expected container at each dispatch gate\n    vector<queue<int>> receiving_queues; // containers waiting at each receiving gate\n    \n    State(const vector<vector<int>>& A) : \n        grid(N, vector<int>(N, -1)),\n        crane_pos(N),\n        crane_holding(N, -1),\n        next_receive(N, 0),\n        next_dispatch(N),\n        receiving_queues(N) {\n        \n        // Initialize crane positions\n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n        }\n        \n        // Initialize dispatch expectations\n        for (int i = 0; i < N; i++) {\n            next_dispatch[i] = i * N;\n        }\n        \n        // Initialize receiving queues\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                receiving_queues[i].push(A[i][j]);\n            }\n        }\n    }\n    \n    bool canMove(int crane, Position newPos, bool isLarge) {\n        if (newPos.r < 0 || newPos.r >= N || newPos.c < 0 || newPos.c >= N) return false;\n        \n        // Check for crane collision\n        for (int i = 0; i < N; i++) {\n            if (i != crane && crane_pos[i] == newPos) return false;\n        }\n        \n        // If small crane carrying container, can't move to occupied square\n        if (!isLarge && crane_holding[crane] != -1 && grid[newPos.r][newPos.c] != -1) {\n            return false;\n        }\n        \n        return true;\n    }\n};\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state(A);\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        vector<char> actions(N, '.');\n        \n        // Step 1: Receive containers\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty() && \n                state.grid[i][0] == -1) {\n                bool crane_holding_here = false;\n                for (int j = 0; j < N; j++) {\n                    if (state.crane_pos[j].r == i && state.crane_pos[j].c == 0 && \n                        state.crane_holding[j] != -1) {\n                        crane_holding_here = true;\n                        break;\n                    }\n                }\n                if (!crane_holding_here) {\n                    state.grid[i][0] = state.receiving_queues[i].front();\n                    state.receiving_queues[i].pop();\n                }\n            }\n        }\n        \n        // Step 2: Decide crane actions\n        for (int crane = 0; crane < N; crane++) {\n            bool isLarge = (crane == 0);\n            Position pos = state.crane_pos[crane];\n            \n            // If holding a container\n            if (state.crane_holding[crane] != -1) {\n                int container = state.crane_holding[crane];\n                int target_row = container / N;\n                \n                // Try to move towards target dispatch gate\n                if (pos.c < N - 1) {\n                    Position newPos = {pos.r, pos.c + 1};\n                    if (state.canMove(crane, newPos, isLarge)) {\n                        actions[crane] = 'R';\n                    } else if (pos.r < target_row) {\n                        newPos = {pos.r + 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'D';\n                        }\n                    } else if (pos.r > target_row) {\n                        newPos = {pos.r - 1, pos.c};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'U';\n                        }\n                    }\n                } else if (pos.c == N - 1 && pos.r == target_row) {\n                    // At dispatch gate\n                    if (state.grid[pos.r][pos.c] == -1) {\n                        actions[crane] = 'Q';\n                    }\n                }\n            } else {\n                // Not holding container\n                // Try to pick up if at a position with container\n                if (state.grid[pos.r][pos.c] != -1) {\n                    actions[crane] = 'P';\n                } else {\n                    // Move towards receiving gates\n                    if (pos.c > 0) {\n                        Position newPos = {pos.r, pos.c - 1};\n                        if (state.canMove(crane, newPos, isLarge)) {\n                            actions[crane] = 'L';\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Execute actions\n        vector<Position> new_positions = state.crane_pos;\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            Position& pos = state.crane_pos[crane];\n            \n            if (action == 'P') {\n                if (state.grid[pos.r][pos.c] != -1 && state.crane_holding[crane] == -1) {\n                    state.crane_holding[crane] = state.grid[pos.r][pos.c];\n                    state.grid[pos.r][pos.c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (state.crane_holding[crane] != -1 && state.grid[pos.r][pos.c] == -1) {\n                    state.grid[pos.r][pos.c] = state.crane_holding[crane];\n                    state.crane_holding[crane] = -1;\n                }\n            } else if (action == 'U') {\n                new_positions[crane] = {pos.r - 1, pos.c};\n            } else if (action == 'D') {\n                new_positions[crane] = {pos.r + 1, pos.c};\n            } else if (action == 'L') {\n                new_positions[crane] = {pos.r, pos.c - 1};\n            } else if (action == 'R') {\n                new_positions[crane] = {pos.r, pos.c + 1};\n            }\n            \n            commands[crane] += action;\n        }\n        state.crane_pos = new_positions;\n        \n        // Step 3: Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (state.grid[i][N-1] != -1) {\n                state.grid[i][N-1] = -1;\n            }\n        }\n        \n        // Check if all done\n        bool all_done = true;\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty()) {\n                all_done = false;\n                break;\n            }\n        }\n        if (all_done) {\n            bool grid_empty = true;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (state.grid[i][j] != -1) {\n                        grid_empty = false;\n                        break;\n                    }\n                }\n            }\n            if (grid_empty) break;\n        }\n    }\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <set>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_OPS = 100000;\nconst int INF = 1e9;\n\nvector<string> operations;\nint grid[N][N];\nint cur_r = 0, cur_c = 0;\nint loaded = 0;\n\n// Direction vectors\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct Task {\n    int sr, sc, dr, dc, amount;\n    double efficiency;\n    bool operator<(const Task& other) const {\n        return efficiency > other.efficiency; // Higher efficiency first\n    }\n};\n\n// BFS to find shortest path\nvector<int> find_path(int sr, int sc, int tr, int tc) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    \n    dist[sr][sc] = 0;\n    q.push({sr, sc});\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        \n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == INF) {\n                dist[nr][nc] = dist[r][c] + 1;\n                parent[nr][nc] = d;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path;\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int d = parent[r][c];\n        path.push_back(d);\n        r -= dr[d];\n        c -= dc[d];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Move to target location\nvoid move_to(int tr, int tc) {\n    if (cur_r == tr && cur_c == tc) return;\n    \n    vector<int> path = find_path(cur_r, cur_c, tr, tc);\n    for (int d : path) {\n        operations.push_back(string(1, dir_char[d]));\n        cur_r += dr[d];\n        cur_c += dc[d];\n    }\n}\n\n// Load soil from current position\nvoid load_soil(int amount) {\n    if (amount <= 0 || grid[cur_r][cur_c] <= 0) return;\n    amount = min(amount, grid[cur_r][cur_c]);\n    operations.push_back(\"+\" + to_string(amount));\n    grid[cur_r][cur_c] -= amount;\n    loaded += amount;\n}\n\n// Unload soil to current position  \nvoid unload_soil(int amount) {\n    if (amount <= 0 || loaded <= 0 || grid[cur_r][cur_c] >= 0) return;\n    amount = min(amount, min(loaded, -grid[cur_r][cur_c]));\n    operations.push_back(\"-\" + to_string(amount));\n    grid[cur_r][cur_c] += amount;\n    loaded -= amount;\n}\n\n// Unload all to current position (handles both positive and negative targets)\nvoid unload_all() {\n    if (loaded <= 0) return;\n    int amount = min(loaded, -grid[cur_r][cur_c]);\n    if (amount > 0) {\n        operations.push_back(\"-\" + to_string(amount));\n        grid[cur_r][cur_c] += amount;\n        loaded -= amount;\n    }\n}\n\nint manhattan_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\n// Calculate efficiency score for a transport task\ndouble calc_efficiency(int sr, int sc, int dr, int dc, int amount, int curr_r, int curr_c) {\n    int dist_to_src = manhattan_dist(curr_r, curr_c, sr, sc);\n    int transport_dist = manhattan_dist(sr, sc, dr, dc);\n    int total_dist = dist_to_src + transport_dist;\n    \n    // Cost = load + unload + movement\n    int cost = 2 * amount + dist_to_src * 100 + transport_dist * (100 + amount);\n    \n    // Efficiency = amount transported / estimated cost\n    // Higher is better\n    return (double)amount / (double)cost;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    // Read grid\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    // Main processing loop\n    while (operations.size() < MAX_OPS - 1000) {\n        // Find all tasks\n        vector<Task> tasks;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] > 0) {\n                    // Find all possible destinations for this source\n                    for (int di = 0; di < N; di++) {\n                        for (int dj = 0; dj < N; dj++) {\n                            if (grid[di][dj] < 0) {\n                                int amount = min(grid[i][j], -grid[di][dj]);\n                                double eff = calc_efficiency(i, j, di, dj, amount, cur_r, cur_c);\n                                tasks.push_back({i, j, di, dj, amount, eff});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (tasks.empty()) break;\n        \n        // Sort by efficiency\n        sort(tasks.begin(), tasks.end());\n        \n        // Execute the best task\n        Task best = tasks[0];\n        \n        // Move to source\n        move_to(best.sr, best.sc);\n        \n        // Load what we can\n        int to_load = min(grid[best.sr][best.sc], best.amount);\n        if (to_load > 0) {\n            load_soil(to_load);\n            \n            // Move to destination\n            move_to(best.dr, best.dc);\n            \n            // Unload\n            unload_all();\n        }\n        \n        // Check if done\n        bool all_zero = true;\n        for (int i = 0; i < N && all_zero; i++) {\n            for (int j = 0; j < N && all_zero; j++) {\n                if (grid[i][j] != 0) all_zero = false;\n            }\n        }\n        if (all_zero) break;\n    }\n    \n    // If there's still loaded soil at the end, try to unload it\n    if (loaded > 0) {\n        for (int i = 0; i < N && loaded > 0; i++) {\n            for (int j = 0; j < N && loaded > 0; j++) {\n                if (grid[i][j] < 0) {\n                    move_to(i, j);\n                    unload_all();\n                }\n            }\n        }\n    }\n    \n    // Output operations\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 <random>\n#include <numeric>\n#include <set>\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));\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    random_device rd;\n    mt19937 gen(rd());\n    \n    // Track global best values\n    vector<int> global_max_traits(M, 0);\n    \n    for (int t = 0; t < T; t++) {\n        // Update global max traits\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                global_max_traits[j] = max(global_max_traits[j], X[i][j]);\n            }\n        }\n        \n        // Calculate seed values and statistics\n        vector<int> seed_values(seed_count);\n        vector<double> seed_scores(seed_count);\n        \n        // Get trait statistics\n        vector<vector<int>> trait_values(M);\n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += X[i][j];\n                trait_values[j].push_back(X[i][j]);\n            }\n        }\n        \n        // Calculate percentiles\n        vector<int> p80(M), p60(M);\n        for (int j = 0; j < M; j++) {\n            sort(trait_values[j].begin(), trait_values[j].end());\n            p60[j] = trait_values[j][3*seed_count/5];\n            p80[j] = trait_values[j][4*seed_count/5];\n        }\n        \n        // Score seeds\n        for (int i = 0; i < seed_count; i++) {\n            double score = seed_values[i];\n            \n            // Count strong traits\n            int strong_traits = 0;\n            int elite_traits = 0;\n            double min_trait = 1000.0;\n            double variance = 0.0;\n            double mean = (double)seed_values[i] / M;\n            \n            for (int j = 0; j < M; j++) {\n                if (X[i][j] >= p60[j]) strong_traits++;\n                if (X[i][j] >= p80[j]) elite_traits++;\n                min_trait = min(min_trait, (double)X[i][j]);\n                variance += pow(X[i][j] - mean, 2);\n            }\n            variance /= M;\n            \n            // Reward balanced excellence\n            score += min_trait * 2.0;  // Bonus for high minimum\n            score -= sqrt(variance) * 0.5;  // Penalty for high variance\n            score += elite_traits * 20.0;  // Bonus for elite traits\n            \n            // Special bonus for seeds close to perfection\n            if (min_trait > mean * 0.8) {\n                score *= 1.1;\n            }\n            \n            seed_scores[i] = score;\n        }\n        \n        // Create sorted list\n        vector<pair<double, int>> scored_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            scored_seeds.push_back({seed_scores[i], i});\n        }\n        sort(scored_seeds.begin(), scored_seeds.end(), greater<pair<double,int>>());\n        \n        // Select seeds for planting\n        vector<int> selected_seeds;\n        set<int> used;\n        \n        if (t < 2) {\n            // Early: Mix top seeds with diverse ones\n            // Take top 60%\n            int elite_count = (N * N * 3) / 5;\n            for (int i = 0; i < elite_count; i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n            \n            // Add random diverse seeds\n            vector<int> remaining;\n            for (int i = elite_count; i < seed_count; i++) {\n                if (used.find(scored_seeds[i].second) == used.end()) {\n                    remaining.push_back(scored_seeds[i].second);\n                }\n            }\n            \n            shuffle(remaining.begin(), remaining.end(), gen);\n            for (int i = 0; selected_seeds.size() < N*N && i < remaining.size(); i++) {\n                selected_seeds.push_back(remaining[i]);\n                used.insert(remaining[i]);\n            }\n            \n            // Shuffle for diversity\n            shuffle(selected_seeds.begin(), selected_seeds.end(), gen);\n            \n        } else if (t < T - 3) {\n            // Middle: Focus on good seeds with some variation\n            for (int i = 0; i < N*N && i < scored_seeds.size(); i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n            \n            // Slight randomization to avoid local optima\n            if (t % 2 == 0) {\n                // Swap a few seeds randomly\n                uniform_int_distribution<> dis(0, N*N-1);\n                for (int i = 0; i < 3; i++) {\n                    int idx1 = dis(gen);\n                    int idx2 = dis(gen);\n                    if (idx1 != idx2) {\n                        swap(selected_seeds[idx1], selected_seeds[idx2]);\n                    }\n                }\n            }\n            \n        } else {\n            // Final: Pure exploitation of best seeds\n            for (int i = 0; i < N*N && i < scored_seeds.size(); i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n        }\n        \n        // Ensure we have exactly N*N seeds\n        while (selected_seeds.size() < N*N) {\n            for (int i = 0; i < seed_count && selected_seeds.size() < N*N; i++) {\n                if (used.find(i) == used.end()) {\n                    selected_seeds.push_back(i);\n                    used.insert(i);\n                }\n            }\n        }\n        \n        // Place seeds on grid\n        vector<vector<int>> A(N, vector<int>(N));\n        \n        if (t >= T - 3) {\n            // Final generations: Place best seeds in center\n            vector<pair<int, pair<int,int>>> positions;\n            \n            // Calculate distance from center for each position\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double center_i = (N - 1) / 2.0;\n                    double center_j = (N - 1) / 2.0;\n                    double dist = abs(i - center_i) + abs(j - center_j);\n                    positions.push_back({dist, {i, j}});\n                }\n            }\n            \n            // Sort by distance (closest to center first)\n            sort(positions.begin(), positions.end());\n            \n            // Place best seeds in center positions\n            for (int k = 0; k < N*N; k++) {\n                int i = positions[k].second.first;\n                int j = positions[k].second.second;\n                A[i][j] = selected_seeds[k];\n            }\n            \n        } else if (t >= 3 && t < T - 3) {\n            // Middle generations: Strategic pairing\n            // Try to place complementary seeds adjacent\n            \n            // Calculate complementarity scores\n            vector<vector<double>> complement(N*N, vector<double>(N*N, 0));\n            for (int i = 0; i < N*N; i++) {\n                for (int j = i+1; j < N*N; j++) {\n                    int s1 = selected_seeds[i];\n                    int s2 = selected_seeds[j];\n                    \n                    // Seeds complement if they have different strengths\n                    double comp_score = 0;\n                    for (int k = 0; k < M; k++) {\n                        comp_score += max(X[s1][k], X[s2][k]);\n                        // Bonus if they excel in different traits\n                        if ((X[s1][k] >= p80[k]) != (X[s2][k] >= p80[k])) {\n                            comp_score += 10;\n                        }\n                    }\n                    complement[i][j] = complement[j][i] = comp_score;\n                }\n            }\n            \n            // Greedy placement with complementarity consideration\n            vector<bool> placed(N*N, false);\n            int placed_count = 0;\n            \n            // Start with best seed in center\n            A[N/2][N/2] = selected_seeds[0];\n            placed[0] = true;\n            placed_count = 1;\n            \n            // Greedily place remaining seeds\n            while (placed_count < N*N) {\n                double best_score = -1;\n                int best_seed_idx = -1;\n                int best_i = -1, best_j = -1;\n                \n                for (int idx = 0; idx < N*N; idx++) {\n                    if (placed[idx]) continue;\n                    \n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            if (A[i][j] != 0 && !placed[A[i][j]]) continue;  // Skip filled positions\n                            if (A[i][j] == 0) {\n                                // Empty position - calculate score based on neighbors\n                                double score = seed_scores[selected_seeds[idx]];\n                                int neighbor_count = 0;\n                                \n                                // Check all neighbors\n                                if (i > 0 && A[i-1][j] != 0) {\n                                    for (int k = 0; k < N*N; k++) {\n                                        if (selected_seeds[k] == A[i-1][j] && placed[k]) {\n                                            score += complement[idx][k] / 100;\n                                            neighbor_count++;\n                                            break;\n                                        }\n                                    }\n                                }\n                                if (i < N-1 && A[i+1][j] != 0) {\n                                    for (int k = 0; k < N*N; k++) {\n                                        if (selected_seeds[k] == A[i+1][j] && placed[k]) {\n                                            score += complement[idx][k] / 100;\n                                            neighbor_count++;\n                                            break;\n                                        }\n                                    }\n                                }\n                                if (j > 0 && A[i][j-1] != 0) {\n                                    for (int k = 0; k < N*N; k++) {\n                                        if (selected_seeds[k] == A[i][j-1] && placed[k]) {\n                                            score += complement[idx][k] / 100;\n                                            neighbor_count++;\n                                            break;\n                                        }\n                                    }\n                                }\n                                if (j < N-1 && A[i][j+1] != 0) {\n                                    for (int k = 0; k < N*N; k++) {\n                                        if (selected_seeds[k] == A[i][j+1] && placed[k]) {\n                                            score += complement[idx][k] / 100;\n                                            neighbor_count++;\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                if (neighbor_count > 0 && score > best_score) {\n                                    best_score = score;\n                                    best_seed_idx = idx;\n                                    best_i = i;\n                                    best_j = j;\n                                }\n                            }\n                        }\n                    }\n                }\n                \n                // If no good position found, place in first empty spot\n                if (best_seed_idx == -1) {\n                    for (int idx = 0; idx < N*N; idx++) {\n                        if (!placed[idx]) {\n                            for (int i = 0; i < N; i++) {\n                                for (int j = 0; j < N; j++) {\n                                    if (A[i][j] == 0) {\n                                        A[i][j] = selected_seeds[idx];\n                                        placed[idx] = true;\n                                        placed_count++;\n                                        goto next_placement;\n                                    }\n                                }\n                            }\n                        }\n                    }\n                } else {\n                    A[best_i][best_j] = selected_seeds[best_seed_idx];\n                    placed[best_seed_idx] = true;\n                    placed_count++;\n                }\n                next_placement:;\n            }\n            \n            // Fill any remaining empty spots\n            int seed_idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (A[i][j] == 0) {\n                        while (seed_idx < N*N && placed[seed_idx]) seed_idx++;\n                        if (seed_idx < N*N) {\n                            A[i][j] = selected_seeds[seed_idx];\n                            placed[seed_idx] = true;\n                        }\n                    }\n                }\n            }\n            \n        } else {\n            // Early generations: Simple placement\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    A[i][j] = selected_seeds[idx++];\n                }\n            }\n        }\n        \n        // Verify no duplicates (debug check)\n        set<int> check;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                check.insert(A[i][j]);\n            }\n        }\n        if (check.size() != N*N) {\n            // Fallback to simple placement if something went wrong\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    A[i][j] = selected_seeds[idx++];\n                }\n            }\n        }\n        \n        // Output placement\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                } else {\n                    cout << endl;\n                }\n            }\n        }\n        cout.flush();\n        \n        // Read new generation\n        X.clear();\n        X.resize(seed_count, vector<int>(M));\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 <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nconst int dx[4] = {0, 1, 0, -1};  // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\nconst char dirChar[5] = {'.', 'R', 'D', 'L', 'U'};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> initialGrid(N), targetGrid(N);\n    for (int i = 0; i < N; i++) cin >> initialGrid[i];\n    for (int i = 0; i < N; i++) cin >> targetGrid[i];\n    \n    // Track takoyaki positions\n    vector<Point> sources, targets;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (initialGrid[i][j] == '1') sources.push_back({i, j});\n            if (targetGrid[i][j] == '1') targets.push_back({i, j});\n        }\n    }\n    \n    // Design simple arm: just 2 vertices (root and one leaf)\n    int armV = 2;\n    cout << armV << \"\\n\";\n    cout << \"0 1\\n\";  // vertex 1 has parent 0, length 1\n    \n    // Start from center\n    int rootX = N/2, rootY = N/2;\n    cout << rootX << \" \" << rootY << \"\\n\";\n    \n    // State tracking\n    vector<string> currentGrid = initialGrid;\n    int direction = 0;  // 0=right, 1=down, 2=left, 3=up\n    bool holding = false;\n    int heldFrom = -1;  // which source we picked up\n    \n    vector<string> operations;\n    int maxTurns = 50000;\n    \n    for (int turn = 0; turn < maxTurns; turn++) {\n        // Check if we're done\n        bool allDone = true;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (targetGrid[i][j] == '1' && currentGrid[i][j] != '1') {\n                    allDone = false;\n                    break;\n                }\n            }\n            if (!allDone) break;\n        }\n        if (allDone) break;\n        \n        string op(4, '.');  // 2*armV = 4 characters\n        \n        // Calculate current fingertip position\n        int tipX = rootX + dx[direction];\n        int tipY = rootY + dy[direction];\n        \n        // Find goal position\n        Point goal(-1, -1);\n        int minDist = INT_MAX;\n        \n        if (holding) {\n            // Find nearest empty target position\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (targetGrid[i][j] == '1' && currentGrid[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goal = {i, j};\n                        }\n                    }\n                }\n            }\n        } else {\n            // Find nearest takoyaki that needs to be moved\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (currentGrid[i][j] == '1' && targetGrid[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goal = {i, j};\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Plan movement\n        int newRootX = rootX, newRootY = rootY;\n        int moveDir = 0;  // 0=none, 1=R, 2=D, 3=L, 4=U\n        \n        if (goal.x != -1) {\n            // Move towards goal\n            if (abs(goal.x - tipX) + abs(goal.y - tipY) > 1) {\n                // Need to move closer\n                if (goal.x < rootX && rootX > 0) {\n                    newRootX--;\n                    moveDir = 4;  // U\n                } else if (goal.x > rootX && rootX < N-1) {\n                    newRootX++;\n                    moveDir = 2;  // D\n                } else if (goal.y < rootY && rootY > 0) {\n                    newRootY--;\n                    moveDir = 3;  // L\n                } else if (goal.y > rootY && rootY < N-1) {\n                    newRootY++;\n                    moveDir = 1;  // R\n                }\n            }\n        }\n        \n        // Apply movement\n        if (moveDir > 0) {\n            op[0] = dirChar[moveDir];\n            rootX = newRootX;\n            rootY = newRootY;\n        }\n        \n        // Recalculate tip position after move\n        tipX = rootX + dx[direction];\n        tipY = rootY + dy[direction];\n        \n        // Plan rotation to get closer to goal\n        if (goal.x != -1) {\n            int bestDir = direction;\n            int bestDist = abs(tipX - goal.x) + abs(tipY - goal.y);\n            \n            // Try rotating\n            for (int d = 0; d < 4; d++) {\n                int newTipX = rootX + dx[d];\n                int newTipY = rootY + dy[d];\n                int dist = abs(newTipX - goal.x) + abs(newTipY - goal.y);\n                if (dist < bestDist) {\n                    bestDist = dist;\n                    bestDir = d;\n                }\n            }\n            \n            if (bestDir != direction) {\n                int diff = (bestDir - direction + 4) % 4;\n                if (diff == 1) {\n                    op[1] = 'R';\n                    direction = bestDir;\n                } else if (diff == 3) {\n                    op[1] = 'L';\n                    direction = bestDir;\n                } else if (diff == 2 && turn % 2 == 0) {\n                    // Need 2 rotations, do one now\n                    op[1] = 'R';\n                    direction = (direction + 1) % 4;\n                }\n            }\n        }\n        \n        // Recalculate tip position after rotation\n        tipX = rootX + dx[direction];\n        tipY = rootY + dy[direction];\n        \n        // Try to pick or place\n        if (tipX >= 0 && tipX < N && tipY >= 0 && tipY < N) {\n            if (!holding && currentGrid[tipX][tipY] == '1' && targetGrid[tipX][tipY] == '0') {\n                // Pick up\n                op[3] = 'P';  // op[V + 1] where V=2\n                currentGrid[tipX][tipY] = '0';\n                holding = true;\n            } else if (holding && currentGrid[tipX][tipY] == '0' && targetGrid[tipX][tipY] == '1') {\n                // Place\n                op[3] = 'P';\n                currentGrid[tipX][tipY] = '1';\n                holding = false;\n            }\n        }\n        \n        operations.push_back(op);\n    }\n    \n    // Output all operations\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nclass Solution {\nprivate:\n    int N;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    \npublic:\n    void solve() {\n        cin >> N;\n        mackerels.resize(N);\n        sardines.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> mackerels[i].x >> mackerels[i].y;\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> sardines[i].x >> sardines[i].y;\n        }\n        \n        // Find density-based grid size\n        int grid_size = determineOptimalGridSize();\n        \n        // Find best rectangle\n        auto [x1, y1, x2, y2] = findBestRectangle(grid_size);\n        \n        // Refine boundaries\n        refineBoundaries(x1, y1, x2, y2);\n        \n        // Output as simple rectangle\n        cout << \"4\\n\";\n        cout << x1 << \" \" << y1 << \"\\n\";\n        cout << x2 << \" \" << y1 << \"\\n\";\n        cout << x2 << \" \" << y2 << \"\\n\";\n        cout << x1 << \" \" << y2 << \"\\n\";\n    }\n    \nprivate:\n    int determineOptimalGridSize() {\n        // Calculate spread of mackerels to determine grid granularity\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        \n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int spread = max(max_x - min_x, max_y - min_y);\n        \n        // Adaptive grid size based on spread\n        if (spread < 20000) return 200;  // Fine grid for concentrated data\n        else if (spread < 50000) return 150;\n        else if (spread < 80000) return 100;\n        else return 75;  // Coarser grid for spread out data\n    }\n    \n    tuple<int, int, int, int> findBestRectangle(int grid_size) {\n        int cell_size = (MAX_COORD + grid_size - 1) / grid_size;\n        \n        // Build prefix sum grid\n        vector<vector<int>> grid(grid_size + 1, vector<int>(grid_size + 1, 0));\n        \n        for (const auto& p : mackerels) {\n            int gx = min(p.x / cell_size + 1, grid_size);\n            int gy = min(p.y / cell_size + 1, grid_size);\n            grid[gx][gy]++;\n        }\n        for (const auto& p : sardines) {\n            int gx = min(p.x / cell_size + 1, grid_size);\n            int gy = min(p.y / cell_size + 1, grid_size);\n            grid[gx][gy]--;\n        }\n        \n        // Build prefix sums\n        for (int i = 1; i <= grid_size; i++) {\n            for (int j = 1; j <= grid_size; j++) {\n                grid[i][j] += grid[i-1][j] + grid[i][j-1] - grid[i-1][j-1];\n            }\n        }\n        \n        // Find best rectangle using prefix sums\n        int best_score = 0;\n        int best_x1 = 0, best_y1 = 0, best_x2 = 10000, best_y2 = 10000;\n        \n        for (int x1 = 0; x1 < grid_size; x1++) {\n            for (int y1 = 0; y1 < grid_size; y1++) {\n                for (int x2 = x1 + 1; x2 <= min(x1 + 150, grid_size); x2++) {\n                    for (int y2 = y1 + 1; y2 <= min(y1 + 150, grid_size); y2++) {\n                        // Check edge length constraint\n                        int width = (x2 - x1) * cell_size;\n                        int height = (y2 - y1) * cell_size;\n                        if (2 * (width + height) > 400000) continue;\n                        \n                        // Calculate score using prefix sum\n                        int score = grid[x2][y2] - grid[x1][y2] - grid[x2][y1] + grid[x1][y1];\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_x1 = x1 * cell_size;\n                            best_y1 = y1 * cell_size;\n                            best_x2 = min(x2 * cell_size, MAX_COORD);\n                            best_y2 = min(y2 * cell_size, MAX_COORD);\n                        }\n                    }\n                }\n            }\n        }\n        \n        return {best_x1, best_y1, best_x2, best_y2};\n    }\n    \n    void refineBoundaries(int& x1, int& y1, int& x2, int& y2) {\n        // Create sorted lists for efficient range queries\n        vector<int> mackerel_x, mackerel_y;\n        vector<int> sardine_x, sardine_y;\n        \n        for (const auto& p : mackerels) {\n            mackerel_x.push_back(p.x);\n            mackerel_y.push_back(p.y);\n        }\n        for (const auto& p : sardines) {\n            sardine_x.push_back(p.x);\n            sardine_y.push_back(p.y);\n        }\n        \n        sort(mackerel_x.begin(), mackerel_x.end());\n        sort(mackerel_y.begin(), mackerel_y.end());\n        sort(sardine_x.begin(), sardine_x.end());\n        sort(sardine_y.begin(), sardine_y.end());\n        \n        // Current score calculation using binary search\n        auto calcScore = [&](int x1, int y1, int x2, int y2) {\n            int score = 0;\n            \n            // Count mackerels in range\n            for (const auto& p : mackerels) {\n                if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                    score++;\n                }\n            }\n            \n            // Subtract sardines in range\n            for (const auto& p : sardines) {\n                if (p.x >= x1 && p.x <= x2 && p.y >= y1 && p.y <= y2) {\n                    score--;\n                }\n            }\n            \n            return score;\n        };\n        \n        int current_score = calcScore(x1, y1, x2, y2);\n        \n        // Try to shrink/expand each boundary\n        for (int iter = 0; iter < 20; iter++) {\n            bool improved = false;\n            \n            // Try adjusting x1\n            for (int new_x1 : {max(0, x1 - 1000), max(0, x1 - 100), x1 + 100, x1 + 1000}) {\n                if (new_x1 < x2 && new_x1 >= 0) {\n                    int score = calcScore(new_x1, y1, x2, y2);\n                    if (score > current_score) {\n                        x1 = new_x1;\n                        current_score = score;\n                        improved = true;\n                    }\n                }\n            }\n            \n            // Try adjusting x2\n            for (int new_x2 : {min(MAX_COORD, x2 + 1000), min(MAX_COORD, x2 + 100), x2 - 100, x2 - 1000}) {\n                if (new_x2 > x1 && new_x2 <= MAX_COORD) {\n                    if (2 * ((new_x2 - x1) + (y2 - y1)) <= 400000) {\n                        int score = calcScore(x1, y1, new_x2, y2);\n                        if (score > current_score) {\n                            x2 = new_x2;\n                            current_score = score;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            \n            // Try adjusting y1\n            for (int new_y1 : {max(0, y1 - 1000), max(0, y1 - 100), y1 + 100, y1 + 1000}) {\n                if (new_y1 < y2 && new_y1 >= 0) {\n                    int score = calcScore(x1, new_y1, x2, y2);\n                    if (score > current_score) {\n                        y1 = new_y1;\n                        current_score = score;\n                        improved = true;\n                    }\n                }\n            }\n            \n            // Try adjusting y2\n            for (int new_y2 : {min(MAX_COORD, y2 + 1000), min(MAX_COORD, y2 + 100), y2 - 100, y2 - 1000}) {\n                if (new_y2 > y1 && new_y2 <= MAX_COORD) {\n                    if (2 * ((x2 - x1) + (new_y2 - y1)) <= 400000) {\n                        int score = calcScore(x1, y1, x2, new_y2);\n                        if (score > current_score) {\n                            y2 = new_y2;\n                            current_score = score;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n            \n            if (!improved) break;\n        }\n        \n        // Fine-tune with smaller steps\n        for (int step : {50, 10, 1}) {\n            bool improved = true;\n            while (improved) {\n                improved = false;\n                \n                // Try all four boundaries with current step\n                for (int dx : {-step, 0, step}) {\n                    for (int dy : {-step, 0, step}) {\n                        if (dx == 0 && dy == 0) continue;\n                        \n                        // Adjust boundaries\n                        vector<tuple<int,int,int,int>> candidates = {\n                            {x1 + dx, y1, x2, y2},\n                            {x1, y1 + dy, x2, y2},\n                            {x1, y1, x2 + dx, y2},\n                            {x1, y1, x2, y2 + dy}\n                        };\n                        \n                        for (auto [nx1, ny1, nx2, ny2] : candidates) {\n                            if (nx1 >= 0 && nx1 < nx2 && nx2 <= MAX_COORD &&\n                                ny1 >= 0 && ny1 < ny2 && ny2 <= MAX_COORD &&\n                                2 * ((nx2 - nx1) + (ny2 - ny1)) <= 400000) {\n                                \n                                int score = calcScore(nx1, ny1, nx2, ny2);\n                                if (score > current_score) {\n                                    x1 = nx1; y1 = ny1; x2 = nx2; y2 = ny2;\n                                    current_score = score;\n                                    improved = true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    int idx;\n    double obs_w, obs_h;\n    double est_w, est_h;\n    int measure_count;\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nstruct PlacedRect {\n    int x, y, w, h;\n};\n\nclass Packer {\nprivate:\n    int N, T;\n    double sigma;\n    vector<Rectangle> rects;\n    double best_score = 1e18;\n    vector<Placement> best_placement;\n    \n    // Simulate placement to get actual positions\n    pair<vector<PlacedRect>, pair<int,int>> simulatePlacement(const vector<Placement>& placements) {\n        vector<PlacedRect> placed;\n        \n        for (const auto& p : placements) {\n            int w = p.r ? (int)round(rects[p.p].est_h) : (int)round(rects[p.p].est_w);\n            int h = p.r ? (int)round(rects[p.p].est_w) : (int)round(rects[p.p].est_h);\n            \n            int x = 0, y = 0;\n            \n            if (p.d == 'U') {\n                // Moving upward from bottom\n                if (p.b >= 0 && p.b < (int)placed.size()) {\n                    x = placed[p.b].x + placed[p.b].w;\n                }\n                // Find the highest obstacle\n                for (const auto& rect : placed) {\n                    if (x < rect.x + rect.w && x + w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n            } else { // 'L'\n                // Moving leftward from right\n                if (p.b >= 0 && p.b < (int)placed.size()) {\n                    y = placed[p.b].y + placed[p.b].h;\n                }\n                // Find the rightmost obstacle\n                for (const auto& rect : placed) {\n                    if (y < rect.y + rect.h && y + h > rect.y) {\n                        x = max(x, rect.x + rect.w);\n                    }\n                }\n            }\n            \n            placed.push_back({x, y, w, h});\n        }\n        \n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.w);\n            maxY = max(maxY, rect.y + rect.h);\n        }\n        \n        return {placed, {maxX, maxY}};\n    }\n    \n    // Create a simple strip packing\n    vector<Placement> createStripPacking(bool horizontal, const vector<bool>& rotations) {\n        vector<Placement> result;\n        \n        for (int i = 0; i < N; i++) {\n            if (result.empty()) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, horizontal ? 'U' : 'L'});\n            } else {\n                if (horizontal) {\n                    // Place rectangles in a horizontal strip\n                    result.push_back({i, rotations[i] ? 1 : 0, (int)result.size() - 1, 'U'});\n                } else {\n                    // Place rectangles in a vertical strip\n                    result.push_back({i, rotations[i] ? 1 : 0, (int)result.size() - 1, 'L'});\n                }\n            }\n        }\n        \n        return result;\n    }\n    \n    // Create a shelf packing\n    vector<Placement> createShelfPacking(const vector<bool>& rotations, int shelf_size) {\n        vector<Placement> result;\n        int current_shelf_start = -1;\n        int items_in_shelf = 0;\n        \n        for (int i = 0; i < N; i++) {\n            if (items_in_shelf == 0) {\n                // Start new shelf\n                if (result.empty()) {\n                    result.push_back({i, rotations[i] ? 1 : 0, -1, 'L'});\n                } else {\n                    result.push_back({i, rotations[i] ? 1 : 0, current_shelf_start, 'L'});\n                }\n                current_shelf_start = result.size() - 1;\n                items_in_shelf = 1;\n            } else if (items_in_shelf < shelf_size) {\n                // Add to current shelf\n                result.push_back({i, rotations[i] ? 1 : 0, (int)result.size() - 1, 'U'});\n                items_in_shelf++;\n            } else {\n                // Start new shelf\n                result.push_back({i, rotations[i] ? 1 : 0, current_shelf_start, 'L'});\n                current_shelf_start = result.size() - 1;\n                items_in_shelf = 1;\n            }\n        }\n        \n        return result;\n    }\n    \n    // Create a bottom-left packing\n    vector<Placement> createBottomLeftPacking(const vector<bool>& rotations) {\n        vector<Placement> result;\n        vector<PlacedRect> placed;\n        \n        for (int i = 0; i < N; i++) {\n            int w = rotations[i] ? (int)round(rects[i].est_h) : (int)round(rects[i].est_w);\n            int h = rotations[i] ? (int)round(rects[i].est_w) : (int)round(rects[i].est_h);\n            \n            if (result.empty()) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n                placed.push_back({0, 0, w, h});\n            } else {\n                // Try to find a good position\n                int best_y = INT_MAX;\n                int best_x = INT_MAX;\n                int best_ref = -1;\n                char best_dir = 'U';\n                \n                // Try placing at x=0\n                int y = 0;\n                for (const auto& rect : placed) {\n                    if (w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n                if (y < best_y || (y == best_y && 0 < best_x)) {\n                    best_y = y;\n                    best_x = 0;\n                    best_ref = -1;\n                    best_dir = 'U';\n                }\n                \n                // Try placing to the right of each existing rectangle\n                for (int j = 0; j < (int)placed.size(); j++) {\n                    int x = placed[j].x + placed[j].w;\n                    y = 0;\n                    for (const auto& rect : placed) {\n                        if (x < rect.x + rect.w && x + w > rect.x) {\n                            y = max(y, rect.y + rect.h);\n                        }\n                    }\n                    if (y < best_y || (y == best_y && x < best_x)) {\n                        best_y = y;\n                        best_x = x;\n                        best_ref = j;\n                        best_dir = 'U';\n                    }\n                }\n                \n                result.push_back({i, rotations[i] ? 1 : 0, best_ref, best_dir});\n                placed.push_back({best_x, best_y, w, h});\n            }\n        }\n        \n        return result;\n    }\n    \n    pair<int, int> query(const vector<Placement>& placements) {\n        cout << placements.size() << endl;\n        for (const auto& p : placements) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << endl;\n        }\n        cout.flush();\n        \n        int W, H;\n        cin >> W >> H;\n        return {W, H};\n    }\n    \n    void updateEstimates(int W_measured, int H_measured, const vector<Placement>& placements) {\n        // Get the actual placement\n        auto [placed, dims] = simulatePlacement(placements);\n        int W_actual = dims.first;\n        int H_actual = dims.second;\n        \n        // Estimate the measurement error\n        double error_W = W_measured - W_actual;\n        double error_H = H_measured - H_actual;\n        \n        // Update estimates for all placed rectangles\n        for (size_t i = 0; i < placements.size(); i++) {\n            int idx = placements[i].p;\n            rects[idx].measure_count++;\n            \n            // Simple exponential smoothing\n            double alpha = 1.0 / (1.0 + rects[idx].measure_count);\n            \n            // Adjust estimates based on the overall error pattern\n            double adj_factor = 1.0;\n            if (abs(error_W) < sigma && abs(error_H) < sigma) {\n                // Good measurement, trust it more\n                adj_factor = 0.9;\n            } else {\n                // Noisy measurement, trust it less\n                adj_factor = 0.95;\n            }\n            \n            rects[idx].est_w = rects[idx].est_w * adj_factor + rects[idx].obs_w * (1 - adj_factor);\n            rects[idx].est_h = rects[idx].est_h * adj_factor + rects[idx].obs_h * (1 - adj_factor);\n        }\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> T >> sigma;\n        rects.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            rects[i].idx = i;\n            cin >> rects[i].obs_w >> rects[i].obs_h;\n            rects[i].est_w = rects[i].obs_w;\n            rects[i].est_h = rects[i].obs_h;\n            rects[i].measure_count = 0;\n        }\n        \n        for (int turn = 0; turn < T; turn++) {\n            vector<bool> rotations(N, false);\n            vector<Placement> placements;\n            \n            // Choose rotation strategy\n            for (int i = 0; i < N; i++) {\n                if (turn < T / 3) {\n                    // Early phase: minimize height\n                    rotations[i] = (rects[i].est_w > rects[i].est_h);\n                } else if (turn < 2 * T / 3) {\n                    // Middle phase: try to balance\n                    double ratio = max(rects[i].est_w, rects[i].est_h) / min(rects[i].est_w, rects[i].est_h);\n                    rotations[i] = (ratio > 1.5 && rects[i].est_h > rects[i].est_w);\n                } else {\n                    // Late phase: use best known orientation\n                    if (best_score < 1e18) {\n                        // Keep using what worked best\n                        rotations[i] = (rects[i].est_w > rects[i].est_h);\n                    } else {\n                        rotations[i] = (rects[i].est_w > rects[i].est_h * 1.2);\n                    }\n                }\n            }\n            \n            // Choose packing strategy based on turn\n            if (turn % 5 == 0) {\n                placements = createStripPacking(true, rotations);\n            } else if (turn % 5 == 1) {\n                placements = createStripPacking(false, rotations);\n            } else if (turn % 5 == 2) {\n                int shelf_size = max(3, N / 5);\n                placements = createShelfPacking(rotations, shelf_size);\n            } else if (turn % 5 == 3) {\n                int shelf_size = max(4, N / 4);\n                placements = createShelfPacking(rotations, shelf_size);\n            } else {\n                placements = createBottomLeftPacking(rotations);\n            }\n            \n            auto [W, H] = query(placements);\n            \n            // Track best configuration\n            double score = W + H;\n            if (score < best_score) {\n                best_score = score;\n                best_placement = placements;\n            }\n            \n            updateEstimates(W, H, placements);\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.solve();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass ForestOptimizer {\n    int N, M, H;\n    vector<int> beauty;\n    vector<vector<int>> adj;\n    vector<pair<int,int>> coords;\n    \n    struct Solution {\n        vector<int> parent;\n        long long score;\n    };\n    \n    long long calculateScore(const vector<int>& parent) {\n        long long score = 1;\n        for (int i = 0; i < N; i++) {\n            int depth = 0;\n            int curr = i;\n            while (parent[curr] != -1) {\n                depth++;\n                curr = parent[curr];\n            }\n            score += (long long)(depth + 1) * beauty[i];\n        }\n        return score;\n    }\n    \n    long long evaluateSubtreeScore(int root, const vector<bool>& used, int maxDepth) {\n        if (used[root]) return 0;\n        \n        vector<bool> visited = used;\n        visited[root] = true;\n        queue<pair<int,int>> q;\n        q.push({root, 0});\n        \n        long long score = beauty[root];\n        \n        while (!q.empty()) {\n            auto [u, depth] = q.front();\n            q.pop();\n            \n            if (depth >= maxDepth) continue;\n            \n            vector<int> candidates;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    candidates.push_back(v);\n                }\n            }\n            \n            sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                return beauty[a] > beauty[b];\n            });\n            \n            for (int v : candidates) {\n                visited[v] = true;\n                score += (long long)(depth + 2) * beauty[v];\n                q.push({v, depth + 1});\n            }\n        }\n        \n        return score;\n    }\n    \n    Solution buildForestWithStrategy(function<bool(int,int)> comparator) {\n        vector<int> parent(N, -1);\n        vector<int> depth(N, -1);\n        vector<bool> visited(N, false);\n        \n        vector<int> order(N);\n        iota(order.begin(), order.end(), 0);\n        sort(order.begin(), order.end(), comparator);\n        \n        for (int root : order) {\n            if (visited[root]) continue;\n            \n            depth[root] = 0;\n            visited[root] = true;\n            \n            priority_queue<pair<int,int>> pq;\n            pq.push({beauty[root], root});\n            \n            while (!pq.empty()) {\n                auto [_, u] = pq.top();\n                pq.pop();\n                \n                if (depth[u] >= H) continue;\n                \n                for (int v : adj[u]) {\n                    if (!visited[v]) {\n                        parent[v] = u;\n                        depth[v] = depth[u] + 1;\n                        visited[v] = true;\n                        pq.push({beauty[v] * (H - depth[v]), v});\n                    }\n                }\n            }\n        }\n        \n        return {parent, calculateScore(parent)};\n    }\n    \n    Solution buildForestWithEvaluation() {\n        vector<int> parent(N, -1);\n        vector<bool> used(N, false);\n        vector<int> depth(N, -1);\n        \n        while (true) {\n            int bestRoot = -1;\n            long long bestScore = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (!used[i]) {\n                    long long score = evaluateSubtreeScore(i, used, H);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestRoot = i;\n                    }\n                }\n            }\n            \n            if (bestRoot == -1) break;\n            \n            used[bestRoot] = true;\n            depth[bestRoot] = 0;\n            \n            queue<int> q;\n            q.push(bestRoot);\n            \n            while (!q.empty()) {\n                int u = q.front();\n                q.pop();\n                \n                if (depth[u] >= H) continue;\n                \n                vector<int> candidates;\n                for (int v : adj[u]) {\n                    if (!used[v]) {\n                        candidates.push_back(v);\n                    }\n                }\n                \n                sort(candidates.begin(), candidates.end(), [&](int a, int b) {\n                    return beauty[a] > beauty[b];\n                });\n                \n                for (int v : candidates) {\n                    parent[v] = u;\n                    depth[v] = depth[u] + 1;\n                    used[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        \n        return {parent, calculateScore(parent)};\n    }\n    \n    Solution localSearch(Solution initial) {\n        vector<int> parent = initial.parent;\n        long long currentScore = initial.score;\n        \n        // Try reassigning leaf nodes\n        for (int iter = 0; iter < 100; iter++) {\n            bool improved = false;\n            \n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                \n                // Check if v is a leaf\n                bool isLeaf = true;\n                for (int u = 0; u < N; u++) {\n                    if (parent[u] == v) {\n                        isLeaf = false;\n                        break;\n                    }\n                }\n                \n                if (!isLeaf) continue;\n                \n                int oldParent = parent[v];\n                \n                // Try reassigning to different parents\n                for (int newParent : adj[v]) {\n                    if (newParent == oldParent) continue;\n                    \n                    // Check depth constraint\n                    int newDepth = 0;\n                    int curr = newParent;\n                    while (parent[curr] != -1) {\n                        newDepth++;\n                        curr = parent[curr];\n                    }\n                    \n                    if (newDepth >= H) continue;\n                    \n                    parent[v] = newParent;\n                    long long newScore = calculateScore(parent);\n                    \n                    if (newScore > currentScore) {\n                        currentScore = newScore;\n                        improved = true;\n                    } else {\n                        parent[v] = oldParent;\n                    }\n                }\n            }\n            \n            if (!improved) break;\n        }\n        \n        return {parent, currentScore};\n    }\n    \npublic:\n    ForestOptimizer(int n, int m, int h) : N(n), M(m), H(h) {\n        beauty.resize(N);\n        adj.resize(N);\n        coords.resize(N);\n    }\n    \n    void input() {\n        for (int i = 0; i < N; i++) {\n            cin >> beauty[i];\n        }\n        \n        for (int i = 0; i < M; i++) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        \n        for (int i = 0; i < N; i++) {\n            cin >> coords[i].first >> coords[i].second;\n        }\n    }\n    \n    vector<int> solve() {\n        Solution best = {{}, 0};\n        \n        // Strategy 1: Pure beauty greedy\n        auto sol1 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] > beauty[b];\n        });\n        if (sol1.score > best.score) best = sol1;\n        \n        // Strategy 2: Beauty * degree\n        auto sol2 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] * (int)adj[a].size() > beauty[b] * (int)adj[b].size();\n        });\n        if (sol2.score > best.score) best = sol2;\n        \n        // Strategy 3: Evaluation-based\n        auto sol3 = buildForestWithEvaluation();\n        if (sol3.score > best.score) best = sol3;\n        \n        // Strategy 4: Beauty / (degree + 1) for better root selection\n        auto sol4 = buildForestWithStrategy([&](int a, int b) {\n            return beauty[a] * 1.0 / (adj[a].size() + 1) > beauty[b] * 1.0 / (adj[b].size() + 1);\n        });\n        if (sol4.score > best.score) best = sol4;\n        \n        // Apply local search to best solution\n        best = localSearch(best);\n        \n        return best.parent;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    ForestOptimizer optimizer(N, M, H);\n    optimizer.input();\n    \n    vector<int> result = optimizer.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> operations;\n    \n    // Try to find optimal removal order using better heuristics\n    while (true) {\n        double best_efficiency = 1e9;\n        char best_dir = ' ';\n        int best_line = -1;\n        vector<pair<int,int>> best_targets;\n        int best_shifts = 0;\n        \n        // Check all possible batch removals\n        for (int j = 0; j < N; j++) {\n            // Check upward removal\n            vector<pair<int,int>> up_targets;\n            int max_up = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = 0; k < i; k++) {\n                    if (board[k][j] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    up_targets.push_back({i, j});\n                    max_up = max(max_up, i);\n                }\n            }\n            \n            if (!up_targets.empty()) {\n                int shifts = max_up + 1;\n                double efficiency = (2.0 * shifts) / up_targets.size();\n                \n                // Bonus for removing multiple adjacent Oni\n                int adjacency_bonus = 0;\n                sort(up_targets.begin(), up_targets.end());\n                for (int t = 1; t < up_targets.size(); t++) {\n                    if (up_targets[t].first - up_targets[t-1].first <= 2) {\n                        adjacency_bonus++;\n                    }\n                }\n                efficiency -= adjacency_bonus * 0.5;\n                \n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'U';\n                    best_line = j;\n                    best_targets = up_targets;\n                    best_shifts = shifts;\n                }\n            }\n            \n            // Check downward removal\n            vector<pair<int,int>> down_targets;\n            int min_down = N;\n            \n            for (int i = 0; i < N; i++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = i + 1; k < N; k++) {\n                    if (board[k][j] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    down_targets.push_back({i, j});\n                    min_down = min(min_down, i);\n                }\n            }\n            \n            if (!down_targets.empty()) {\n                int shifts = N - min_down;\n                double efficiency = (2.0 * shifts) / down_targets.size();\n                \n                // Bonus for removing multiple adjacent Oni\n                int adjacency_bonus = 0;\n                sort(down_targets.begin(), down_targets.end());\n                for (int t = 1; t < down_targets.size(); t++) {\n                    if (down_targets[t].first - down_targets[t-1].first <= 2) {\n                        adjacency_bonus++;\n                    }\n                }\n                efficiency -= adjacency_bonus * 0.5;\n                \n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'D';\n                    best_line = j;\n                    best_targets = down_targets;\n                    best_shifts = shifts;\n                }\n            }\n        }\n        \n        // Check all rows\n        for (int i = 0; i < N; i++) {\n            // Check leftward removal\n            vector<pair<int,int>> left_targets;\n            int max_left = -1;\n            \n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = 0; k < j; k++) {\n                    if (board[i][k] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    left_targets.push_back({i, j});\n                    max_left = max(max_left, j);\n                }\n            }\n            \n            if (!left_targets.empty()) {\n                int shifts = max_left + 1;\n                double efficiency = (2.0 * shifts) / left_targets.size();\n                \n                // Bonus for removing multiple adjacent Oni\n                int adjacency_bonus = 0;\n                sort(left_targets.begin(), left_targets.end(), \n                     [](auto& a, auto& b) { return a.second < b.second; });\n                for (int t = 1; t < left_targets.size(); t++) {\n                    if (left_targets[t].second - left_targets[t-1].second <= 2) {\n                        adjacency_bonus++;\n                    }\n                }\n                efficiency -= adjacency_bonus * 0.5;\n                \n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'L';\n                    best_line = i;\n                    best_targets = left_targets;\n                    best_shifts = shifts;\n                }\n            }\n            \n            // Check rightward removal\n            vector<pair<int,int>> right_targets;\n            int min_right = N;\n            \n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                bool safe = true;\n                for (int k = j + 1; k < N; k++) {\n                    if (board[i][k] == 'o') {\n                        safe = false;\n                        break;\n                    }\n                }\n                if (safe) {\n                    right_targets.push_back({i, j});\n                    min_right = min(min_right, j);\n                }\n            }\n            \n            if (!right_targets.empty()) {\n                int shifts = N - min_right;\n                double efficiency = (2.0 * shifts) / right_targets.size();\n                \n                // Bonus for removing multiple adjacent Oni\n                int adjacency_bonus = 0;\n                sort(right_targets.begin(), right_targets.end(),\n                     [](auto& a, auto& b) { return a.second < b.second; });\n                for (int t = 1; t < right_targets.size(); t++) {\n                    if (right_targets[t].second - right_targets[t-1].second <= 2) {\n                        adjacency_bonus++;\n                    }\n                }\n                efficiency -= adjacency_bonus * 0.5;\n                \n                if (efficiency < best_efficiency) {\n                    best_efficiency = efficiency;\n                    best_dir = 'R';\n                    best_line = i;\n                    best_targets = right_targets;\n                    best_shifts = shifts;\n                }\n            }\n        }\n        \n        if (best_line == -1) break;\n        \n        // Execute the best batch removal\n        for (int t = 0; t < best_shifts; t++) {\n            operations.push_back({best_dir, best_line});\n        }\n        \n        // Reverse direction\n        char reverse_dir = best_dir;\n        if (best_dir == 'U') reverse_dir = 'D';\n        else if (best_dir == 'D') reverse_dir = 'U';\n        else if (best_dir == 'L') reverse_dir = 'R';\n        else if (best_dir == 'R') reverse_dir = 'L';\n        \n        for (int t = 0; t < best_shifts; t++) {\n            operations.push_back({reverse_dir, best_line});\n        }\n        \n        // Mark removed Oni\n        for (auto [i, j] : best_targets) {\n            board[i][j] = '.';\n        }\n    }\n    \n    // Output operations\n    for (auto [dir, pos] : operations) {\n        cout << dir << \" \" << pos << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N), b(N);\n    mt19937 rng(42);\n    \n    // Initialize with weighted probabilities\n    vector<double> prob(N);\n    double total = 0;\n    for (int i = 0; i < N; i++) {\n        prob[i] = T[i] + 10.0;  // Add small constant to avoid zero\n        total += prob[i];\n    }\n    for (int i = 0; i < N; i++) {\n        prob[i] /= total;\n    }\n    \n    // Initialize transitions based on target distribution\n    for (int i = 0; i < N; i++) {\n        discrete_distribution<int> dist(prob.begin(), prob.end());\n        a[i] = dist(rng);\n        b[i] = dist(rng);\n    }\n    \n    // Full simulation function\n    auto simulate = [&](int maxSteps) -> vector<int> {\n        vector<int> count(N, 0);\n        int curr = 0;\n        count[0]++;\n        \n        for (int step = 2; step <= maxSteps; step++) {\n            if (count[curr] & 1) {\n                curr = a[curr];\n            } else {\n                curr = b[curr];\n            }\n            count[curr]++;\n        }\n        \n        return count;\n    };\n    \n    // Calculate total error\n    auto calculateError = [&](const vector<int>& counts, int simLen) -> int {\n        double scale = (double)L / simLen;\n        int totalError = 0;\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            totalError += abs(projected - T[i]);\n        }\n        return totalError;\n    };\n    \n    // Multi-stage optimization\n    vector<int> simLengths = {10000, 30000, 50000};\n    \n    for (int stage = 0; stage < simLengths.size(); stage++) {\n        int simLen = min(simLengths[stage], L);\n        \n        // Store best solution\n        auto bestCounts = simulate(simLen);\n        int bestError = calculateError(bestCounts, simLen);\n        vector<int> bestA = a, bestB = b;\n        \n        // Temperature for simulated annealing\n        double initialTemp = 100.0;\n        double finalTemp = 0.1;\n        int maxIter = 500;\n        \n        for (int iter = 0; iter < maxIter; iter++) {\n            double temp = initialTemp * pow(finalTemp / initialTemp, (double)iter / maxIter);\n            \n            // Get current state\n            auto counts = simulate(simLen);\n            \n            // Find employees with errors\n            vector<pair<int, int>> errors;\n            double scale = (double)L / simLen;\n            \n            for (int i = 0; i < N; i++) {\n                int projected = (int)(counts[i] * scale + 0.5);\n                int error = abs(projected - T[i]);\n                if (error > 0) {\n                    errors.push_back({error, i});\n                }\n            }\n            \n            if (errors.empty()) break;\n            \n            // Sort by error\n            sort(errors.rbegin(), errors.rend());\n            \n            // Pick employee to modify (bias towards high error)\n            int idx = 0;\n            if (errors.size() > 1) {\n                double r = uniform_real_distribution<>(0, 1)(rng);\n                idx = min((int)(r * r * errors.size()), (int)errors.size() - 1);\n            }\n            int emp = errors[idx].second;\n            \n            // Determine if this employee needs more or fewer visits\n            int projected = (int)(counts[emp] * scale + 0.5);\n            bool needsMore = projected < T[emp];\n            \n            // Store old values\n            int oldA = a[emp], oldB = b[emp];\n            \n            if (needsMore) {\n                // Find employees getting too many visits\n                vector<pair<int, int>> excess;\n                for (int i = 0; i < N; i++) {\n                    int proj = (int)(counts[i] * scale + 0.5);\n                    if (proj > T[i]) {\n                        excess.push_back({proj - T[i], i});\n                    }\n                }\n                \n                if (!excess.empty()) {\n                    sort(excess.rbegin(), excess.rend());\n                    int donor = excess[rng() % min(3, (int)excess.size())].second;\n                    \n                    // Make donor point to emp\n                    if (rng() % 2 == 0) {\n                        a[donor] = emp;\n                    } else {\n                        b[donor] = emp;\n                    }\n                }\n            } else {\n                // emp gets too many visits - redirect its outputs\n                vector<pair<int, int>> deficit;\n                for (int i = 0; i < N; i++) {\n                    int proj = (int)(counts[i] * scale + 0.5);\n                    if (proj < T[i]) {\n                        deficit.push_back({T[i] - proj, i});\n                    }\n                }\n                \n                if (!deficit.empty()) {\n                    sort(deficit.rbegin(), deficit.rend());\n                    int target = deficit[rng() % min(3, (int)deficit.size())].second;\n                    \n                    if (rng() % 2 == 0) {\n                        a[emp] = target;\n                    } else {\n                        b[emp] = target;\n                    }\n                }\n            }\n            \n            // Also randomly modify some transitions\n            if (uniform_real_distribution<>(0, 1)(rng) < 0.3) {\n                int randEmp = rng() % N;\n                discrete_distribution<int> dist(prob.begin(), prob.end());\n                if (rng() % 2 == 0) {\n                    a[randEmp] = dist(rng);\n                } else {\n                    b[randEmp] = dist(rng);\n                }\n            }\n            \n            // Evaluate new solution\n            counts = simulate(simLen);\n            int newError = calculateError(counts, simLen);\n            \n            if (newError < bestError) {\n                bestError = newError;\n                bestA = a;\n                bestB = b;\n                bestCounts = counts;\n            } else {\n                // Accept with probability based on temperature\n                double delta = newError - bestError;\n                double acceptProb = exp(-delta / temp);\n                \n                if (uniform_real_distribution<>(0, 1)(rng) > acceptProb) {\n                    // Revert\n                    a = bestA;\n                    b = bestB;\n                }\n            }\n            \n            // Early termination if error is very low\n            if (bestError < L * 0.01) break;\n        }\n        \n        a = bestA;\n        b = bestB;\n    }\n    \n    // Final refinement with full simulation if time permits\n    if (L <= 100000) {\n        auto counts = simulate(L);\n        int error = calculateError(counts, L);\n        \n        // Try a few random swaps\n        for (int i = 0; i < 50; i++) {\n            int emp = rng() % N;\n            int oldVal = (rng() % 2 == 0) ? a[emp] : b[emp];\n            int newVal = rng() % N;\n            \n            if (rng() % 2 == 0) a[emp] = newVal;\n            else b[emp] = newVal;\n            \n            auto newCounts = simulate(L);\n            int newError = calculateError(newCounts, L);\n            \n            if (newError >= error) {\n                // Revert\n                if (rng() % 2 == 0) a[emp] = oldVal;\n                else b[emp] = oldVal;\n            } else {\n                error = newError;\n            }\n        }\n    }\n    \n    // Output solution\n    for (int i = 0; i < N; i++) {\n        cout << a[i] << \" \" << b[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n    double uncertainty;\n};\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    \n    UnionFind(int n) : parent(n), size(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (size[px] < size[py]) swap(px, py);\n        parent[py] = px;\n        size[px] += size[py];\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\ndouble dist(const City& a, const City& b) {\n    double dx = a.cx - b.cx;\n    double dy = a.cy - b.cy;\n    return sqrt(dx * dx + dy * dy);\n}\n\ndouble maxPossibleDist(const City& a, const City& b) {\n    double dx = max(abs(a.rx - b.lx), abs(a.lx - b.rx));\n    double dy = max(abs(a.ry - b.ly), abs(a.ly - b.ry));\n    return sqrt(dx * dx + dy * dy);\n}\n\nvector<pair<int, int>> query(const vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v});\n    }\n    return edges;\n}\n\n// K-means++ initialization for better initial centers\nvector<int> kMeansPlusPlus(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<int> centers;\n    vector<double> minDist(n, 1e9);\n    \n    // Choose first center randomly\n    centers.push_back(rand() % n);\n    \n    for (int i = 1; i < k; i++) {\n        // Update distances\n        for (int j = 0; j < n; j++) {\n            double d = dist(cities[j], cities[centers.back()]);\n            minDist[j] = min(minDist[j], d);\n        }\n        \n        // Choose next center with probability proportional to distance squared\n        double sum = 0;\n        for (int j = 0; j < n; j++) sum += minDist[j] * minDist[j];\n        \n        double r = (double)rand() / RAND_MAX * sum;\n        double cumSum = 0;\n        for (int j = 0; j < n; j++) {\n            cumSum += minDist[j] * minDist[j];\n            if (cumSum >= r) {\n                centers.push_back(j);\n                break;\n            }\n        }\n    }\n    \n    return centers;\n}\n\n// Balanced k-means clustering\nvector<vector<int>> balancedKMeans(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<vector<int>> clusters(k);\n    \n    // Initialize centers\n    vector<int> centerIds = kMeansPlusPlus(cities, k, targetSizes);\n    vector<pair<double, double>> centers(k);\n    for (int i = 0; i < k; i++) {\n        centers[i] = {cities[centerIds[i]].cx, cities[centerIds[i]].cy};\n    }\n    \n    // Assign cities to clusters with size constraints\n    for (int iter = 0; iter < 20; iter++) {\n        // Calculate distances to all centers\n        vector<vector<pair<double, int>>> distances(k);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < k; j++) {\n                double dx = cities[i].cx - centers[j].first;\n                double dy = cities[i].cy - centers[j].second;\n                double d = sqrt(dx * dx + dy * dy);\n                distances[j].push_back({d, i});\n            }\n        }\n        \n        // Sort by distance for each cluster\n        for (int i = 0; i < k; i++) {\n            sort(distances[i].begin(), distances[i].end());\n        }\n        \n        // Assign cities greedily with size constraints\n        clusters.assign(k, vector<int>());\n        vector<bool> assigned(n, false);\n        \n        for (int round = 0; round < n; round++) {\n            for (int c = 0; c < k; c++) {\n                if (clusters[c].size() >= targetSizes[c]) continue;\n                \n                for (auto [d, city] : distances[c]) {\n                    if (!assigned[city]) {\n                        clusters[c].push_back(city);\n                        assigned[city] = true;\n                        break;\n                    }\n                }\n                \n                if (clusters[c].size() >= targetSizes[c]) continue;\n            }\n        }\n        \n        // Update centers\n        for (int i = 0; i < k; i++) {\n            if (clusters[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : clusters[i]) {\n                cx += cities[city].cx;\n                cy += cities[city].cy;\n            }\n            centers[i] = {cx / clusters[i].size(), cy / clusters[i].size()};\n        }\n    }\n    \n    return clusters;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<City> cities(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        cities[i].uncertainty = sqrt((cities[i].rx - cities[i].lx) * (cities[i].rx - cities[i].lx) + \n                                    (cities[i].ry - cities[i].ly) * (cities[i].ry - cities[i].ly));\n    }\n    \n    // Use balanced k-means for initial grouping\n    vector<vector<int>> groups = balancedKMeans(cities, M, G);\n    \n    // Ensure exact group sizes\n    for (int i = 0; i < M; i++) {\n        while (groups[i].size() > G[i]) {\n            groups[(i + 1) % M].push_back(groups[i].back());\n            groups[i].pop_back();\n        }\n    }\n    \n    // Process each group to find MST\n    vector<vector<pair<int, int>>> groupEdges(M);\n    map<pair<int, int>, bool> knownEdges;  // Track which edges we know exactly\n    int queriesUsed = 0;\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L && queriesUsed < Q) {\n            // Query entire small group\n            auto edges = query(groups[g]);\n            groupEdges[g] = edges;\n            for (auto& e : edges) {\n                knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n            }\n            queriesUsed++;\n        } else {\n            // Smart querying for large groups\n            UnionFind uf(N);\n            set<pair<int, int>> mstEdges;\n            \n            // Priority queue for potential edges (estimated distance, u, v)\n            priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n            \n            // Add all potential edges\n            for (int i = 0; i < sz; i++) {\n                for (int j = i + 1; j < sz; j++) {\n                    double d = dist(cities[groups[g][i]], cities[groups[g][j]]);\n                    pq.push({d, groups[g][i], groups[g][j]});\n                }\n            }\n            \n            // Process edges and query when uncertain\n            while (!pq.empty() && mstEdges.size() < sz - 1) {\n                auto [d, u, v] = pq.top();\n                pq.pop();\n                \n                if (uf.connected(u, v)) continue;\n                \n                // Check if we know this edge\n                pair<int, int> edge = {min(u, v), max(u, v)};\n                \n                if (!knownEdges.count(edge) && queriesUsed < Q) {\n                    // Query a subset containing this edge and nearby cities\n                    vector<int> subset = {u, v};\n                    \n                    // Add nearby cities up to L\n                    vector<pair<double, int>> neighbors;\n                    for (int c : groups[g]) {\n                        if (c != u && c != v) {\n                            double d1 = dist(cities[u], cities[c]);\n                            double d2 = dist(cities[v], cities[c]);\n                            neighbors.push_back({min(d1, d2), c});\n                        }\n                    }\n                    sort(neighbors.begin(), neighbors.end());\n                    \n                    for (auto [d, c] : neighbors) {\n                        subset.push_back(c);\n                        if (subset.size() >= L) break;\n                    }\n                    \n                    if (subset.size() >= 2) {\n                        auto edges = query(subset);\n                        for (auto& e : edges) {\n                            knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n                            \n                            // Add to MST if it connects our components\n                            if (!uf.connected(e.first, e.second)) {\n                                uf.unite(e.first, e.second);\n                                mstEdges.insert({e.first, e.second});\n                            }\n                        }\n                        queriesUsed++;\n                    }\n                } else {\n                    // Use this edge if no cycle\n                    if (!uf.connected(u, v)) {\n                        uf.unite(u, v);\n                        mstEdges.insert({u, v});\n                    }\n                }\n            }\n            \n            // Ensure connectivity (failsafe)\n            if (mstEdges.size() < sz - 1) {\n                for (int i = 0; i < sz; i++) {\n                    for (int j = i + 1; j < sz; j++) {\n                        if (!uf.connected(groups[g][i], groups[g][j])) {\n                            uf.unite(groups[g][i], groups[g][j]);\n                            mstEdges.insert({groups[g][i], groups[g][j]});\n                            if (mstEdges.size() >= sz - 1) break;\n                        }\n                    }\n                    if (mstEdges.size() >= sz - 1) break;\n                }\n            }\n            \n            groupEdges[g] = vector<pair<int, int>>(mstEdges.begin(), mstEdges.end());\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int c : groups[g]) cout << c << \" \";\n        cout << endl;\n        for (auto& e : groupEdges[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Point {\n    int i, 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 tie(i, j) < tie(other.i, other.j);\n    }\n};\n\nvector<string> actions;\nset<Point> blocks;\nset<Point> permanentBlocks; // Blocks we want to keep\nPoint current;\nvector<Point> targets;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\nPoint getNext(Point p, int dir) {\n    return {p.i + di[dir], p.j + dj[dir]};\n}\n\nPoint slideFrom(Point p, int dir) {\n    while (true) {\n        Point next = getNext(p, dir);\n        if (!inBounds(next.i, next.j) || blocks.count(next)) break;\n        p = next;\n    }\n    return p;\n}\n\nvoid addAction(char type, int dir) {\n    actions.push_back(string(1, type) + \" \" + dirs[dir]);\n    \n    if (type == 'M') {\n        current = getNext(current, dir);\n    } else if (type == 'S') {\n        current = slideFrom(current, dir);\n    } else if (type == 'A') {\n        Point next = getNext(current, dir);\n        if (inBounds(next.i, next.j)) {\n            if (blocks.count(next)) {\n                blocks.erase(next);\n                permanentBlocks.erase(next);\n            } else {\n                blocks.insert(next);\n            }\n        }\n    }\n}\n\n// Calculate effective distance considering sliding potential\nint effectiveDistance(Point from, Point to) {\n    int di = abs(from.i - to.i);\n    int dj = abs(from.j - to.j);\n    \n    // If aligned, sliding is very efficient\n    if (from.i == to.i || from.j == to.j) {\n        return min(di + dj, 3); // Sliding costs at most 3 (place block, slide, remove)\n    }\n    \n    // Otherwise, we need to align first\n    return min(di + dj, min(di, dj) + 3);\n}\n\n// BFS with A* heuristic\nvector<int> findPath(Point start, Point goal, bool avoidPermanent = false) {\n    if (start == goal) return {};\n    \n    priority_queue<tuple<int, Point, vector<int>>, \n                   vector<tuple<int, Point, vector<int>>>,\n                   greater<tuple<int, Point, vector<int>>>> pq;\n    \n    map<Point, int> dist;\n    pq.push({effectiveDistance(start, goal), start, {}});\n    dist[start] = 0;\n    \n    while (!pq.empty()) {\n        auto [f, p, path] = pq.top();\n        pq.pop();\n        \n        if (p == goal) return path;\n        \n        if (dist.count(p) && dist[p] < (int)path.size()) continue;\n        \n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(p, d);\n            if (!inBounds(next.i, next.j)) continue;\n            if (blocks.count(next) && (!avoidPermanent || !permanentBlocks.count(next))) continue;\n            \n            int newDist = path.size() + 1;\n            if (!dist.count(next) || dist[next] > newDist) {\n                dist[next] = newDist;\n                auto newPath = path;\n                newPath.push_back(d);\n                pq.push({newDist + effectiveDistance(next, goal), next, newPath});\n            }\n        }\n    }\n    \n    return {};\n}\n\n// Try to reach target using sliding with strategic block placement\nbool trySlideToTarget(Point target) {\n    // Check if we can slide directly\n    for (int dir = 0; dir < 4; dir++) {\n        Point end = slideFrom(current, dir);\n        if (end == target) {\n            addAction('S', dir);\n            return true;\n        }\n    }\n    \n    // Try to align and slide\n    bool needAlign = (current.i != target.i && current.j != target.j);\n    \n    if (needAlign) {\n        // Choose best alignment\n        Point alignH = {current.i, target.j};\n        Point alignV = {target.i, current.j};\n        \n        Point bestAlign;\n        int bestCost = INT_MAX;\n        \n        // Try horizontal alignment\n        if (inBounds(alignH.i, alignH.j) && !blocks.count(alignH)) {\n            auto pathH = findPath(current, alignH);\n            if (!pathH.empty() && (int)pathH.size() < bestCost) {\n                bestCost = pathH.size();\n                bestAlign = alignH;\n            }\n        }\n        \n        // Try vertical alignment  \n        if (inBounds(alignV.i, alignV.j) && !blocks.count(alignV)) {\n            auto pathV = findPath(current, alignV);\n            if (!pathV.empty() && (int)pathV.size() < bestCost) {\n                bestCost = pathV.size();\n                bestAlign = alignV;\n            }\n        }\n        \n        // If alignment is worth it (saves moves)\n        int directDist = abs(current.i - target.i) + abs(current.j - target.j);\n        if (bestCost < directDist - 2) {\n            auto path = findPath(current, bestAlign);\n            for (int dir : path) {\n                addAction('M', dir);\n            }\n        }\n    }\n    \n    // Now try sliding with blocker if aligned\n    if (current.i == target.i || current.j == target.j) {\n        int dir = -1;\n        Point blocker;\n        \n        if (current.i == target.i) {\n            dir = (current.j < target.j) ? 3 : 2;\n            blocker = getNext(target, dir);\n        } else {\n            dir = (current.i < target.i) ? 1 : 0;\n            blocker = getNext(target, dir);\n        }\n        \n        if (inBounds(blocker.i, blocker.j) && !blocks.count(blocker)) {\n            // Check if sliding would overshoot\n            Point slideEnd = slideFrom(current, dir);\n            bool needsBlocker = (current.i == target.i) ? \n                               (slideEnd.j != target.j) : (slideEnd.i != target.i);\n            \n            if (needsBlocker) {\n                // Place blocker\n                bool placed = false;\n                for (int d = 0; d < 4; d++) {\n                    if (getNext(current, d) == blocker) {\n                        addAction('A', d);\n                        placed = true;\n                        break;\n                    }\n                }\n                \n                if (!placed) {\n                    // Move to place blocker\n                    for (int d = 0; d < 4; d++) {\n                        Point adj = getNext(blocker, d);\n                        if (adj != target && inBounds(adj.i, adj.j) && !blocks.count(adj)) {\n                            auto path = findPath(current, adj);\n                            if (!path.empty() && path.size() <= 3) {\n                                for (int move : path) {\n                                    addAction('M', move);\n                                }\n                                for (int dd = 0; dd < 4; dd++) {\n                                    if (getNext(current, dd) == blocker) {\n                                        addAction('A', dd);\n                                        placed = true;\n                                        \n                                        // Mark as permanent if it might help future targets\n                                        bool useful = false;\n                                        for (int k = 0; k < min(5, (int)targets.size()); k++) {\n                                            if (targets[k].i == blocker.i || targets[k].j == blocker.j) {\n                                                useful = true;\n                                                break;\n                                            }\n                                        }\n                                        if (useful) permanentBlocks.insert(blocker);\n                                        break;\n                                    }\n                                }\n                                break;\n                            }\n                        }\n                    }\n                }\n                \n                if (placed) {\n                    // Slide to target\n                    Point newEnd = slideFrom(current, dir);\n                    if (newEnd == target) {\n                        addAction('S', dir);\n                        \n                        // Only remove if not permanent\n                        if (!permanentBlocks.count(blocker)) {\n                            for (int d = 0; d < 4; d++) {\n                                if (getNext(current, d) == blocker) {\n                                    addAction('A', d);\n                                    break;\n                                }\n                            }\n                        }\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    \n    return false;\n}\n\nvoid moveToTarget(Point target) {\n    if (current == target) return;\n    \n    // Remove block if target is blocked\n    if (blocks.count(target)) {\n        for (int d = 0; d < 4; d++) {\n            Point adj = getNext(target, d);\n            if (inBounds(adj.i, adj.j) && !blocks.count(adj)) {\n                auto path = findPath(current, adj);\n                if (!path.empty()) {\n                    for (int dir : path) {\n                        addAction('M', dir);\n                    }\n                    for (int dd = 0; dd < 4; dd++) {\n                        if (getNext(current, dd) == target) {\n                            addAction('A', dd);\n                            break;\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Try sliding first\n    if (trySlideToTarget(target)) {\n        return;\n    }\n    \n    // Fall back to direct path\n    auto path = findPath(current, target);\n    for (int dir : path) {\n        addAction('M', dir);\n        if (actions.size() >= 1590) break;\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    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].i >> targets[i].j;\n    }\n    \n    current = targets[0];\n    \n    // Visit each target\n    for (int i = 1; i < m && actions.size() < 1590; i++) {\n        moveToTarget(targets[i]);\n    }\n    \n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n    \n    return 0;\n}"},"8":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;\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\nclass Solver {\nprivate:\n    int n;\n    vector<int> x, y, r;\n    vector<Rectangle> solution;\n    vector<bool> placed;\n    \n    bool has_overlap(const Rectangle& rect, int exclude_id) {\n        for (int i = 0; i < n; i++) {\n            if (i == exclude_id || !placed[i]) continue;\n            if (solution[i].overlaps(rect)) return true;\n        }\n        return false;\n    }\n    \n    Rectangle place_rectangle(int idx) {\n        int px = x[idx];\n        int py = y[idx];\n        int target_area = r[idx];\n        \n        // Calculate dimensions (prefer square-ish shapes)\n        int w = max(1, (int)sqrt(target_area));\n        int h = max(1, target_area / w);\n        \n        // Adjust if too large\n        if (w > 10000) {\n            w = 10000;\n            h = max(1, target_area / w);\n        }\n        if (h > 10000) {\n            h = 10000;\n            w = max(1, target_area / h);\n        }\n        \n        // Try to place at the desired position\n        int a = px;\n        int b = py;\n        int c = min(10000, a + w);\n        int d = min(10000, b + h);\n        \n        Rectangle rect = {a, b, c, d};\n        \n        // If it doesn't overlap, use it\n        if (!has_overlap(rect, idx)) {\n            return rect;\n        }\n        \n        // Try shifting slightly\n        for (int shift = 1; shift <= 5; shift++) {\n            // Try right\n            a = min(9999, px + shift);\n            c = min(10000, a + min(w, 10000 - a));\n            rect = {a, b, c, d};\n            if (!has_overlap(rect, idx)) return rect;\n            \n            // Try down\n            a = px;\n            b = min(9999, py + shift);\n            c = min(10000, a + w);\n            d = min(10000, b + min(h, 10000 - b));\n            rect = {a, b, c, d};\n            if (!has_overlap(rect, idx)) return rect;\n        }\n        \n        // If still can't place, use a small rectangle\n        w = min(10, w);\n        h = min(10, h);\n        \n        // Search in a grid pattern\n        for (int ga = 0; ga < 10000; ga += 100) {\n            for (int gb = 0; gb < 10000; gb += 100) {\n                int ta = min(ga, 10000 - w);\n                int tb = min(gb, 10000 - h);\n                rect = {ta, tb, ta + w, tb + h};\n                if (!has_overlap(rect, idx)) return rect;\n            }\n        }\n        \n        // Last resort: 1x1 rectangle\n        return {px, py, min(10000, px + 1), min(10000, py + 1)};\n    }\n    \npublic:\n    void solve() {\n        cin >> n;\n        x.resize(n);\n        y.resize(n);\n        r.resize(n);\n        solution.resize(n);\n        placed.resize(n, false);\n        \n        for (int i = 0; i < n; i++) {\n            cin >> x[i] >> y[i] >> r[i];\n        }\n        \n        // Sort by area (largest first)\n        vector<int> order(n);\n        for (int i = 0; i < n; i++) order[i] = i;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return r[i] > r[j];\n        });\n        \n        // Place rectangles\n        for (int idx : order) {\n            solution[idx] = place_rectangle(idx);\n            placed[idx] = true;\n        }\n    }\n    \n    void output() {\n        for (const auto& rect : solution) {\n            cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    solver.output();\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500;\n\nint si, sj;\nint tile[N][N];\nint points[N][N];\nvector<pair<int,int>> tile_squares[MAX_TILES];\nint tile_value[MAX_TILES];\nvector<int> tile_neighbors[MAX_TILES];\nint num_tiles;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n    int tiles_visited;\n    \n    bool operator<(const State& other) const {\n        // Prioritize by score per tile ratio, then total score\n        double my_ratio = tiles_visited > 0 ? (double)score / tiles_visited : 0;\n        double other_ratio = other.tiles_visited > 0 ? (double)other.score / other.tiles_visited : 0;\n        if (abs(my_ratio - other_ratio) > 1.0) {\n            return my_ratio > other_ratio;\n        }\n        return score > other.score;\n    }\n};\n\nvoid preprocess() {\n    num_tiles = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n            tile_squares[tile[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int t = 0; t < num_tiles; t++) {\n        tile_value[t] = 0;\n        for (auto [i, j] : tile_squares[t]) {\n            tile_value[t] += points[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int curr = tile[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int next = tile[ni][nj];\n                    if (next != curr) {\n                        tile_neighbors[curr].push_back(next);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Remove duplicates and sort by value\n    for (int t = 0; t < num_tiles; t++) {\n        sort(tile_neighbors[t].begin(), tile_neighbors[t].end());\n        tile_neighbors[t].erase(unique(tile_neighbors[t].begin(), tile_neighbors[t].end()), tile_neighbors[t].end());\n        \n        // Sort neighbors by their value\n        sort(tile_neighbors[t].begin(), tile_neighbors[t].end(), \n             [](int a, int b) { return tile_value[a] > tile_value[b]; });\n    }\n}\n\nState beam_search(int beam_width, double exploration_factor = 1.0) {\n    vector<State> current, next;\n    \n    State initial;\n    initial.i = si;\n    initial.j = sj;\n    initial.score = points[si][sj];\n    initial.visited[tile[si][sj]] = true;\n    initial.tiles_visited = 1;\n    \n    current.push_back(initial);\n    State best = initial;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    for (int depth = 0; depth < num_tiles && !current.empty(); depth++) {\n        next.clear();\n        \n        for (const State& state : current) {\n            if (state.score > best.score) {\n                best = state;\n            }\n            \n            // Get all possible moves\n            vector<tuple<double, State>> candidates;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = state.i + di[d];\n                int nj = state.j + dj[d];\n                \n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                int next_tile = tile[ni][nj];\n                if (state.visited[next_tile]) continue;\n                \n                State new_state = state;\n                new_state.i = ni;\n                new_state.j = nj;\n                new_state.path += dir_char[d];\n                new_state.score += points[ni][nj];\n                new_state.visited[next_tile] = true;\n                new_state.tiles_visited++;\n                \n                // Simple but effective scoring\n                double priority = tile_value[next_tile];\n                \n                // Add bonus for tiles with many unvisited neighbors\n                int unvisited_neighbors = 0;\n                double neighbor_value = 0;\n                for (int neighbor : tile_neighbors[next_tile]) {\n                    if (!new_state.visited[neighbor]) {\n                        unvisited_neighbors++;\n                        neighbor_value += tile_value[neighbor];\n                    }\n                }\n                \n                priority += neighbor_value * 0.3;\n                priority += unvisited_neighbors * 5;\n                \n                // Add small random factor for diversity\n                if (exploration_factor > 0) {\n                    priority += dis(gen) * exploration_factor * 50;\n                }\n                \n                candidates.push_back({priority, new_state});\n            }\n            \n            // Sort by priority\n            sort(candidates.rbegin(), candidates.rend());\n            \n            // Add top candidates\n            for (int i = 0; i < min(3, (int)candidates.size()); i++) {\n                next.push_back(get<1>(candidates[i]));\n            }\n        }\n        \n        // Keep top beam_width states\n        if (next.size() > beam_width) {\n            nth_element(next.begin(), next.begin() + beam_width, next.end());\n            next.resize(beam_width);\n        }\n        \n        current = next;\n    }\n    \n    return best;\n}\n\nState hill_climbing(State initial, int max_iterations = 1000) {\n    State current = initial;\n    State best = initial;\n    \n    for (int iter = 0; iter < max_iterations; iter++) {\n        bool improved = false;\n        \n        // Try to extend from current position\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 >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (current.visited[next_tile]) continue;\n            \n            State new_state = current;\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.path += dir_char[d];\n            new_state.score += points[ni][nj];\n            new_state.visited[next_tile] = true;\n            new_state.tiles_visited++;\n            \n            if (new_state.score > best.score) {\n                best = new_state;\n                current = new_state;\n                improved = true;\n                break;\n            }\n        }\n        \n        if (!improved) break;\n    }\n    \n    return best;\n}\n\nState greedy_with_backtrack(double randomness = 0.0) {\n    State state;\n    state.i = si;\n    state.j = sj;\n    state.score = points[si][sj];\n    state.visited[tile[si][sj]] = true;\n    state.tiles_visited = 1;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    stack<State> backtrack_stack;\n    backtrack_stack.push(state);\n    \n    State best = state;\n    int no_improvement = 0;\n    \n    while (!backtrack_stack.empty() && no_improvement < 50) {\n        state = backtrack_stack.top();\n        backtrack_stack.pop();\n        \n        vector<tuple<double, int, int, int>> moves;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            double score = tile_value[next_tile];\n            \n            // Look ahead\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!state.visited[neighbor]) {\n                    score += tile_value[neighbor] * 0.5;\n                }\n            }\n            \n            moves.push_back({score, ni, nj, d});\n        }\n        \n        if (moves.empty()) {\n            no_improvement++;\n            continue;\n        }\n        \n        sort(moves.rbegin(), moves.rend());\n        \n        // Try multiple branches with backtracking\n        int branches = min(2, (int)moves.size());\n        if (randomness > 0 && dis(gen) < randomness) {\n            branches = min(3, (int)moves.size());\n        }\n        \n        for (int i = branches - 1; i >= 0; i--) {\n            auto [score, ni, nj, dir] = moves[i];\n            \n            State new_state = state;\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.path += dir_char[dir];\n            new_state.score += points[ni][nj];\n            new_state.visited[tile[ni][nj]] = true;\n            new_state.tiles_visited++;\n            \n            if (i > 0) {\n                backtrack_stack.push(new_state);\n            } else {\n                state = new_state;\n                if (state.score > best.score) {\n                    best = state;\n                    no_improvement = 0;\n                } else {\n                    no_improvement++;\n                }\n            }\n        }\n    }\n    \n    return best;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess();\n    \n    State best;\n    best.score = 0;\n    \n    auto start = chrono::high_resolution_clock::now();\n    \n    // Multiple beam searches with different parameters\n    State b1 = beam_search(30, 0.0);\n    b1 = hill_climbing(b1);\n    if (b1.score > best.score) best = b1;\n    \n    State b2 = beam_search(20, 0.2);\n    b2 = hill_climbing(b2);\n    if (b2.score > best.score) best = b2;\n    \n    State b3 = beam_search(40, 0.1);\n    b3 = hill_climbing(b3);\n    if (b3.score > best.score) best = b3;\n    \n    // Greedy with backtracking\n    State g1 = greedy_with_backtrack(0.0);\n    g1 = hill_climbing(g1);\n    if (g1.score > best.score) best = g1;\n    \n    State g2 = greedy_with_backtrack(0.2);\n    g2 = hill_climbing(g2);\n    if (g2.score > best.score) best = g2;\n    \n    // Continue trying different approaches\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count();\n        if (elapsed > 1950) break;\n        \n        // Random beam search\n        State b = beam_search(25, 0.3);\n        b = hill_climbing(b);\n        if (b.score > best.score) best = b;\n        \n        // Random greedy\n        State g = greedy_with_backtrack(0.4);\n        g = hill_climbing(g);\n        if (g.score > best.score) best = g;\n    }\n    \n    cout << best.path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int QUERIES = 1000;\n\nstruct Edge {\n    double weight = 5000.0;\n    double variance = 2500000.0;  // Initial high uncertainty\n    vector<double> recent_obs;\n    int total_count = 0;\n    \n    void update(double observation) {\n        total_count++;\n        recent_obs.push_back(observation);\n        if (recent_obs.size() > 20) {\n            recent_obs.erase(recent_obs.begin());\n        }\n        \n        // Adaptive learning rate: aggressive early, conservative later\n        double base_lr = 0.5;\n        double decay_factor = 1.0 / (1.0 + total_count * 0.05);\n        double lr = base_lr * decay_factor;\n        \n        // Update weight using exponential moving average\n        weight = weight * (1 - lr) + observation * lr;\n        \n        // Update variance estimate\n        if (recent_obs.size() >= 2) {\n            double mean = 0;\n            for (double x : recent_obs) mean += x;\n            mean /= recent_obs.size();\n            \n            double var = 0;\n            for (double x : recent_obs) {\n                var += (x - mean) * (x - mean);\n            }\n            var /= recent_obs.size();\n            \n            variance = variance * 0.9 + var * 0.1;\n        }\n        \n        // Keep weight in reasonable bounds\n        weight = max(100.0, min(10000.0, weight));\n    }\n    \n    double get_weight(bool explore = false) const {\n        if (explore && total_count < 10) {\n            // Optimistic: subtract uncertainty for exploration\n            double uncertainty = sqrt(variance) / sqrt(total_count + 1.0);\n            return max(100.0, weight - 0.5 * uncertainty);\n        }\n        return weight;\n    }\n};\n\nEdge h_edges[N][N-1];\nEdge v_edges[N-1][N];\n\nstruct State {\n    double dist;\n    int i, j;\n    bool operator>(const State& other) const {\n        return dist > other.dist;\n    }\n};\n\npair<string, vector<pair<Edge*, double>>> dijkstra(int si, int sj, int ti, int tj, int query_num) {\n    vector<vector<double>> dist(N, vector<double>(N, 1e18));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    \n    bool explore = (query_num < 250);  // Explore in first 250 queries\n    \n    priority_queue<State, vector<State>, greater<State>> pq;\n    dist[si][sj] = 0;\n    pq.push({0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (d > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        // Try all 4 directions\n        if (i > 0) {\n            double w = v_edges[i-1][j].get_weight(explore);\n            if (dist[i][j] + w < dist[i-1][j]) {\n                dist[i-1][j] = dist[i][j] + w;\n                prev[i-1][j] = {i, j};\n                pq.push({dist[i-1][j], i-1, j});\n            }\n        }\n        if (i < N-1) {\n            double w = v_edges[i][j].get_weight(explore);\n            if (dist[i][j] + w < dist[i+1][j]) {\n                dist[i+1][j] = dist[i][j] + w;\n                prev[i+1][j] = {i, j};\n                pq.push({dist[i+1][j], i+1, j});\n            }\n        }\n        if (j > 0) {\n            double w = h_edges[i][j-1].get_weight(explore);\n            if (dist[i][j] + w < dist[i][j-1]) {\n                dist[i][j-1] = dist[i][j] + w;\n                prev[i][j-1] = {i, j};\n                pq.push({dist[i][j-1], i, j-1});\n            }\n        }\n        if (j < N-1) {\n            double w = h_edges[i][j].get_weight(explore);\n            if (dist[i][j] + w < dist[i][j+1]) {\n                dist[i][j+1] = dist[i][j] + w;\n                prev[i][j+1] = {i, j};\n                pq.push({dist[i][j+1], i, j+1});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    string path = \"\";\n    vector<pair<Edge*, double>> edges_used;\n    \n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto [pi, pj] = prev[ci][cj];\n        \n        if (pi == ci - 1) {\n            path += 'D';\n            edges_used.push_back({&v_edges[pi][pj], v_edges[pi][pj].weight});\n        } else if (pi == ci + 1) {\n            path += 'U';\n            edges_used.push_back({&v_edges[ci][cj], v_edges[ci][cj].weight});\n        } else if (pj == cj - 1) {\n            path += 'R';\n            edges_used.push_back({&h_edges[pi][pj], h_edges[pi][pj].weight});\n        } else if (pj == cj + 1) {\n            path += 'L';\n            edges_used.push_back({&h_edges[ci][cj], h_edges[ci][cj].weight});\n        }\n        \n        ci = pi; cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(edges_used.begin(), edges_used.end());\n    \n    return {path, edges_used};\n}\n\nvoid update_from_feedback(const vector<pair<Edge*, double>>& edges, int measured) {\n    if (edges.empty()) return;\n    \n    double total_estimate = 0;\n    for (auto [edge, weight] : edges) {\n        total_estimate += weight;\n    }\n    \n    if (total_estimate <= 0) return;\n    \n    // Account for noise: measured = actual * [0.9, 1.1]\n    // Use expected value (middle of range) for estimation\n    double ratio = measured / total_estimate;\n    \n    // Update each edge\n    for (auto [edge, weight] : edges) {\n        double observation = weight * ratio;\n        edge->update(observation);\n    }\n}\n\n// Simple local smoothing\nvoid smooth_weights() {\n    // Smooth horizontal edges within rows\n    for (int i = 0; i < N; i++) {\n        for (int j = 1; j < N-2; j++) {\n            if (h_edges[i][j].total_count < 3) continue;\n            \n            // Average with neighbors\n            double sum = h_edges[i][j].weight * 2;\n            double count = 2;\n            \n            if (h_edges[i][j-1].total_count > 0) {\n                sum += h_edges[i][j-1].weight;\n                count += 1;\n            }\n            if (h_edges[i][j+1].total_count > 0) {\n                sum += h_edges[i][j+1].weight;\n                count += 1;\n            }\n            \n            // Gentle smoothing\n            h_edges[i][j].weight = h_edges[i][j].weight * 0.85 + (sum/count) * 0.15;\n        }\n    }\n    \n    // Smooth vertical edges within columns\n    for (int j = 0; j < N; j++) {\n        for (int i = 1; i < N-2; i++) {\n            if (v_edges[i][j].total_count < 3) continue;\n            \n            double sum = v_edges[i][j].weight * 2;\n            double count = 2;\n            \n            if (v_edges[i-1][j].total_count > 0) {\n                sum += v_edges[i-1][j].weight;\n                count += 1;\n            }\n            if (v_edges[i+1][j].total_count > 0) {\n                sum += v_edges[i+1][j].weight;\n                count += 1;\n            }\n            \n            v_edges[i][j].weight = v_edges[i][j].weight * 0.85 + (sum/count) * 0.15;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int query = 0; query < QUERIES; query++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [path, edges] = dijkstra(si, sj, ti, tj, query);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_from_feedback(edges, measured);\n        \n        // Apply smoothing periodically after initial learning\n        if (query >= 200 && query % 50 == 49) {\n            smooth_weights();\n        }\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\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<string> strings(m);\n    for (int i = 0; i < m; i++) {\n        cin >> strings[i];\n    }\n    \n    // Best solution tracking\n    vector<vector<char>> bestGrid(n, vector<char>(n, '.'));\n    int bestMatched = 0;\n    int bestDots = n * n;\n    \n    // Random number generator\n    mt19937 rng(42);\n    \n    // Try multiple random configurations\n    for (int attempt = 0; attempt < 50; attempt++) {\n        vector<vector<char>> grid(n, vector<char>(n, '.'));\n        \n        // Shuffle string order for this attempt\n        vector<int> order(m);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        \n        // Sort by length for first half of attempts, random for second half\n        if (attempt < 25) {\n            sort(order.begin(), order.end(), [&](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        }\n        \n        // Helper functions\n        auto canPlaceH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int col = (c + i) % n;\n                if (grid[r][col] != '.' && grid[r][col] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto canPlaceV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int row = (r + i) % n;\n                if (grid[row][c] != '.' && grid[row][c] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto placeH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[r][(c + i) % n] = s[i];\n            }\n        };\n        \n        auto placeV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[(r + i) % n][c] = s[i];\n            }\n        };\n        \n        // Place strings\n        vector<bool> placed(m, false);\n        \n        for (int idx : order) {\n            const string& s = strings[idx];\n            vector<tuple<int, int, int, int>> positions; // r, c, dir, overlap\n            \n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (canPlaceH(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[r][(c + i) % n] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 0, overlap});\n                    }\n                    if (canPlaceV(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[(r + i) % n][c] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 1, overlap});\n                    }\n                }\n            }\n            \n            if (!positions.empty()) {\n                // Choose position based on strategy\n                int choice;\n                if (attempt < 10) {\n                    // Max overlap\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = 0;\n                } else if (attempt < 20) {\n                    // Random from top positions\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = uniform_int_distribution<int>(0, min(3, (int)positions.size()-1))(rng);\n                } else {\n                    // Pure random\n                    choice = uniform_int_distribution<int>(0, positions.size()-1)(rng);\n                }\n                \n                auto [r, c, dir, overlap] = positions[choice];\n                if (dir == 0) {\n                    placeH(r, c, s);\n                } else {\n                    placeV(r, c, s);\n                }\n                placed[idx] = true;\n            }\n        }\n        \n        // Check all strings against final grid\n        int matched = 0;\n        for (const string& s : strings) {\n            bool found = false;\n            for (int r = 0; r < n && !found; r++) {\n                for (int c = 0; c < n && !found; c++) {\n                    // Check horizontal\n                    bool matchH = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[r][(c + i) % n] != s[i]) {\n                            matchH = false;\n                            break;\n                        }\n                    }\n                    if (matchH) {\n                        found = true;\n                        break;\n                    }\n                    \n                    // Check vertical\n                    bool matchV = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[(r + i) % n][c] != s[i]) {\n                            matchV = false;\n                            break;\n                        }\n                    }\n                    if (matchV) {\n                        found = true;\n                        break;\n                    }\n                }\n            }\n            if (found) matched++;\n        }\n        \n        // Count dots\n        int dots = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == '.') dots++;\n            }\n        }\n        \n        // Update best if better\n        if (matched > bestMatched || (matched == bestMatched && dots < bestDots)) {\n            bestGrid = grid;\n            bestMatched = matched;\n            bestDots = dots;\n        }\n    }\n    \n    // Fill remaining dots intelligently\n    map<char, int> freq;\n    for (const auto& s : strings) {\n        for (char c : s) {\n            freq[c]++;\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (bestGrid[i][j] == '.') {\n                // Look at neighbors\n                map<char, int> neighborFreq;\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (di == 0 && dj == 0) continue;\n                        int ni = (i + di + n) % n;\n                        int nj = (j + dj + n) % n;\n                        if (bestGrid[ni][nj] != '.') {\n                            neighborFreq[bestGrid[ni][nj]]++;\n                        }\n                    }\n                }\n                \n                if (!neighborFreq.empty()) {\n                    char best = 'A';\n                    int bestScore = -1;\n                    for (auto [c, cnt] : neighborFreq) {\n                        int score = cnt * 1000 + freq[c];\n                        if (score > bestScore) {\n                            bestScore = score;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                } else {\n                    // Use most frequent character\n                    char best = 'A';\n                    int maxF = 0;\n                    for (auto [c, f] : freq) {\n                        if (f > maxF) {\n                            maxF = f;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                }\n            }\n        }\n    }\n    \n    // Output the best grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestGrid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\npair<int, string> dijkstra(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return {0, \"\"};\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    \n    pq.push({0, si, sj});\n    dist[si][sj] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (d > dist[i][j]) continue;\n        if (i == ei && j == ej) {\n            // Reconstruct path\n            string path = \"\";\n            int ci = ei, cj = ej;\n            while (!(ci == si && cj == sj)) {\n                path = dir[parent_dir[ci][cj]] + path;\n                auto [pi, pj] = parent[ci][cj];\n                ci = pi; cj = pj;\n            }\n            return {d, path};\n        }\n        \n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (is_road(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    parent[ni][nj] = {i, j};\n                    parent_dir[ni][nj] = k;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return {1e9, \"\"};\n}\n\nvector<pair<int,int>> get_visible(int i, int j) {\n    vector<pair<int,int>> vis;\n    if (!is_road(i, j)) return vis;\n    vis.push_back({i, j});\n    for (int jj = j-1; jj >= 0 && is_road(i, jj); jj--) vis.push_back({i, jj});\n    for (int jj = j+1; jj < N && is_road(i, jj); jj++) vis.push_back({i, jj});\n    for (int ii = i-1; ii >= 0 && is_road(ii, j); ii--) vis.push_back({ii, j});\n    for (int ii = i+1; ii < N && is_road(ii, j); ii++) vis.push_back({ii, j});\n    return vis;\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    // Analyze visibility from each position\n    vector<vector<vector<pair<int,int>>>> visibility(N, vector<vector<pair<int,int>>>(N));\n    vector<pair<int,int>> all_roads;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j)) {\n                all_roads.push_back({i, j});\n                visibility[i][j] = get_visible(i, j);\n            }\n        }\n    }\n    \n    // Greedy set cover approach\n    vector<vector<bool>> covered(N, vector<bool>(N, false));\n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    auto mark_visible = [&](int i, int j) {\n        for (auto [vi, vj] : visibility[i][j]) {\n            covered[vi][vj] = true;\n        }\n    };\n    \n    mark_visible(si, sj);\n    \n    // Iteratively select positions that cover the most uncovered squares\n    while (true) {\n        int best_i = -1, best_j = -1;\n        int best_new_coverage = 0;\n        \n        for (auto [i, j] : all_roads) {\n            if (covered[i][j]) {\n                // Count new coverage from this position\n                int new_coverage = 0;\n                for (auto [vi, vj] : visibility[i][j]) {\n                    if (!covered[vi][vj]) new_coverage++;\n                }\n                \n                if (new_coverage > best_new_coverage) {\n                    best_new_coverage = new_coverage;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        \n        // If no covered position helps, find best uncovered position\n        if (best_new_coverage < 3) {  // Threshold to avoid too many waypoints\n            for (auto [i, j] : all_roads) {\n                if (!covered[i][j]) {\n                    int new_coverage = 0;\n                    for (auto [vi, vj] : visibility[i][j]) {\n                        if (!covered[vi][vj]) new_coverage++;\n                    }\n                    \n                    if (new_coverage > best_new_coverage) {\n                        best_new_coverage = new_coverage;\n                        best_i = i;\n                        best_j = j;\n                    }\n                }\n            }\n        }\n        \n        if (best_i == -1 || best_new_coverage == 0) break;\n        \n        waypoints.push_back({best_i, best_j});\n        mark_visible(best_i, best_j);\n    }\n    \n    // Optimize waypoint ordering using 2-opt\n    if (waypoints.size() <= 15) {\n        // Precompute distances between all waypoints\n        vector<vector<int>> dist_matrix(waypoints.size(), vector<int>(waypoints.size(), 0));\n        for (int i = 0; i < waypoints.size(); i++) {\n            for (int j = i+1; j < waypoints.size(); j++) {\n                auto [d, _] = dijkstra(waypoints[i].first, waypoints[i].second,\n                                      waypoints[j].first, waypoints[j].second);\n                dist_matrix[i][j] = dist_matrix[j][i] = d;\n            }\n        }\n        \n        // 2-opt improvement\n        vector<int> tour(waypoints.size());\n        iota(tour.begin(), tour.end(), 0);\n        \n        bool improved = true;\n        while (improved) {\n            improved = false;\n            for (int i = 1; i < tour.size() - 1; i++) {\n                for (int j = i + 1; j < tour.size(); j++) {\n                    int cur_cost = dist_matrix[tour[i-1]][tour[i]] + \n                                  dist_matrix[tour[j]][tour[(j+1) % tour.size()]];\n                    int new_cost = dist_matrix[tour[i-1]][tour[j]] + \n                                  dist_matrix[tour[i]][tour[(j+1) % tour.size()]];\n                    \n                    if (new_cost < cur_cost) {\n                        reverse(tour.begin() + i, tour.begin() + j + 1);\n                        improved = true;\n                    }\n                }\n            }\n        }\n        \n        // Reorder waypoints according to optimized tour\n        vector<pair<int,int>> optimized_waypoints;\n        for (int idx : tour) {\n            optimized_waypoints.push_back(waypoints[idx]);\n        }\n        waypoints = optimized_waypoints;\n    } else {\n        // For larger tours, use nearest neighbor\n        vector<pair<int,int>> tour;\n        vector<bool> used(waypoints.size(), false);\n        tour.push_back(waypoints[0]);\n        used[0] = true;\n        \n        for (int t = 1; t < waypoints.size(); t++) {\n            int best_idx = -1;\n            int best_dist = 1e9;\n            auto [ci, cj] = tour.back();\n            \n            for (int idx = 0; idx < waypoints.size(); idx++) {\n                if (!used[idx]) {\n                    auto [ni, nj] = waypoints[idx];\n                    auto [d, _] = dijkstra(ci, cj, ni, nj);\n                    if (d < best_dist) {\n                        best_dist = d;\n                        best_idx = idx;\n                    }\n                }\n            }\n            \n            if (best_idx != -1) {\n                tour.push_back(waypoints[best_idx]);\n                used[best_idx] = true;\n            }\n        }\n        waypoints = tour;\n    }\n    \n    // Build the route\n    string route = \"\";\n    for (int t = 1; t < waypoints.size(); t++) {\n        auto [d, path] = dijkstra(waypoints[t-1].first, waypoints[t-1].second,\n                                  waypoints[t].first, waypoints[t].second);\n        route += path;\n    }\n    \n    // Return to start\n    if (!waypoints.empty() && waypoints.back() != make_pair(si, sj)) {\n        auto [d, path] = dijkstra(waypoints.back().first, waypoints.back().second, si, sj);\n        route += path;\n    }\n    \n    cout << route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> task_total(N, 0);\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> d[i][j];\n            task_total[i] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> dependents(N);\n    vector<vector<int>> dependencies(N);\n    vector<int> dep_count(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        dependents[u].push_back(v);\n        dependencies[v].push_back(u);\n        dep_count[v]++;\n    }\n    \n    // Calculate critical metrics for each task\n    vector<int> descendants(N, 0);\n    vector<int> max_chain(N, 0);\n    vector<bool> visited(N, false);\n    \n    function<pair<int,int>(int)> dfs = [&](int task) -> pair<int,int> {\n        if (visited[task]) return {descendants[task], max_chain[task]};\n        visited[task] = true;\n        \n        int desc = 0;\n        int chain = 0;\n        for (int dep : dependents[task]) {\n            auto [d, c] = dfs(dep);\n            desc += d + 1;\n            chain = max(chain, c);\n        }\n        descendants[task] = desc;\n        max_chain[task] = chain + 1;\n        return {desc, chain + 1};\n    };\n    \n    for (int i = 0; i < N; i++) {\n        if (!visited[i]) dfs(i);\n    }\n    \n    // Initialize skills with smart priors based on task distribution\n    double avg_task_req = 0;\n    for (int i = 0; i < N; i++) avg_task_req += task_total[i];\n    avg_task_req /= N;\n    \n    vector<vector<double>> skill_est(M, vector<double>(K));\n    vector<vector<double>> skill_min(M, vector<double>(K, 0));\n    vector<vector<double>> skill_max(M, vector<double>(K, 100));\n    \n    // Initialize with some variance to encourage exploration\n    mt19937 rng(42);\n    uniform_real_distribution<> init_dist(30, 50);\n    for (int m = 0; m < M; m++) {\n        for (int k = 0; k < K; k++) {\n            skill_est[m][k] = init_dist(rng);\n        }\n    }\n    \n    vector<int> completed_count(M, 0);\n    vector<double> member_efficiency(M, 1.0);\n    vector<set<pair<int,int>>> observations(M); // (task, actual_days)\n    \n    vector<int> task_state(N, -1);\n    vector<int> member_task(M, -1);\n    vector<int> start_day(M, 0);\n    vector<int> remaining_deps(N);\n    for (int i = 0; i < N; i++) remaining_deps[i] = dep_count[i];\n    \n    int day = 0;\n    int completed = 0;\n    int total_assigned = 0;\n    \n    while (completed < N && day < 1950) {\n        day++;\n        \n        // Adaptive strategy based on progress\n        double progress_rate = (double)completed / max(1, day);\n        double time_pressure = (double)day / 1950;\n        bool exploration_phase = (total_assigned < M * 5) || (day < 50 && completed_count[0] < 3);\n        \n        // Find available tasks\n        vector<int> available;\n        for (int i = 0; i < N; i++) {\n            if (task_state[i] == -1 && remaining_deps[i] == 0) {\n                available.push_back(i);\n            }\n        }\n        \n        // Priority scoring with adaptive weights\n        vector<pair<double, int>> task_priority;\n        for (int task : available) {\n            double score = 0;\n            \n            // Critical path weight increases with time pressure\n            score += max_chain[task] * (1000 + time_pressure * 1000);\n            \n            // Descendants weight\n            score += descendants[task] * (50 + time_pressure * 50);\n            \n            // Unlocking bonus - tasks that will unlock many others\n            int unlock_count = 0;\n            for (int succ : dependents[task]) {\n                if (remaining_deps[succ] == 1) unlock_count++;\n            }\n            score += unlock_count * 200;\n            \n            // Task difficulty penalty (prefer easier tasks under time pressure)\n            score -= task_total[task] * (0.5 + time_pressure);\n            \n            task_priority.push_back({score, task});\n        }\n        sort(task_priority.rbegin(), task_priority.rend());\n        \n        // Member-task assignment\n        vector<pair<int, int>> assignments;\n        vector<bool> used_member(M, false);\n        \n        for (auto [_, task] : task_priority) {\n            if (assignments.size() >= M) break;\n            \n            vector<pair<double, int>> member_scores;\n            \n            for (int m = 0; m < M; m++) {\n                if (member_task[m] != -1 || used_member[m]) continue;\n                \n                // Calculate expected completion time\n                double expected_w = 0;\n                int matching_skills = 0;\n                for (int k = 0; k < K; k++) {\n                    double gap = max(0.0, d[task][k] - skill_est[m][k]);\n                    expected_w += gap;\n                    if (d[task][k] > 0 && skill_est[m][k] >= d[task][k]) {\n                        matching_skills++;\n                    }\n                }\n                \n                double expected_time = (expected_w < 0.01) ? 1 : max(1.0, expected_w);\n                expected_time *= member_efficiency[m];\n                \n                double score = -expected_time * 100;\n                \n                // Skill match bonus\n                score += matching_skills * 10;\n                \n                // Exploration bonus in early game\n                if (exploration_phase) {\n                    if (completed_count[m] == 0) {\n                        score += 1000; // Strong bonus for untested members\n                    } else if (completed_count[m] < 5) {\n                        score += (5 - completed_count[m]) * 50;\n                    }\n                }\n                \n                // Confidence bonus - prefer members we know well for critical tasks\n                if (max_chain[task] > 10 && completed_count[m] > 10) {\n                    score += 20;\n                }\n                \n                // Workload balancing\n                double avg_completed = (double)completed / M;\n                if (completed_count[m] < avg_completed - 5) {\n                    score += (avg_completed - completed_count[m]) * 5;\n                }\n                \n                member_scores.push_back({score, m});\n            }\n            \n            if (!member_scores.empty()) {\n                sort(member_scores.rbegin(), member_scores.rend());\n                int best_member = member_scores[0].second;\n                \n                assignments.push_back({best_member, task});\n                used_member[best_member] = true;\n                member_task[best_member] = task;\n                start_day[best_member] = day;\n                task_state[task] = 0;\n                total_assigned++;\n            }\n        }\n        \n        // Output\n        cout << assignments.size();\n        for (auto [m, t] : assignments) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << \"\\n\";\n        cout.flush();\n        \n        // Read completions\n        int n_completed;\n        cin >> n_completed;\n        \n        if (n_completed == -1) break;\n        \n        for (int i = 0; i < n_completed; i++) {\n            int m;\n            cin >> m;\n            m--;\n            \n            int task = member_task[m];\n            if (task != -1) {\n                task_state[task] = 1;\n                completed++;\n                \n                int actual_days = day - start_day[m] + 1;\n                observations[m].insert({task, actual_days});\n                \n                for (int dep : dependents[task]) {\n                    remaining_deps[dep]--;\n                }\n                \n                // Update skill estimates with bounded updates\n                double lr = 0.4 / (1 + completed_count[m] * 0.03);\n                \n                if (actual_days == 1) {\n                    // Skills definitely meet all requirements\n                    for (int k = 0; k < K; k++) {\n                        skill_min[m][k] = max(skill_min[m][k], (double)d[task][k]);\n                        if (skill_est[m][k] < d[task][k]) {\n                            skill_est[m][k] = d[task][k] + 1;\n                        }\n                    }\n                } else {\n                    // Estimate w from actual_days\n                    double observed_w = actual_days; // Approximate, ignoring \u00b13 noise\n                    \n                    // Calculate current estimated w\n                    double current_w = 0;\n                    vector<double> gaps(K);\n                    int gap_count = 0;\n                    for (int k = 0; k < K; k++) {\n                        gaps[k] = max(0.0, d[task][k] - skill_est[m][k]);\n                        current_w += gaps[k];\n                        if (gaps[k] > 0) gap_count++;\n                    }\n                    \n                    if (current_w > 0.01 && gap_count > 0) {\n                        // Distribute the error proportionally\n                        double error = observed_w - current_w;\n                        \n                        for (int k = 0; k < K; k++) {\n                            if (gaps[k] > 0) {\n                                double adjustment = (gaps[k] / current_w) * error * lr;\n                                skill_est[m][k] -= adjustment;\n                                \n                                // Apply bounds\n                                skill_est[m][k] = max(skill_min[m][k], \n                                                     min(skill_max[m][k], skill_est[m][k]));\n                            }\n                        }\n                    }\n                    \n                    // Update efficiency estimate\n                    double expected_days = max(1.0, current_w);\n                    double efficiency_update = actual_days / expected_days;\n                    member_efficiency[m] = 0.9 * member_efficiency[m] + 0.1 * efficiency_update;\n                }\n                \n                // Re-estimate skills using all observations periodically\n                if (completed_count[m] % 10 == 9 && observations[m].size() > 5) {\n                    // Use gradient descent on all observations to refine estimates\n                    for (int iter = 0; iter < 5; iter++) {\n                        vector<double> gradient(K, 0);\n                        double total_error = 0;\n                        \n                        for (auto [t, act_days] : observations[m]) {\n                            double pred_w = 0;\n                            for (int k = 0; k < K; k++) {\n                                pred_w += max(0.0, d[t][k] - skill_est[m][k]);\n                            }\n                            double pred_days = (pred_w < 0.01) ? 1 : max(1.0, pred_w);\n                            double error = pred_days - act_days;\n                            total_error += error * error;\n                            \n                            if (pred_w > 0.01) {\n                                for (int k = 0; k < K; k++) {\n                                    if (d[t][k] > skill_est[m][k]) {\n                                        gradient[k] -= error * (1.0 / observations[m].size());\n                                    }\n                                }\n                            }\n                        }\n                        \n                        // Update with small step\n                        for (int k = 0; k < K; k++) {\n                            skill_est[m][k] += gradient[k] * 0.1;\n                            skill_est[m][k] = max(skill_min[m][k], \n                                                 min(skill_max[m][k], skill_est[m][k]));\n                        }\n                    }\n                }\n                \n                completed_count[m]++;\n                member_task[m] = -1;\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n    double score;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    vector<Order> orders(1000);\n    \n    // Read all orders\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        orders[i].id = i + 1;\n        \n        // Score based on proximity to center and delivery distance\n        int dist_from_center_pickup = manhattan(400, 400, orders[i].ax, orders[i].ay);\n        int dist_from_center_delivery = manhattan(400, 400, orders[i].cx, orders[i].cy);\n        int delivery_dist = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n        \n        // Prefer orders close to center with reasonable delivery distances\n        orders[i].score = dist_from_center_pickup + dist_from_center_delivery + delivery_dist * 0.3;\n    }\n    \n    // Sort orders by score (lower is better)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    \n    // Select the best 50 orders\n    vector<int> selected_ids;\n    vector<pair<int, int>> pickups, deliveries;\n    \n    for (int i = 0; i < 50; i++) {\n        selected_ids.push_back(orders[i].id);\n        pickups.push_back({orders[i].ax, orders[i].ay});\n        deliveries.push_back({orders[i].cx, orders[i].cy});\n    }\n    \n    // Build route using greedy approach with preference for clearing deliveries\n    vector<pair<int, int>> route;\n    route.push_back({400, 400});\n    \n    vector<bool> picked(50, false);\n    vector<bool> delivered(50, false);\n    int num_delivered = 0;\n    \n    while (num_delivered < 50) {\n        int cur_x = route.back().first;\n        int cur_y = route.back().second;\n        \n        int best_dist = INT_MAX;\n        int best_idx = -1;\n        bool best_is_pickup = false;\n        \n        // Count how many items we're currently carrying\n        int carrying = 0;\n        for (int i = 0; i < 50; i++) {\n            if (picked[i] && !delivered[i]) carrying++;\n        }\n        \n        // If carrying many items, prioritize deliveries\n        double delivery_weight = (carrying > 10) ? 0.7 : 1.0;\n        \n        // Consider pickups\n        for (int i = 0; i < 50; i++) {\n            if (picked[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, pickups[i].first, pickups[i].second);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = i;\n                best_is_pickup = true;\n            }\n        }\n        \n        // Consider deliveries for items we're carrying\n        for (int i = 0; i < 50; i++) {\n            if (!picked[i] || delivered[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, deliveries[i].first, deliveries[i].second);\n            int weighted_dist = dist * delivery_weight;\n            \n            if (weighted_dist < best_dist) {\n                best_dist = weighted_dist;\n                best_idx = i;\n                best_is_pickup = false;\n            }\n        }\n        \n        if (best_is_pickup) {\n            route.push_back(pickups[best_idx]);\n            picked[best_idx] = true;\n        } else {\n            route.push_back(deliveries[best_idx]);\n            delivered[best_idx] = true;\n            num_delivered++;\n        }\n    }\n    \n    // Return to office\n    route.push_back({400, 400});\n    \n    // Output\n    cout << \"50\";\n    for (int id : selected_ids) {\n        cout << \" \" << id;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        \n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n    \n    int getComponents() {\n        return components;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const 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<pair<int, int>> edges(M);\n    vector<int> distances(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n        int dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        int dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        distances[i] = round(sqrt(dx * dx + dy * dy));\n    }\n    \n    UnionFind uf(N);\n    int edges_accepted = 0;\n    int connecting_edges_seen = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n        \n        int u = edges[i].first;\n        int v = edges[i].second;\n        int d_i = distances[i];\n        double ratio = (double)l_i / d_i;\n        \n        int decision = 0;\n        \n        if (!uf.connected(u, v)) {\n            // Edge connects different components\n            connecting_edges_seen++;\n            int edges_needed = uf.getComponents() - 1;\n            int remaining_edges = M - i - 1;\n            double progress = (double)i / M;\n            \n            // Calculate dynamic threshold based on multiple factors\n            double threshold = 3.0;  // Default: accept everything\n            \n            if (edges_needed > 0) {\n                // Estimate how many more connecting edges we'll see\n                // Based on ratio of connecting edges seen so far\n                double connecting_ratio = (double)connecting_edges_seen / (i + 1);\n                double expected_connecting = remaining_edges * connecting_ratio;\n                \n                // Real safety factor based on expected connecting edges\n                double real_safety = expected_connecting / edges_needed;\n                \n                // Dynamic threshold based on safety and progress\n                if (real_safety > 8.0 && progress < 0.5) {\n                    threshold = 2.5;  // Be selective early with high safety\n                } else if (real_safety > 5.0 && progress < 0.6) {\n                    threshold = 2.6;\n                } else if (real_safety > 3.0 && progress < 0.7) {\n                    threshold = 2.7;\n                } else if (real_safety > 2.0 && progress < 0.8) {\n                    threshold = 2.8;\n                } else if (real_safety > 1.5) {\n                    threshold = 2.9;\n                }\n                \n                // Extra selectivity for very early edges with lots of components\n                if (i < 50 && edges_needed > 300 && ratio > 2.3) {\n                    threshold = min(threshold, 2.3);\n                }\n            }\n            \n            // Always accept very good edges\n            if (ratio <= 1.2) {\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            } else if (ratio < threshold) {\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            }\n            \n            // Safety override: accept if critically needed\n            if (edges_needed > 0 && remaining_edges <= edges_needed * 1.2) {\n                if (decision == 0) {\n                    decision = 1;\n                    uf.unite(u, v);\n                    edges_accepted++;\n                }\n            }\n        }\n        \n        cout << decision << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Position& other) const {\n        return x < other.x || (x == other.x && y < other.y);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> walls;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dirChar[4] = {'U', 'D', 'L', 'R'};\n    const char blockChar[4] = {'u', 'd', 'l', 'r'};\n    \n    bool isValid(int x, int y) const {\n        return x >= 1 && x <= GRID_SIZE && y >= 1 && y <= GRID_SIZE;\n    }\n    \n    bool canMakeWall(int x, int y) const {\n        if (!isValid(x, y) || walls[x][y]) return false;\n        \n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return false;\n        }\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny)) {\n                for (const auto& p : petPos) {\n                    if (p.x == nx && p.y == ny) return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    int manhattanDist(int x1, int y1, int x2, int y2) const {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    Position findSafeCorner() const {\n        vector<Position> corners = {\n            {3, 3}, {3, 27}, {27, 3}, {27, 27},\n            {3, 15}, {27, 15}, {15, 3}, {15, 27}\n        };\n        \n        Position best = corners[0];\n        int bestScore = -1000000;\n        \n        for (const auto& corner : corners) {\n            int score = 0;\n            \n            // Distance from all pets\n            for (int i = 0; i < N; i++) {\n                int dist = manhattanDist(corner.x, corner.y, petPos[i].x, petPos[i].y);\n                if (petType[i] == 4) { // Dog\n                    score += dist * 3;\n                } else {\n                    score += dist;\n                }\n            }\n            \n            // Prefer actual corners\n            if ((corner.x == 3 || corner.x == 27) && (corner.y == 3 || corner.y == 27)) {\n                score += 50;\n            }\n            \n            // Distance from humans\n            for (const auto& h : humanPos) {\n                score -= manhattanDist(corner.x, corner.y, h.x, h.y);\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                best = corner;\n            }\n        }\n        \n        return best;\n    }\n    \n    double getMinPetDistance(int x, int y) const {\n        double minDist = 1000;\n        for (const auto& p : petPos) {\n            minDist = min(minDist, (double)manhattanDist(x, y, p.x, p.y));\n        }\n        return minDist;\n    }\n    \npublic:\n    void solve() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n        }\n        \n        walls.assign(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        \n        Position safeCorner = findSafeCorner();\n        \n        for (int turn = 0; turn < MAX_TURNS; turn++) {\n            string actions(M, '.');\n            set<Position> wallsBeingBuilt;\n            \n            // Recalculate safe corner periodically\n            if (turn % 50 == 0 && turn > 0) {\n                safeCorner = findSafeCorner();\n            }\n            \n            // Step 1: Plan all wall building actions first\n            if (turn >= 20) {\n                for (int i = 0; i < M; i++) {\n                    const Position& human = humanPos[i];\n                    \n                    // Check if human is in danger from pets\n                    bool inDanger = false;\n                    for (int j = 0; j < N; j++) {\n                        int dist = manhattanDist(human.x, human.y, petPos[j].x, petPos[j].y);\n                        if ((petType[j] == 4 && dist <= 2) || dist <= 1) {\n                            inDanger = true;\n                            break;\n                        }\n                    }\n                    \n                    // Skip wall building if in danger\n                    if (inDanger) continue;\n                    \n                    int bestDir = -1;\n                    double bestScore = -1000;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int wx = human.x + dx[d];\n                        int wy = human.y + dy[d];\n                        \n                        if (canMakeWall(wx, wy) && !wallsBeingBuilt.count({wx, wy})) {\n                            double score = 0;\n                            \n                            // Distance from pets\n                            score += getMinPetDistance(wx, wy) * 2;\n                            \n                            // Connect to existing walls\n                            int connectedWalls = 0;\n                            for (int dd = 0; dd < 4; dd++) {\n                                int nwx = wx + dx[dd];\n                                int nwy = wy + dy[dd];\n                                if (isValid(nwx, nwy) && walls[nwx][nwy]) {\n                                    connectedWalls++;\n                                }\n                            }\n                            score += connectedWalls * 10;\n                            \n                            // Build around the safe corner\n                            int distToCorner = manhattanDist(wx, wy, safeCorner.x, safeCorner.y);\n                            if (distToCorner >= 2 && distToCorner <= 4) {\n                                score += 20;\n                            }\n                            \n                            // Avoid building too close to center of human group\n                            int humansNearby = 0;\n                            for (const auto& h : humanPos) {\n                                if (manhattanDist(wx, wy, h.x, h.y) <= 1) {\n                                    humansNearby++;\n                                }\n                            }\n                            if (humansNearby >= M - 1) {\n                                score -= 30;\n                            }\n                            \n                            if (score > bestScore && score > 5) {\n                                bestScore = score;\n                                bestDir = d;\n                            }\n                        }\n                    }\n                    \n                    if (bestDir != -1) {\n                        int wx = human.x + dx[bestDir];\n                        int wy = human.y + dy[bestDir];\n                        actions[i] = blockChar[bestDir];\n                        wallsBeingBuilt.insert({wx, wy});\n                    }\n                }\n            }\n            \n            // Step 2: Plan movements for humans not building walls\n            for (int i = 0; i < M; i++) {\n                if (actions[i] != '.') continue; // Already building a wall\n                \n                const Position& human = humanPos[i];\n                \n                // Check if in immediate danger\n                bool needEscape = false;\n                Position nearestThreat = {-1, -1};\n                int minThreatDist = 1000;\n                \n                for (int j = 0; j < N; j++) {\n                    int dist = manhattanDist(human.x, human.y, petPos[j].x, petPos[j].y);\n                    if ((petType[j] == 4 && dist <= 2) || dist <= 1) {\n                        needEscape = true;\n                        if (dist < minThreatDist) {\n                            minThreatDist = dist;\n                            nearestThreat = petPos[j];\n                        }\n                    }\n                }\n                \n                if (needEscape) {\n                    // Emergency escape\n                    int bestDir = -1;\n                    double maxSafety = -1;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = human.x + dx[d];\n                        int ny = human.y + dy[d];\n                        \n                        if (isValid(nx, ny) && !walls[nx][ny] && !wallsBeingBuilt.count({nx, ny})) {\n                            double safety = getMinPetDistance(nx, ny);\n                            if (nearestThreat.x != -1) {\n                                safety += manhattanDist(nx, ny, nearestThreat.x, nearestThreat.y) * 2;\n                            }\n                            \n                            if (safety > maxSafety) {\n                                maxSafety = safety;\n                                bestDir = d;\n                            }\n                        }\n                    }\n                    \n                    if (bestDir != -1) {\n                        actions[i] = dirChar[bestDir];\n                    }\n                } else if (turn < 80) {\n                    // Move towards safe corner\n                    int currentDist = manhattanDist(human.x, human.y, safeCorner.x, safeCorner.y);\n                    if (currentDist > 3) {\n                        int bestDir = -1;\n                        int minDist = currentDist;\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            \n                            if (isValid(nx, ny) && !walls[nx][ny] && !wallsBeingBuilt.count({nx, ny})) {\n                                int newDist = manhattanDist(nx, ny, safeCorner.x, safeCorner.y);\n                                // Also check pet distance to avoid walking into danger\n                                double petDist = getMinPetDistance(nx, ny);\n                                \n                                if (newDist < minDist && petDist >= 2) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                        }\n                    }\n                }\n            }\n            \n            cout << actions << endl;\n            cout.flush();\n            \n            // Apply actions\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                Position& human = humanPos[i];\n                \n                if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    for (int d = 0; d < 4; d++) {\n                        if (dirChar[d] == action) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            // Double-check the move is valid\n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                bool blocked = false;\n                                // Check if another human is making this square a wall\n                                for (int j = 0; j < M; j++) {\n                                    if (i != j && (actions[j] == 'u' || actions[j] == 'd' || \n                                                   actions[j] == 'l' || actions[j] == 'r')) {\n                                        for (int dd = 0; dd < 4; dd++) {\n                                            if (blockChar[dd] == actions[j]) {\n                                                int wx = humanPos[j].x + dx[dd];\n                                                int wy = humanPos[j].y + dy[dd];\n                                                if (wx == nx && wy == ny) {\n                                                    blocked = true;\n                                                    break;\n                                                }\n                                            }\n                                        }\n                                    }\n                                    if (blocked) break;\n                                }\n                                \n                                if (!blocked) {\n                                    human.x = nx;\n                                    human.y = ny;\n                                }\n                            }\n                            break;\n                        }\n                    }\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            if (isValid(wx, wy)) {\n                                walls[wx][wy] = true;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Read pet movements\n            for (int i = 0; i < N; i++) {\n                string petMove;\n                cin >> petMove;\n                \n                for (char c : petMove) {\n                    if (c != '.') {\n                        for (int d = 0; d < 4; d++) {\n                            if (dirChar[d] == c) {\n                                petPos[i].x += dx[d];\n                                petPos[i].y += dy[d];\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    // Build wall information\n    vector<vector<bool>> canGoRight(20, vector<bool>(20, false));\n    vector<vector<bool>> canGoDown(20, vector<bool>(20, false));\n    \n    for (int i = 0; i < 20; i++) {\n        for (int j = 0; j < 19; j++) {\n            if (h[i][j] == '0') {\n                canGoRight[i][j] = true;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 19; i++) {\n        for (int j = 0; j < 20; j++) {\n            if (v[i][j] == '0') {\n                canGoDown[i][j] = true;\n            }\n        }\n    }\n    \n    // BFS to find shortest path\n    queue<pair<int,int>> q;\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> parent(20, vector<pair<int,int>>(20, {-1, -1}));\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        // Check all 4 directions\n        if (j < 19 && canGoRight[i][j] && dist[i][j+1] == -1) {\n            dist[i][j+1] = dist[i][j] + 1;\n            parent[i][j+1] = {i, j};\n            q.push({i, j+1});\n        }\n        if (j > 0 && canGoRight[i][j-1] && dist[i][j-1] == -1) {\n            dist[i][j-1] = dist[i][j] + 1;\n            parent[i][j-1] = {i, j};\n            q.push({i, j-1});\n        }\n        if (i < 19 && canGoDown[i][j] && dist[i+1][j] == -1) {\n            dist[i+1][j] = dist[i][j] + 1;\n            parent[i+1][j] = {i, j};\n            q.push({i+1, j});\n        }\n        if (i > 0 && canGoDown[i-1][j] && dist[i-1][j] == -1) {\n            dist[i-1][j] = dist[i][j] + 1;\n            parent[i-1][j] = {i, j};\n            q.push({i-1, j});\n        }\n    }\n    \n    // Reconstruct shortest path\n    string shortestPath;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        auto [pi, pj] = parent[ci][cj];\n        \n        if (ci - pi == 1) shortestPath = \"D\" + shortestPath;\n        else if (ci - pi == -1) shortestPath = \"U\" + shortestPath;\n        else if (cj - pj == 1) shortestPath = \"R\" + shortestPath;\n        else if (cj - pj == -1) shortestPath = \"L\" + shortestPath;\n        \n        ci = pi;\n        cj = pj;\n    }\n    \n    int pathLen = shortestPath.length();\n    string result;\n    \n    // Back to simple strategy with refined repetition\n    // Key insight: for most cases, repeating each move 1-3 times based on p works well\n    int baseRepeat = 1;\n    \n    // Refined thresholds based on probability theory\n    // For k repetitions: success prob per move = 1 - p^k\n    // k=1: p=0.5 \u2192 50%, p=0.4 \u2192 60%, p=0.3 \u2192 70%, p=0.2 \u2192 80%, p=0.1 \u2192 90%\n    // k=2: p=0.5 \u2192 75%, p=0.4 \u2192 84%, p=0.3 \u2192 91%, p=0.2 \u2192 96%, p=0.1 \u2192 99%\n    // k=3: p=0.5 \u2192 87.5%, p=0.4 \u2192 93.6%, p=0.3 \u2192 97.3%, p=0.2 \u2192 99.2%, p=0.1 \u2192 99.9%\n    \n    if (p >= 0.45) {\n        baseRepeat = 3;  // High forget rate needs more redundancy\n    } else if (p >= 0.35) {\n        baseRepeat = 2;  // Medium-high forget rate\n    } else if (p >= 0.25) {\n        baseRepeat = 2;  // Medium forget rate\n    } else {\n        baseRepeat = 1;  // Low forget rate, path repetition is more efficient\n    }\n    \n    // Check if basic repetition fits\n    int expandedLen = pathLen * baseRepeat;\n    \n    if (expandedLen <= 200) {\n        // First, add the path with repetitions for each move\n        for (char move : shortestPath) {\n            for (int r = 0; r < baseRepeat; r++) {\n                result += move;\n            }\n        }\n        \n        // Then repeat the entire expanded sequence as much as possible\n        while (result.length() + expandedLen <= 200) {\n            for (char move : shortestPath) {\n                for (int r = 0; r < baseRepeat; r++) {\n                    result += move;\n                }\n            }\n        }\n        \n        // Fill remaining space with the original path cycling\n        int idx = 0;\n        while (result.length() < 200) {\n            result += shortestPath[idx % pathLen];\n            idx++;\n        }\n    } else {\n        // Path too long for full repetition\n        // Use adaptive repetition based on available space\n        int maxRepeat = 200 / pathLen;\n        \n        if (maxRepeat >= 2) {\n            // We can at least double the moves\n            int useRepeat = min(baseRepeat, maxRepeat);\n            \n            for (char move : shortestPath) {\n                for (int r = 0; r < useRepeat && result.length() < 200; r++) {\n                    result += move;\n                }\n            }\n        } else {\n            // Very long path, just add once and cycle\n            result = shortestPath;\n        }\n        \n        // Fill remaining\n        int idx = 0;\n        while (result.length() < 200) {\n            result += shortestPath[idx % pathLen];\n            idx++;\n        }\n    }\n    \n    // Ensure exactly 200 or less\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint rotations[N][N];\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nint rotate_tile(int tile) {\n    if (tile <= 3) return (tile + 1) % 4;\n    if (tile == 4) return 5;\n    if (tile == 5) return 4;\n    if (tile == 6) return 7;\n    return 6;\n}\n\nint get_tile_state(int i, int j) {\n    int t = tiles[i][j];\n    for (int r = 0; r < rotations[i][j]; r++) {\n        t = rotate_tile(t);\n    }\n    return t;\n}\n\nint trace_path(int si, int sj, int sd, vector<vector<vector<bool>>>& visited) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;\n        \n        int tile_state = get_tile_state(i, j);\n        int d2 = to[tile_state][d];\n        if (d2 == -1) return 0;\n        \n        int ni = i + di[d2];\n        int nj = j + dj[d2];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return 0;\n        \n        i = ni;\n        j = nj;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (length > N * N * 4) return 0; // Prevent infinite loops\n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\nvector<int> find_all_loops() {\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    vector<int> loops;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = trace_path(i, j, d, visited);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    // Mark all positions in this loop as visited\n                    int ci = i, cj = j, cd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ci][cj][cd] = true;\n                        int tile_state = get_tile_state(ci, cj);\n                        int d2 = to[tile_state][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    return loops;\n}\n\nint calculate_score() {\n    vector<int> loops = find_all_loops();\n    if (loops.size() < 2) return 0;\n    sort(loops.rbegin(), loops.rend());\n    return loops[0] * loops[1];\n}\n\n// Try to connect tiles greedily\nvoid greedy_init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int best_rot = 0;\n            int best_connections = -1;\n            \n            for (int r = 0; r < 4; r++) {\n                rotations[i][j] = r;\n                int connections = 0;\n                int tile_state = get_tile_state(i, j);\n                \n                // Count valid connections to neighbors\n                for (int d = 0; d < 4; d++) {\n                    int d2 = to[tile_state][d];\n                    if (d2 == -1) continue;\n                    \n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    \n                    int neighbor_state = get_tile_state(ni, nj);\n                    int return_dir = (d2 + 2) % 4;\n                    if (to[neighbor_state][return_dir] != -1) {\n                        connections++;\n                    }\n                }\n                \n                if (connections > best_connections) {\n                    best_connections = connections;\n                    best_rot = r;\n                }\n            }\n            \n            rotations[i][j] = best_rot;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rot_dist(0, 3);\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    // Start with greedy initialization\n    greedy_init();\n    \n    int best_score = calculate_score();\n    int best_rotations[N][N];\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    auto start_time = chrono::steady_clock::now();\n    int iteration = 0;\n    int no_improve = 0;\n    \n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1900) {\n        iteration++;\n        \n        // Multi-restart strategy\n        if (no_improve > 10000) {\n            // Random restart\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n            no_improve = 0;\n        }\n        \n        // Try different neighborhood moves\n        int move_type = rng() % 3;\n        vector<pair<pair<int,int>, int>> changes;\n        \n        if (move_type == 0) {\n            // Single tile change\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            int old_rot = rotations[i][j];\n            int new_rot = rot_dist(rng);\n            if (new_rot == old_rot) continue;\n            changes.push_back({{i, j}, old_rot});\n            rotations[i][j] = new_rot;\n        } else if (move_type == 1) {\n            // Change 2x2 block\n            int i = rng() % (N-1);\n            int j = rng() % (N-1);\n            for (int di = 0; di < 2; di++) {\n                for (int dj = 0; dj < 2; dj++) {\n                    changes.push_back({{i+di, j+dj}, rotations[i+di][j+dj]});\n                    rotations[i+di][j+dj] = rot_dist(rng);\n                }\n            }\n        } else {\n            // Change a row or column\n            if (rng() % 2 == 0) {\n                int i = pos_dist(rng);\n                for (int j = 0; j < N; j++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            } else {\n                int j = pos_dist(rng);\n                for (int i = 0; i < N; i++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n        }\n        \n        int new_score = calculate_score();\n        \n        if (new_score > best_score) {\n            best_score = new_score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n            no_improve = 0;\n        } else {\n            // Revert changes with some probability\n            double temp = max(1.0, 50.0 * (1.0 - iteration / 100000.0));\n            if (prob_dist(rng) >= exp((new_score - best_score) / temp)) {\n                for (auto& [pos, old_val] : changes) {\n                    rotations[pos.first][pos.second] = old_val;\n                }\n            }\n            no_improve++;\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, T;\nvector<vector<int>> board;\npair<int, int> empty_pos;\nvector<char> answer;\nmt19937 rng(42);\n\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int opposite_dir[] = {1, 0, 3, 2};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\nvoid find_empty() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n                return;\n            }\n        }\n    }\n}\n\nvoid make_move(int dir) {\n    int nx = empty_pos.first + dx[dir];\n    int ny = empty_pos.second + dy[dir];\n    if (in_bounds(nx, ny)) {\n        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        empty_pos = {nx, ny};\n        answer.push_back(dir_char[dir]);\n    }\n}\n\nstruct UnionFind {\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x); y = find(y);\n        if (x == y) return false;\n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    int get_size(int x) { return size[find(x)]; }\n};\n\nint get_tree_size() {\n    // Map positions to indices\n    map<pair<int,int>, int> pos_to_id;\n    int id = 0;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] != 0) {\n                pos_to_id[{i,j}] = id++;\n            }\n        }\n    }\n    \n    if (id == 0) return 0;\n    \n    UnionFind uf(id);\n    vector<set<int>> adj(id);\n    int edge_count = 0;\n    \n    // Build graph\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 cur_id = pos_to_id[{i,j}];\n            \n            // Check down\n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    int next_id = pos_to_id[{i+1,j}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n            \n            // Check right\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    int next_id = pos_to_id[{i,j+1}];\n                    if (adj[cur_id].insert(next_id).second) {\n                        adj[next_id].insert(cur_id);\n                        uf.unite(cur_id, next_id);\n                        edge_count++;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Find largest tree (connected component without cycles)\n    int max_tree = 0;\n    map<int, vector<int>> components;\n    for (int i = 0; i < id; i++) {\n        components[uf.find(i)].push_back(i);\n    }\n    \n    for (auto& [root, comp] : components) {\n        int comp_edges = 0;\n        set<pair<int,int>> counted;\n        for (int v : comp) {\n            for (int u : adj[v]) {\n                if (counted.insert({min(u,v), max(u,v)}).second) {\n                    comp_edges++;\n                }\n            }\n        }\n        \n        // It's a tree if edges = vertices - 1\n        if (comp_edges == (int)comp.size() - 1) {\n            max_tree = max(max_tree, (int)comp.size());\n        }\n    }\n    \n    return max_tree;\n}\n\n// BFS to move empty square to target position\nvector<int> move_empty_to(pair<int,int> target) {\n    if (empty_pos == target) return {};\n    \n    queue<pair<pair<int,int>, vector<int>>> q;\n    set<pair<int,int>> visited;\n    q.push({empty_pos, {}});\n    visited.insert(empty_pos);\n    \n    while (!q.empty()) {\n        auto [pos, path] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            int nx = pos.first + dx[dir];\n            int ny = pos.second + dy[dir];\n            if (!in_bounds(nx, ny) || visited.count({nx, ny})) continue;\n            \n            vector<int> new_path = path;\n            new_path.push_back(dir);\n            \n            if (make_pair(nx, ny) == target) {\n                return new_path;\n            }\n            \n            visited.insert({nx, ny});\n            q.push({{nx, ny}, new_path});\n        }\n    }\n    return {};\n}\n\n// Evaluate board state\ndouble evaluate_board() {\n    int tree_size = get_tree_size();\n    int connected_edges = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) continue;\n            \n            if (i < N-1 && board[i+1][j] != 0) {\n                if ((board[i][j] & DOWN) && (board[i+1][j] & UP)) {\n                    connected_edges++;\n                }\n            }\n            if (j < N-1 && board[i][j+1] != 0) {\n                if ((board[i][j] & RIGHT) && (board[i][j+1] & LEFT)) {\n                    connected_edges++;\n                }\n            }\n        }\n    }\n    \n    return tree_size * 1000.0 + connected_edges;\n}\n\nvoid solve() {\n    int best_tree = get_tree_size();\n    auto best_board = board;\n    auto best_empty = empty_pos;\n    int stagnation = 0;\n    \n    while (answer.size() < T * 0.95 && best_tree < N * N - 1) {\n        double temp = 1.0 - (double)answer.size() / T;\n        \n        if (stagnation > 50) {\n            // Strategic restart: try to connect largest components\n            int depth = min(5, (int)(T - answer.size()) / 10);\n            \n            // Try multiple random sequences and pick the best\n            auto save_board = board;\n            auto save_empty = empty_pos;\n            int save_ans_size = answer.size();\n            \n            double best_eval = evaluate_board();\n            vector<int> best_moves;\n            \n            for (int attempt = 0; attempt < 10; attempt++) {\n                board = save_board;\n                empty_pos = save_empty;\n                vector<int> moves;\n                \n                for (int m = 0; m < depth; m++) {\n                    vector<int> dirs;\n                    for (int d = 0; d < 4; d++) {\n                        if (in_bounds(empty_pos.first + dx[d], empty_pos.second + dy[d])) {\n                            if (moves.empty() || d != opposite_dir[moves.back()]) {\n                                dirs.push_back(d);\n                            }\n                        }\n                    }\n                    if (!dirs.empty()) {\n                        int dir = dirs[rng() % dirs.size()];\n                        moves.push_back(dir);\n                        int nx = empty_pos.first + dx[dir];\n                        int ny = empty_pos.second + dy[dir];\n                        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                        empty_pos = {nx, ny};\n                    }\n                }\n                \n                double eval = evaluate_board();\n                if (eval > best_eval) {\n                    best_eval = eval;\n                    best_moves = moves;\n                }\n            }\n            \n            board = save_board;\n            empty_pos = save_empty;\n            for (int dir : best_moves) {\n                make_move(dir);\n            }\n            \n            stagnation = 0;\n        }\n        \n        // Try deeper lookahead\n        int lookahead = min(3, (int)(T - answer.size()) / 20);\n        \n        function<pair<double, vector<int>>(int, int, vector<int>&)> search = \n            [&](int depth, int last_dir, vector<int>& path) -> pair<double, vector<int>> {\n            \n            if (depth == 0) {\n                return {evaluate_board(), path};\n            }\n            \n            double best_score = -1e9;\n            vector<int> best_path;\n            \n            for (int dir = 0; dir < 4; dir++) {\n                if (last_dir != -1 && dir == opposite_dir[last_dir]) continue;\n                \n                int nx = empty_pos.first + dx[dir];\n                int ny = empty_pos.second + dy[dir];\n                if (!in_bounds(nx, ny)) continue;\n                \n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                auto old_empty = empty_pos;\n                empty_pos = {nx, ny};\n                path.push_back(dir);\n                \n                auto [score, sub_path] = search(depth - 1, dir, path);\n                \n                if (score > best_score || \n                    (score == best_score && (rng() % 100) < temp * 50)) {\n                    best_score = score;\n                    best_path = sub_path;\n                }\n                \n                path.pop_back();\n                empty_pos = old_empty;\n                swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n            }\n            \n            return {best_score, best_path};\n        };\n        \n        vector<int> empty_path;\n        auto [score, path] = search(lookahead, -1, empty_path);\n        \n        if (!path.empty()) {\n            make_move(path[0]);\n            \n            int new_tree = get_tree_size();\n            if (new_tree > best_tree) {\n                best_tree = new_tree;\n                best_board = board;\n                best_empty = empty_pos;\n                stagnation = 0;\n            } else {\n                stagnation++;\n            }\n        } else {\n            stagnation++;\n        }\n    }\n}\n\nint main() {\n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            if (line[j] >= '0' && line[j] <= '9') {\n                board[i][j] = line[j] - '0';\n            } else {\n                board[i][j] = line[j] - 'a' + 10;\n            }\n        }\n    }\n    \n    find_empty();\n    solve();\n    \n    for (char c : answer) {\n        cout << c;\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst double RADIUS = 10000.0;\nconst double EPS = 1e-9;\nconst double TIME_LIMIT = 2.85;\n\nstruct Point {\n    double x, y;\n    Point(double x = 0, double y = 0) : x(x), y(y) {}\n    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }\n    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }\n    Point operator*(double t) const { return Point(x * t, y * t); }\n    double norm2() const { return x * x + y * y; }\n    double norm() const { return sqrt(norm2()); }\n};\n\nstruct Line {\n    int px, py, qx, qy;\n    Line(int px = 0, int py = 0, int qx = 0, int qy = 0) : px(px), py(py), qx(qx), qy(qy) {}\n    \n    int side(const Point& p) const {\n        double dx1 = qx - px;\n        double dy1 = qy - py;\n        double dx2 = p.x - px;\n        double dy2 = p.y - py;\n        double v = dx1 * dy2 - dy1 * dx2;\n        if (v > EPS) return 1;\n        if (v < -EPS) return -1;\n        return 0;\n    }\n};\n\nint N, K;\nvector<int> a(11);\nvector<Point> strawberries;\nvector<Line> lines;\nvector<Line> bestLines;\nint bestScore = 0;\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool insideCircle(const Point& p) {\n    return p.norm2() < RADIUS * RADIUS - EPS;\n}\n\nint calculateScore() {\n    map<vector<int>, int> regionCount;\n    \n    for (int i = 0; i < N; i++) {\n        if (!insideCircle(strawberries[i])) continue;\n        \n        vector<int> sideVector;\n        bool onLine = false;\n        \n        for (const Line& line : lines) {\n            int s = line.side(strawberries[i]);\n            if (s == 0) {\n                onLine = true;\n                break;\n            }\n            sideVector.push_back(s);\n        }\n        \n        if (!onLine) {\n            regionCount[sideVector]++;\n        }\n    }\n    \n    vector<int> b(11, 0);\n    for (auto& [region, cnt] : regionCount) {\n        if (cnt <= 10) b[cnt]++;\n    }\n    \n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(a[d], b[d]);\n    }\n    \n    return score;\n}\n\nLine randomLine() {\n    uniform_int_distribution<int> coord_dist(-20000, 20000);\n    int px = coord_dist(rng);\n    int py = coord_dist(rng);\n    int qx = coord_dist(rng);\n    int qy = coord_dist(rng);\n    while (px == qx && py == qy) {\n        qx = coord_dist(rng);\n        qy = coord_dist(rng);\n    }\n    return Line(px, py, qx, qy);\n}\n\nLine targetedLine() {\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    int i = idx_dist(rng);\n    int j = idx_dist(rng);\n    while (i == j) j = idx_dist(rng);\n    \n    Point mid = (strawberries[i] + strawberries[j]) * 0.5;\n    Point dir = strawberries[j] - strawberries[i];\n    \n    if (dir.norm() < EPS) return randomLine();\n    \n    uniform_real_distribution<double> angle_dist(-0.6, 0.6);\n    double angle = atan2(dir.y, dir.x) + angle_dist(rng);\n    \n    uniform_real_distribution<double> offset_dist(-2500, 2500);\n    mid.x += offset_dist(rng);\n    mid.y += offset_dist(rng);\n    \n    int px = (int)mid.x;\n    int py = (int)mid.y;\n    int qx = px + (int)(15000 * cos(angle + M_PI/2));\n    int qy = py + (int)(15000 * sin(angle + M_PI/2));\n    \n    return Line(px, py, qx, qy);\n}\n\nLine smartLine() {\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    int center = idx_dist(rng);\n    \n    vector<pair<double, int>> dists;\n    for (int i = 0; i < N; i++) {\n        if (i != center) {\n            double d = (strawberries[i] - strawberries[center]).norm2();\n            dists.push_back({d, i});\n        }\n    }\n    sort(dists.begin(), dists.end());\n    \n    int gapIdx = -1;\n    double maxGap = 0;\n    for (int i = 0; i < min(15, (int)dists.size() - 1); i++) {\n        double gap = sqrt(dists[i+1].first) - sqrt(dists[i].first);\n        if (gap > maxGap) {\n            maxGap = gap;\n            gapIdx = i;\n        }\n    }\n    \n    if (gapIdx >= 0 && gapIdx < (int)dists.size() - 1) {\n        int idx1 = dists[gapIdx].second;\n        int idx2 = dists[gapIdx + 1].second;\n        \n        Point mid = (strawberries[idx1] + strawberries[idx2]) * 0.5;\n        Point dir = strawberries[idx2] - strawberries[idx1];\n        \n        if (dir.norm() > EPS) {\n            double angle = atan2(dir.y, dir.x) + M_PI/2;\n            \n            int px = (int)mid.x;\n            int py = (int)mid.y;\n            int qx = px + (int)(15000 * cos(angle));\n            int qy = py + (int)(15000 * sin(angle));\n            \n            return Line(px, py, qx, qy);\n        }\n    }\n    \n    return targetedLine();\n}\n\nLine densityLine() {\n    double maxDensity = 0;\n    Point bestPoint;\n    \n    for (int sample = 0; sample < 10; sample++) {\n        uniform_int_distribution<int> idx_dist(0, N - 1);\n        int idx = idx_dist(rng);\n        Point p = strawberries[idx];\n        \n        double density = 0;\n        for (int i = 0; i < N; i++) {\n            double d = (strawberries[i] - p).norm();\n            if (d < 3000) {\n                density += 1.0 / (1.0 + d);\n            }\n        }\n        \n        if (density > maxDensity) {\n            maxDensity = density;\n            bestPoint = p;\n        }\n    }\n    \n    uniform_real_distribution<double> angle_dist(0, 2 * M_PI);\n    double angle = angle_dist(rng);\n    \n    int px = (int)bestPoint.x;\n    int py = (int)bestPoint.y;\n    int qx = px + (int)(15000 * cos(angle));\n    int qy = py + (int)(15000 * sin(angle));\n    \n    return Line(px, py, qx, qy);\n}\n\nvoid solve() {\n    double startTime = clock();\n    lines.clear();\n    bestLines.clear();\n    bestScore = 0;\n    \n    // Phase 1: Greedy initialization\n    for (int iter = 0; iter < min(25, K); iter++) {\n        if ((clock() - startTime) / CLOCKS_PER_SEC > TIME_LIMIT * 0.25) break;\n        \n        Line bestLine = randomLine();\n        int bestImprovement = -1;\n        int currentScore = calculateScore();\n        \n        for (int trial = 0; trial < 40; trial++) {\n            Line candidate;\n            int strategy = trial % 5;\n            switch(strategy) {\n                case 0: candidate = randomLine(); break;\n                case 1: candidate = targetedLine(); break;\n                case 2: candidate = smartLine(); break;\n                case 3: candidate = densityLine(); break;\n                case 4: {\n                    if (!lines.empty()) {\n                        Line& ref = lines[rng() % lines.size()];\n                        double dx = ref.qx - ref.px;\n                        double dy = ref.qy - ref.py;\n                        uniform_int_distribution<int> offset_dist(-5000, 5000);\n                        int cx = offset_dist(rng);\n                        int cy = offset_dist(rng);\n                        candidate = Line(cx - (int)dy, cy + (int)dx, cx + (int)dy, cy - (int)dx);\n                    } else {\n                        candidate = randomLine();\n                    }\n                    break;\n                }\n            }\n            \n            lines.push_back(candidate);\n            int newScore = calculateScore();\n            lines.pop_back();\n            \n            if (newScore - currentScore > bestImprovement) {\n                bestImprovement = newScore - currentScore;\n                bestLine = candidate;\n            }\n        }\n        \n        if (bestImprovement >= 0) {\n            lines.push_back(bestLine);\n        }\n    }\n    \n    // Phase 2: Simulated annealing\n    int currentScore = calculateScore();\n    bestLines = lines;\n    bestScore = currentScore;\n    \n    double temp = 12.0;\n    int iter = 0;\n    int stagnation = 0;\n    int lastImprovement = 0;\n    \n    vector<int> strategySuccess(5, 0);\n    vector<int> strategyTries(5, 1);\n    \n    while ((clock() - startTime) / CLOCKS_PER_SEC < TIME_LIMIT) {\n        iter++;\n        \n        if (iter % 500 == 0) {\n            double elapsed = (clock() - startTime) / CLOCKS_PER_SEC;\n            temp = 12.0 * (1.0 - elapsed / TIME_LIMIT);\n            \n            if (iter - lastImprovement > 2000) {\n                temp = min(20.0, temp * 3);\n                lastImprovement = iter;\n                stagnation++;\n                \n                if (stagnation > 3) {\n                    if (lines.size() > 10) {\n                        for (int i = 0; i < 5 && lines.size() > 5; i++) {\n                            lines.erase(lines.begin() + (rng() % lines.size()));\n                        }\n                        currentScore = calculateScore();\n                    }\n                    stagnation = 0;\n                }\n            }\n        }\n        \n        uniform_real_distribution<double> op_dist(0, 1);\n        double op = op_dist(rng);\n        \n        if (op < 0.35 && lines.size() < (size_t)K) {\n            // Add a line\n            int totalSuccess = 1;\n            for (int s : strategySuccess) totalSuccess += s;\n            \n            uniform_int_distribution<int> weight_dist(0, totalSuccess - 1);\n            int w = weight_dist(rng);\n            int strategy = 0;\n            int cumSum = 0;\n            for (int s = 0; s < 5; s++) {\n                cumSum += strategySuccess[s] + 1;\n                if (w < cumSum) {\n                    strategy = s;\n                    break;\n                }\n            }\n            \n            Line newLine;\n            switch(strategy) {\n                case 0: newLine = randomLine(); break;\n                case 1: newLine = targetedLine(); break;\n                case 2: newLine = smartLine(); break;\n                case 3: newLine = densityLine(); break;\n                case 4: {\n                    if (!lines.empty()) {\n                        Line& ref = lines[rng() % lines.size()];\n                        double dx = ref.qx - ref.px;\n                        double dy = ref.qy - ref.py;\n                        uniform_int_distribution<int> offset_dist(-5000, 5000);\n                        int cx = offset_dist(rng);\n                        int cy = offset_dist(rng);\n                        newLine = Line(cx - (int)dy, cy + (int)dx, cx + (int)dy, cy - (int)dx);\n                    } else {\n                        newLine = randomLine();\n                    }\n                    break;\n                }\n            }\n            \n            lines.push_back(newLine);\n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                strategyTries[strategy]++;\n                if (delta > 0) {\n                    strategySuccess[strategy]++;\n                    lastImprovement = iter;\n                }\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.pop_back();\n            }\n        } else if (op < 0.55 && lines.size() > 5) {\n            // Remove a line\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line removed = lines[idx];\n            lines.erase(lines.begin() + idx);\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                if (delta > 0) lastImprovement = iter;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines.insert(lines.begin() + idx, removed);\n            }\n        } else if (lines.size() > 0) {\n            // Modify a line\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line old = lines[idx];\n            \n            if (rng() % 4 == 0) {\n                // Small perturbation\n                uniform_int_distribution<int> perturb_dist(-2000, 2000);\n                lines[idx].px += perturb_dist(rng);\n                lines[idx].py += perturb_dist(rng);\n                lines[idx].qx += perturb_dist(rng);\n                lines[idx].qy += perturb_dist(rng);\n            } else {\n                int strategy = rng() % 4;\n                switch(strategy) {\n                    case 0: lines[idx] = randomLine(); break;\n                    case 1: lines[idx] = targetedLine(); break;\n                    case 2: lines[idx] = smartLine(); break;\n                    case 3: lines[idx] = densityLine(); break;\n                }\n            }\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.01)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                if (delta > 0) lastImprovement = iter;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n            } else {\n                lines[idx] = old;\n            }\n        }\n    }\n    \n    lines = bestLines;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    \n    solve();\n    \n    cout << lines.size() << \"\\n\";\n    for (const Line& line : lines) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return tie(x, y) < tie(p.x, p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n    Point operator-(const Point& p) const {\n        return Point(x - p.x, y - p.y);\n    }\n};\n\nint N, M;\nset<Point> dots;\nset<pair<Point, Point>> usedEdges;\nclock_t startTime;\n\nint weight(int x, int y) {\n    int c = (N - 1) / 2;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\ndouble getElapsedTime() {\n    return (double)(clock() - startTime) / CLOCKS_PER_SEC;\n}\n\nint dot(Point a, Point b) {\n    return a.x * b.x + a.y * b.y;\n}\n\nbool isRectangle(Point p1, Point p2, Point p3, Point p4) {\n    // Check if p1-p2-p3-p4 forms a rectangle\n    Point v12 = p2 - p1;\n    Point v23 = p3 - p2;\n    Point v34 = p4 - p3;\n    Point v41 = p1 - p4;\n    \n    // For a rectangle, opposite sides must be equal and adjacent sides perpendicular\n    if (v12.x == v34.x && v12.y == v34.y && \n        v23.x == v41.x && v23.y == v41.y &&\n        dot(v12, v23) == 0) {\n        return true;\n    }\n    \n    return false;\n}\n\nvector<Point> getAllPointsOnSegment(Point a, Point b) {\n    vector<Point> points;\n    int dx = (b.x > a.x) ? 1 : (b.x < a.x) ? -1 : 0;\n    int dy = (b.y > a.y) ? 1 : (b.y < a.y) ? -1 : 0;\n    \n    Point curr = a;\n    while (!(curr == b)) {\n        points.push_back(curr);\n        curr.x += dx;\n        curr.y += dy;\n    }\n    points.push_back(b);\n    return points;\n}\n\nbool tryRectangle(Point newDot, vector<Point>& existingDots, vector<int>& output) {\n    if (dots.count(newDot)) return false;\n    if (newDot.x < 0 || newDot.x >= N || newDot.y < 0 || newDot.y >= N) return false;\n    \n    // Try all permutations of 3 existing dots\n    sort(existingDots.begin(), existingDots.end());\n    do {\n        Point p2 = existingDots[0];\n        Point p3 = existingDots[1]; \n        Point p4 = existingDots[2];\n        \n        if (!isRectangle(newDot, p2, p3, p4)) continue;\n        \n        // Check perimeter has no other dots\n        vector<pair<Point, Point>> edges = {\n            {newDot, p2}, {p2, p3}, {p3, p4}, {p4, newDot}\n        };\n        \n        bool valid = true;\n        set<Point> corners = {newDot, p2, p3, p4};\n        \n        for (auto& edge : edges) {\n            auto points = getAllPointsOnSegment(edge.first, edge.second);\n            for (auto& pt : points) {\n                if (!corners.count(pt) && dots.count(pt)) {\n                    valid = false;\n                    break;\n                }\n            }\n            if (!valid) break;\n        }\n        \n        if (!valid) continue;\n        \n        // Check edges not already used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            if (usedEdges.count({a, b})) {\n                valid = false;\n                break;\n            }\n        }\n        \n        if (!valid) continue;\n        \n        // Found valid rectangle\n        output = {newDot.x, newDot.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y};\n        \n        // Mark edges as used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            usedEdges.insert({a, b});\n        }\n        \n        return true;\n        \n    } while (next_permutation(existingDots.begin(), existingDots.end()));\n    \n    return false;\n}\n\nint main() {\n    startTime = clock();\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert(Point(x, y));\n    }\n    \n    vector<vector<int>> result;\n    int center = (N - 1) / 2;\n    \n    while (getElapsedTime() < 4.0) {\n        bool found = false;\n        \n        // Try positions from center outward\n        for (int dist = 0; dist <= N && !found; dist++) {\n            for (int x = max(0, center - dist); x <= min(N - 1, center + dist) && !found; x++) {\n                for (int y = max(0, center - dist); y <= min(N - 1, center + dist) && !found; y++) {\n                    if (abs(x - center) != dist && abs(y - center) != dist) continue;\n                    \n                    Point newDot(x, y);\n                    if (dots.count(newDot)) continue;\n                    \n                    // Try to form rectangle with 3 existing dots\n                    vector<Point> dotVec(dots.begin(), dots.end());\n                    int n = dotVec.size();\n                    \n                    // Try combinations of 3 dots\n                    for (int i = 0; i < n && !found; i++) {\n                        for (int j = i + 1; j < n && !found; j++) {\n                            for (int k = j + 1; k < n && !found; k++) {\n                                vector<Point> threeDots = {dotVec[i], dotVec[j], dotVec[k]};\n                                vector<int> output;\n                                \n                                if (tryRectangle(newDot, threeDots, output)) {\n                                    dots.insert(newDot);\n                                    result.push_back(output);\n                                    found = true;\n                                }\n                                \n                                if (getElapsedTime() > 4.0) break;\n                            }\n                            if (getElapsedTime() > 4.0) break;\n                        }\n                        if (getElapsedTime() > 4.0) break;\n                    }\n                }\n            }\n        }\n        \n        if (!found) break;\n    }\n    \n    cout << result.size() << endl;\n    for (auto& r : result) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << \" \";\n            cout << r[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int TOTAL = 100;\n\nstruct Board {\n    int grid[N][N];\n    int candyCount = 0;\n    \n    Board() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void place(int pos, int flavor) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == pos) {\n                        grid[i][j] = flavor;\n                        candyCount++;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tiltForward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = 0;\n            for (int i = 0; i < N; i++) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltBackward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = N-1;\n            for (int i = N-1; i >= 0; i--) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tiltLeft() {\n        for (int i = 0; i < N; i++) {\n            int writePos = 0;\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltRight() {\n        for (int i = 0; i < N; i++) {\n            int writePos = N-1;\n            for (int j = N-1; j >= 0; j--) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') tiltForward();\n        else if (dir == 'B') tiltBackward();\n        else if (dir == 'L') tiltLeft();\n        else if (dir == 'R') tiltRight();\n    }\n    \n    // Calculate sum of squares of component sizes\n    pair<double, map<int, int>> calculateScore() {\n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        \n        double totalScore = 0;\n        map<int, int> largestComponent; // largest component size for each flavor\n        \n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int flavor = grid[i][j];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    \n                    totalScore += size * size;\n                    largestComponent[flavor] = max(largestComponent[flavor], size);\n                }\n            }\n        }\n        return {totalScore, largestComponent};\n    }\n    \n    // Count adjacent pairs (for early game)\n    int countAdjacent() {\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (i + 1 < N && grid[i+1][j] == grid[i][j]) count += 2;\n                    if (j + 1 < N && grid[i][j+1] == grid[i][j]) count += 2;\n                }\n            }\n        }\n        return count;\n    }\n    \n    // Count components\n    int countComponents() {\n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        int count = 0;\n        \n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    count++;\n                    int flavor = grid[i][j];\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return count;\n    }\n    \n    // Main evaluation function\n    double evaluate(int t, const vector<int>& flavors, const vector<int>& flavorFreq) {\n        auto [baseScore, largestComp] = calculateScore();\n        double score = baseScore * 10; // Heavily weight the main metric\n        \n        int numComponents = countComponents();\n        \n        // Progressive penalty for fragmentation\n        double fragPenalty = numComponents * (1 + t * 0.02);\n        score -= fragPenalty;\n        \n        // Strong bonus for very large components\n        for (auto [flavor, size] : largestComp) {\n            if (size >= 30) score += size * 50;\n            else if (size >= 20) score += size * 20;\n            else if (size >= 10) score += size * 8;\n        }\n        \n        // Look ahead with frequency weighting\n        if (t < TOTAL - 1) {\n            map<int, int> upcomingCount;\n            int lookAhead = min(10, TOTAL - t - 1);\n            \n            for (int i = t + 1; i <= t + lookAhead && i < TOTAL; i++) {\n                upcomingCount[flavors[i]]++;\n            }\n            \n            for (auto [flavor, count] : upcomingCount) {\n                if (largestComp.count(flavor)) {\n                    // Bonus proportional to both component size and upcoming frequency\n                    score += largestComp[flavor] * count * 2;\n                    \n                    // Extra bonus if this flavor is dominant overall\n                    if (flavorFreq[flavor] >= 40) {\n                        score += largestComp[flavor] * 3;\n                    }\n                }\n            }\n        }\n        \n        return score;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(TOTAL);\n    vector<int> flavorFreq(4, 0);\n    \n    for (int i = 0; i < TOTAL; i++) {\n        cin >> flavors[i];\n        flavorFreq[flavors[i]]++;\n    }\n    \n    Board board;\n    \n    for (int t = 0; t < TOTAL; t++) {\n        int pos;\n        cin >> pos;\n        \n        board.place(pos, flavors[t]);\n        \n        if (t == TOTAL - 1) break;\n        \n        char dirs[] = {'F', 'B', 'L', 'R'};\n        char bestDir = 'F';\n        double bestScore = -1e9;\n        \n        // Try each direction\n        for (char dir : dirs) {\n            Board tempBoard = board;\n            tempBoard.tilt(dir);\n            \n            double score;\n            \n            if (t < 15) {\n                // Early game: focus on creating connections\n                score = tempBoard.countAdjacent() * 50.0;\n                auto [baseScore, largest] = tempBoard.calculateScore();\n                score += baseScore * 5;\n                \n                // Light penalty for too many components\n                int numComp = tempBoard.countComponents();\n                score -= numComp * 3;\n            } else if (t < 50) {\n                // Mid game: balance between consolidation and score\n                score = tempBoard.evaluate(t, flavors, flavorFreq);\n            } else {\n                // Late game: focus heavily on final score\n                auto [baseScore, largest] = tempBoard.calculateScore();\n                score = baseScore * 15;\n                \n                // Still penalize excessive fragmentation\n                int numComp = tempBoard.countComponents();\n                score -= numComp * 5;\n                \n                // Bonus for maintaining large components\n                for (auto [flavor, size] : largest) {\n                    if (size >= 20) score += size * 30;\n                }\n            }\n            \n            // Tie-breaking: slight preference for consolidating moves\n            if (score > bestScore || (score == bestScore && (dir == 'L' || dir == 'F'))) {\n                bestScore = score;\n                bestDir = dir;\n            }\n        }\n        \n        board.tilt(bestDir);\n        cout << bestDir << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass Graph {\n    int N;\n    vector<vector<int>> adj;\n    \npublic:\n    Graph(int n) : N(n), adj(n, vector<int>(n, 0)) {}\n    \n    void setEdge(int i, int j, int val) {\n        adj[i][j] = adj[j][i] = val;\n    }\n    \n    string toString() const {\n        string s;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void fromString(const string& s) {\n        int idx = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1' ? 1 : 0);\n            }\n        }\n    }\n    \n    vector<double> getComprehensiveInvariants() const {\n        vector<double> inv;\n        \n        // 1. Basic edge count\n        int edges = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                edges += adj[i][j];\n            }\n        }\n        inv.push_back(edges);\n        \n        // 2. Degree sequence (sorted)\n        vector<int> degrees(N, 0);\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        \n        // Add full degree sequence for small N\n        for(int i = 0; i < N; i++) {\n            inv.push_back(degrees[i]);\n        }\n        \n        // 3. Triangle count\n        int triangles = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(adj[i][j]) {\n                    for(int k = j + 1; k < N; k++) {\n                        triangles += adj[j][k] * adj[k][i];\n                    }\n                }\n            }\n        }\n        inv.push_back(triangles);\n        \n        // 4. 4-cycles (more robust to noise than 4-cliques)\n        int cycles4 = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                int common = 0;\n                for(int k = 0; k < N; k++) {\n                    if(k != i && k != j) {\n                        common += adj[i][k] * adj[j][k];\n                    }\n                }\n                cycles4 += common * (common - 1) / 2;\n            }\n        }\n        inv.push_back(cycles4);\n        \n        // 5. Degree pairs for edges\n        double deg_sum = 0, deg_prod = 0;\n        int edge_cnt = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(adj[i][j]) {\n                    deg_sum += degrees[i] + degrees[j];\n                    deg_prod += degrees[i] * degrees[j];\n                    edge_cnt++;\n                }\n            }\n        }\n        if(edge_cnt > 0) {\n            inv.push_back(deg_sum);\n            inv.push_back(deg_prod);\n        } else {\n            inv.push_back(0);\n            inv.push_back(0);\n        }\n        \n        // 6. Non-edge degree pairs (complement information)\n        double non_deg_sum = 0, non_deg_prod = 0;\n        int non_edge_cnt = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(!adj[i][j]) {\n                    non_deg_sum += degrees[i] + degrees[j];\n                    non_deg_prod += degrees[i] * degrees[j];\n                    non_edge_cnt++;\n                }\n            }\n        }\n        if(non_edge_cnt > 0) {\n            inv.push_back(non_deg_sum);\n            inv.push_back(non_deg_prod);\n        } else {\n            inv.push_back(0);\n            inv.push_back(0);\n        }\n        \n        // 7. Wedge count (paths of length 2)\n        int wedges = 0;\n        for(int i = 0; i < N; i++) {\n            int deg = 0;\n            for(int j = 0; j < N; j++) {\n                deg += adj[i][j];\n            }\n            wedges += deg * (deg - 1) / 2;\n        }\n        inv.push_back(wedges);\n        \n        // 8. Clustering-related metric\n        double local_clustering = 0;\n        for(int i = 0; i < N; i++) {\n            vector<int> neighbors;\n            for(int j = 0; j < N; j++) {\n                if(adj[i][j]) neighbors.push_back(j);\n            }\n            if(neighbors.size() >= 2) {\n                int edges_between = 0;\n                for(int a = 0; a < neighbors.size(); a++) {\n                    for(int b = a + 1; b < neighbors.size(); b++) {\n                        edges_between += adj[neighbors[a]][neighbors[b]];\n                    }\n                }\n                local_clustering += edges_between;\n            }\n        }\n        inv.push_back(local_clustering);\n        \n        // 9. K2,2 count (bipartite subgraphs)\n        int k22 = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i+1; j < N; j++) {\n                if(!adj[i][j]) {\n                    int common = 0;\n                    for(int k = 0; k < N; k++) {\n                        if(k != i && k != j && adj[i][k] && adj[j][k]) {\n                            common++;\n                        }\n                    }\n                    k22 += common * (common - 1) / 2;\n                }\n            }\n        }\n        inv.push_back(k22);\n        \n        return inv;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Very aggressive N selection for maximum score\n    int N;\n    if(M <= 6) {\n        N = 4;  // Minimum allowed\n    } else if(M <= 10) {\n        N = 5;\n    } else if(M <= 15) {\n        N = 6;\n    } else if(M <= 21) {\n        N = 7;\n    } else if(M <= 28) {\n        N = 8;\n    } else if(M <= 36) {\n        N = 9;\n    } else if(M <= 45) {\n        N = 10;\n    } else if(M <= 66) {\n        N = 12;\n    } else if(M <= 91) {\n        N = 14;\n    } else {\n        N = 16;\n    }\n    \n    // Adjust based on error rate\n    if(eps > 0.3) {\n        N = min(100, N + 2);\n    } else if(eps > 0.2) {\n        N = min(100, N + 1);\n    }\n    \n    vector<Graph> graphs;\n    int max_edges = N * (N - 1) / 2;\n    \n    // Generate graphs with maximally different edge counts\n    for(int idx = 0; idx < M; idx++) {\n        Graph g(N);\n        \n        // Distribute edge counts as evenly as possible\n        int target_edges = (idx * max_edges) / max(1, M - 1);\n        \n        // For small N, we can enumerate specific graph structures\n        set<pair<int,int>> edges;\n        \n        if(N <= 6 && idx < 20) {\n            // Use predefined optimal structures for small graphs\n            if(idx == 0) {\n                // Empty graph\n            } else if(idx == 1) {\n                edges.insert({0, 1});\n            } else if(idx == 2) {\n                edges.insert({0, 1});\n                edges.insert({1, 2});\n            } else if(idx == 3) {\n                edges.insert({0, 1});\n                edges.insert({2, 3});\n            } else if(idx == 4) {\n                edges.insert({0, 1});\n                edges.insert({0, 2});\n                edges.insert({0, 3});\n            } else if(idx == 5) {\n                edges.insert({0, 1});\n                edges.insert({1, 2});\n                edges.insert({2, 0});\n            } else if(idx == 6) {\n                edges.insert({0, 1});\n                edges.insert({1, 2});\n                edges.insert({2, 3});\n                edges.insert({3, 0});\n            } else if(idx == 7 && N >= 5) {\n                for(int i = 1; i < 5; i++) {\n                    edges.insert({0, i});\n                }\n            } else {\n                // Fill with systematic pattern\n                mt19937 gen(idx * 999);\n                vector<pair<int,int>> all_edges;\n                for(int i = 0; i < N; i++) {\n                    for(int j = i + 1; j < N; j++) {\n                        all_edges.push_back({i, j});\n                    }\n                }\n                shuffle(all_edges.begin(), all_edges.end(), gen);\n                for(int e = 0; e < min(target_edges, (int)all_edges.size()); e++) {\n                    edges.insert(all_edges[e]);\n                }\n            }\n        } else {\n            // For larger N or higher indices, use systematic generation\n            mt19937 gen(idx * 31415 + 92653);\n            \n            // Create edges with a deterministic pattern\n            vector<pair<int,int>> all_edges;\n            for(int i = 0; i < N; i++) {\n                for(int j = i + 1; j < N; j++) {\n                    all_edges.push_back({i, j});\n                }\n            }\n            \n            // Use a deterministic but well-distributed selection\n            shuffle(all_edges.begin(), all_edges.end(), gen);\n            \n            for(int e = 0; e < min(target_edges, (int)all_edges.size()); e++) {\n                edges.insert(all_edges[e]);\n            }\n        }\n        \n        // Build the graph\n        for(auto [u, v] : edges) {\n            g.setEdge(u, v, 1);\n        }\n        \n        graphs.push_back(g);\n    }\n    \n    // Output graphs\n    cout << N << \"\\n\";\n    for(const auto& g : graphs) {\n        cout << g.toString() << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute invariants for all graphs\n    vector<vector<double>> invariants;\n    for(const auto& g : graphs) {\n        invariants.push_back(g.getComprehensiveInvariants());\n    }\n    \n    // Process queries\n    for(int q = 0; q < 100; q++) {\n        string h_str;\n        cin >> h_str;\n        \n        Graph h(N);\n        h.fromString(h_str);\n        auto h_inv = h.getComprehensiveInvariants();\n        \n        // Find best match with robust scoring\n        int best = 0;\n        double best_score = -1e18;\n        \n        for(int i = 0; i < M; i++) {\n            double score = 0;\n            \n            // Weighted matching based on invariant importance\n            for(size_t j = 0; j < min(h_inv.size(), invariants[i].size()); j++) {\n                double weight = 1.0;\n                \n                // Edge count is most important\n                if(j == 0) weight = 10.0;\n                // Degree sequence is important\n                else if(j >= 1 && j <= N) weight = 3.0;\n                // Triangles are robust\n                else if(j == N + 1) weight = 5.0;\n                // 4-cycles are robust\n                else if(j == N + 2) weight = 4.0;\n                \n                double diff = abs(h_inv[j] - invariants[i][j]);\n                double norm = max(1.0, abs(invariants[i][j]) + abs(h_inv[j]) + 1.0);\n                score -= weight * diff / norm;\n            }\n            \n            if(score > best_score) {\n                best_score = score;\n                best = i;\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<int> assignment;\nvector<int> best_global;\ndouble best_global_score = 1e18;\nmt19937 rng(42);\n\nconst int INF = 1000000000;\n\n// Fast Dijkstra\nvector<int> dijkstra(int s, const vector<bool>& usable, const vector<vector<pair<int, int>>>& graph) {\n    vector<int> dist(N, INF);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            if (!usable[eid]) continue;\n            int w = edges[eid].w;\n            \n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    return dist;\n}\n\n// Evaluate with caching\ndouble evaluateFrustration(const vector<int>& assign, \n                          const vector<vector<int>>& base_dist,\n                          const vector<int>& samples,\n                          const vector<vector<pair<int, int>>>& graph,\n                          bool quick = true) {\n    // Check constraints\n    vector<int> counts(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        counts[assign[i]]++;\n        if (counts[assign[i]] > K) return 1e18;\n    }\n    \n    vector<vector<int>> day_edges(D + 1);\n    for (int i = 0; i < M; i++) {\n        day_edges[assign[i]].push_back(i);\n    }\n    \n    double total = 0;\n    int pair_count = 0;\n    \n    for (int day = 1; day <= D; day++) {\n        vector<bool> usable(M, true);\n        for (int e : day_edges[day]) {\n            usable[e] = false;\n        }\n        \n        for (int idx = 0; idx < samples.size(); idx++) {\n            int s = samples[idx];\n            auto dist = dijkstra(s, usable, graph);\n            \n            // Sample targets\n            int step = quick ? max(5, N/20) : max(2, N/50);\n            for (int t = 0; t < N; t += step) {\n                if (s != t) {\n                    total += (double)(dist[t] - base_dist[idx][t]);\n                    pair_count++;\n                }\n            }\n        }\n    }\n    \n    return total / (pair_count * D);\n}\n\n// BFS-based clustering\nvector<int> bfsCluster(const vector<vector<pair<int, int>>>& graph) {\n    vector<int> result(M);\n    vector<bool> edge_used(M, false);\n    vector<int> day_counts(D + 1, 0);\n    \n    // Start from random vertices and assign edges in BFS order\n    vector<int> start_vertices;\n    for (int i = 0; i < D && i < N; i++) {\n        start_vertices.push_back((i * N) / D);\n    }\n    \n    int current_day = 1;\n    for (int start : start_vertices) {\n        queue<int> q;\n        q.push(start);\n        vector<bool> visited(N, false);\n        visited[start] = true;\n        \n        while (!q.empty() && day_counts[current_day] < K) {\n            int u = q.front();\n            q.pop();\n            \n            for (auto [v, eid] : graph[u]) {\n                if (!edge_used[eid] && day_counts[current_day] < K) {\n                    result[eid] = current_day;\n                    edge_used[eid] = true;\n                    day_counts[current_day]++;\n                }\n                \n                if (!visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        current_day = (current_day % D) + 1;\n    }\n    \n    // Assign remaining edges\n    for (int i = 0; i < M; i++) {\n        if (!edge_used[i]) {\n            for (int d = 1; d <= D; d++) {\n                if (day_counts[d] < K) {\n                    result[i] = d;\n                    day_counts[d]++;\n                    break;\n                }\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Local search with multiple move types\nvoid localSearch(vector<int>& assign, \n                const vector<vector<int>>& base_dist,\n                const vector<int>& samples,\n                const vector<vector<pair<int, int>>>& graph,\n                int time_limit) {\n    auto start = chrono::high_resolution_clock::now();\n    \n    double current_score = evaluateFrustration(assign, base_dist, samples, graph, true);\n    double best_score = current_score;\n    vector<int> best_assign = assign;\n    \n    vector<int> day_counts(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_counts[assign[i]]++;\n    }\n    \n    double T = current_score * 0.01;\n    uniform_real_distribution<double> prob(0, 1);\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(1, D);\n    \n    int no_improve = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > time_limit) break;\n        \n        int move_type = rng() % 100;\n        vector<int> old_assign = assign;\n        vector<int> old_counts = day_counts;\n        bool valid = true;\n        \n        if (move_type < 40) {\n            // Swap two edges\n            int e1 = edge_dist(rng);\n            int e2 = edge_dist(rng);\n            if (e1 != e2 && assign[e1] != assign[e2]) {\n                swap(assign[e1], assign[e2]);\n            } else {\n                continue;\n            }\n        } else if (move_type < 70) {\n            // Move edge to different day\n            int e = edge_dist(rng);\n            int old_day = assign[e];\n            int new_day = day_dist(rng);\n            \n            if (old_day != new_day && day_counts[new_day] < K) {\n                assign[e] = new_day;\n                day_counts[old_day]--;\n                day_counts[new_day]++;\n            } else {\n                continue;\n            }\n        } else if (move_type < 90) {\n            // Move multiple connected edges\n            int e = edge_dist(rng);\n            int v = edges[e].u;\n            int old_day = assign[e];\n            int new_day = day_dist(rng);\n            \n            if (old_day == new_day) continue;\n            \n            vector<int> to_move;\n            for (auto [u, eid] : graph[v]) {\n                if (assign[eid] == old_day) {\n                    to_move.push_back(eid);\n                }\n            }\n            \n            if (day_counts[new_day] + to_move.size() <= K && \n                day_counts[old_day] >= to_move.size()) {\n                for (int eid : to_move) {\n                    assign[eid] = new_day;\n                }\n                day_counts[old_day] -= to_move.size();\n                day_counts[new_day] += to_move.size();\n            } else {\n                continue;\n            }\n        } else {\n            // Balance days - move from max to min\n            int max_day = 1, min_day = 1;\n            for (int d = 1; d <= D; d++) {\n                if (day_counts[d] > day_counts[max_day]) max_day = d;\n                if (day_counts[d] < day_counts[min_day]) min_day = d;\n            }\n            \n            if (max_day != min_day && day_counts[min_day] < K) {\n                for (int i = 0; i < M; i++) {\n                    if (assign[i] == max_day) {\n                        assign[i] = min_day;\n                        day_counts[max_day]--;\n                        day_counts[min_day]++;\n                        break;\n                    }\n                }\n            } else {\n                continue;\n            }\n        }\n        \n        // Verify constraints\n        for (int d = 1; d <= D; d++) {\n            if (day_counts[d] > K) {\n                valid = false;\n                break;\n            }\n        }\n        \n        if (!valid) {\n            assign = old_assign;\n            day_counts = old_counts;\n            continue;\n        }\n        \n        double new_score = evaluateFrustration(assign, base_dist, samples, graph, true);\n        double delta = new_score - current_score;\n        \n        if (delta < 0 || prob(rng) < exp(-delta / T)) {\n            current_score = new_score;\n            no_improve = 0;\n            \n            if (current_score < best_score) {\n                best_score = current_score;\n                best_assign = assign;\n                \n                if (best_score < best_global_score) {\n                    best_global_score = best_score;\n                    best_global = best_assign;\n                }\n            }\n        } else {\n            assign = old_assign;\n            day_counts = old_counts;\n            no_improve++;\n        }\n        \n        // Adaptive temperature\n        T *= 0.995;\n        \n        // Restart if stuck\n        if (no_improve > 500) {\n            T = best_score * 0.005;\n            no_improve = 0;\n        }\n    }\n    \n    assign = best_assign;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].id = i;\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build graph\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    // Sample vertices - use more samples\n    int sample_size = min(35, N);\n    vector<int> samples;\n    for (int i = 0; i < sample_size; i++) {\n        samples.push_back((i * N) / sample_size);\n    }\n    \n    // Compute base distances\n    vector<bool> all_usable(M, true);\n    vector<vector<int>> base_dist(sample_size);\n    for (int i = 0; i < sample_size; i++) {\n        base_dist[i] = dijkstra(samples[i], all_usable, graph);\n    }\n    \n    // Multi-start with different strategies\n    int strategies = 3;\n    int time_per_strategy = 4800 / strategies;\n    \n    for (int strategy = 0; strategy < strategies; strategy++) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        if (elapsed > 4800) break;\n        \n        // Different initial assignments\n        if (strategy == 0) {\n            // BFS clustering\n            assignment = bfsCluster(graph);\n        } else if (strategy == 1) {\n            // Random assignment\n            assignment.resize(M);\n            vector<int> counts(D + 1, 0);\n            for (int i = 0; i < M; i++) {\n                int d = (rng() % D) + 1;\n                while (counts[d] >= K) {\n                    d = (rng() % D) + 1;\n                }\n                assignment[i] = d;\n                counts[d]++;\n            }\n        } else {\n            // Weight-based clustering\n            assignment.resize(M);\n            vector<pair<int, int>> weight_order;\n            for (int i = 0; i < M; i++) {\n                weight_order.push_back({edges[i].w, i});\n            }\n            sort(weight_order.begin(), weight_order.end());\n            \n            vector<int> counts(D + 1, 0);\n            for (auto [w, eid] : weight_order) {\n                int best_day = 1;\n                for (int d = 1; d <= D; d++) {\n                    if (counts[d] < counts[best_day]) best_day = d;\n                }\n                assignment[eid] = best_day;\n                counts[best_day]++;\n            }\n        }\n        \n        localSearch(assignment, base_dist, samples, graph, \n                   min(time_per_strategy, 4800 - (int)elapsed));\n    }\n    \n    // Use best found solution\n    assignment = best_global;\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nvoid read_input() {\n    cin >> D;\n    f1.resize(D); r1.resize(D);\n    f2.resize(D); r2.resize(D);\n    \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\nvector<vector<vector<int>>> construct_object(vector<string>& f, vector<string>& r) {\n    vector<vector<vector<int>>> obj(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(f[z][x] == '1' && r[z][y] == '1') {\n                    obj[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    return obj;\n}\n\nstruct Block {\n    set<tuple<int,int,int>> cells;\n    \n    Block normalized() const {\n        if(cells.empty()) return *this;\n        \n        int min_x = INT_MAX, min_y = INT_MAX, min_z = INT_MAX;\n        for(auto [x,y,z] : cells) {\n            min_x = min(min_x, x);\n            min_y = min(min_y, y);\n            min_z = min(min_z, z);\n        }\n        \n        Block result;\n        for(auto [x,y,z] : cells) {\n            result.cells.insert({x - min_x, y - min_y, z - min_z});\n        }\n        return result;\n    }\n    \n    bool operator<(const Block& other) const {\n        return cells < other.cells;\n    }\n    \n    bool operator==(const Block& other) const {\n        return cells == other.cells;\n    }\n};\n\nset<Block> get_all_orientations(const Block& block) {\n    set<Block> result;\n    \n    auto apply = [](const Block& b, const vector<int>& perm, const vector<int>& sign) -> Block {\n        Block res;\n        for(auto [x,y,z] : b.cells) {\n            vector<int> coords = {x, y, z};\n            int nx = coords[abs(perm[0]) - 1] * sign[0];\n            int ny = coords[abs(perm[1]) - 1] * sign[1];\n            int nz = coords[abs(perm[2]) - 1] * sign[2];\n            res.cells.insert({nx, ny, nz});\n        }\n        return res.normalized();\n    };\n    \n    // Generate all 24 orientations (6 faces * 4 rotations each)\n    vector<vector<int>> perms = {{1,2,3}, {1,3,2}, {2,1,3}, {2,3,1}, {3,1,2}, {3,2,1}};\n    vector<vector<int>> signs = {{1,1,1}, {1,1,-1}, {1,-1,1}, {1,-1,-1}, \n                                  {-1,1,1}, {-1,1,-1}, {-1,-1,1}, {-1,-1,-1}};\n    \n    for(auto& perm : perms) {\n        for(auto& sign : signs) {\n            // Check if this is a valid rotation (determinant = 1)\n            int det = sign[0] * sign[1] * sign[2];\n            if(perm == vector<int>{1,2,3} || perm == vector<int>{2,3,1} || perm == vector<int>{3,1,2}) {\n                if(det == 1) result.insert(apply(block, perm, sign));\n            } else {\n                if(det == -1) result.insert(apply(block, perm, sign));\n            }\n        }\n    }\n    \n    return result;\n}\n\nBlock extract_block_bfs(vector<vector<vector<int>>>& obj,\n                       vector<vector<vector<bool>>>& used,\n                       int sx, int sy, int sz, int target_size) {\n    Block block;\n    queue<tuple<int,int,int>> q;\n    q.push({sx, sy, sz});\n    used[sx][sy][sz] = true;\n    block.cells.insert({sx, sy, sz});\n    \n    int dx[] = {1,-1,0,0,0,0};\n    int dy[] = {0,0,1,-1,0,0};\n    int dz[] = {0,0,0,0,1,-1};\n    \n    while(!q.empty() && block.cells.size() < target_size) {\n        auto [x, y, z] = q.front();\n        q.pop();\n        \n        vector<tuple<int,int,int>> candidates;\n        \n        for(int d = 0; d < 6; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            int nz = z + dz[d];\n            \n            if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n               obj[nx][ny][nz] == 1 && !used[nx][ny][nz]) {\n                candidates.push_back({nx, ny, nz});\n            }\n        }\n        \n        // Add candidates to maintain connectivity\n        for(auto [nx, ny, nz] : candidates) {\n            if(block.cells.size() < target_size) {\n                used[nx][ny][nz] = true;\n                block.cells.insert({nx, ny, nz});\n                q.push({nx, ny, nz});\n            }\n        }\n    }\n    \n    return block;\n}\n\nvoid create_and_output() {\n    auto obj1 = construct_object(f1, r1);\n    auto obj2 = construct_object(f2, r2);\n    \n    vector<int> b1(D * D * D, 0);\n    vector<int> b2(D * D * D, 0);\n    \n    vector<vector<vector<bool>>> used1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> used2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    // Collect all potential blocks from both objects\n    vector<pair<Block, int>> blocks1_list; // block, start_position\n    vector<pair<Block, int>> blocks2_list;\n    \n    // Target block sizes - prefer medium-sized blocks for better matching\n    vector<int> target_sizes = {8, 6, 4, 10, 12};\n    \n    for(int target : target_sizes) {\n        auto temp_used1 = used1;\n        auto temp_used2 = used2;\n        \n        // Extract blocks from obj1\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(obj1[x][y][z] == 1 && !temp_used1[x][y][z]) {\n                        Block block = extract_block_bfs(obj1, temp_used1, x, y, z, target);\n                        blocks1_list.push_back({block, x * D * D + y * D + z});\n                    }\n                }\n            }\n        }\n        \n        // Extract blocks from obj2\n        temp_used2 = used2;\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(obj2[x][y][z] == 1 && !temp_used2[x][y][z]) {\n                        Block block = extract_block_bfs(obj2, temp_used2, x, y, z, target);\n                        blocks2_list.push_back({block, x * D * D + y * D + z});\n                    }\n                }\n            }\n        }\n    }\n    \n    // Build a map of normalized blocks to their orientations\n    map<Block, set<int>> norm_to_indices1;\n    map<Block, set<int>> norm_to_indices2;\n    \n    for(int i = 0; i < blocks1_list.size(); i++) {\n        Block norm = blocks1_list[i].first.normalized();\n        norm_to_indices1[norm].insert(i);\n    }\n    \n    for(int i = 0; i < blocks2_list.size(); i++) {\n        Block norm = blocks2_list[i].first.normalized();\n        norm_to_indices2[norm].insert(i);\n    }\n    \n    // Greedy matching with rotation consideration\n    vector<bool> used_blocks1(blocks1_list.size(), false);\n    vector<bool> used_blocks2(blocks2_list.size(), false);\n    int block_id = 0;\n    \n    // First pass: exact matches at same position\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && obj2[x][y][z] == 1 && \n                   !used1[x][y][z] && !used2[x][y][z]) {\n                    // Create shared block\n                    block_id++;\n                    \n                    queue<tuple<int,int,int>> q;\n                    q.push({x, y, z});\n                    used1[x][y][z] = true;\n                    used2[x][y][z] = true;\n                    b1[x * D * D + y * D + z] = block_id;\n                    b2[x * D * D + y * D + z] = block_id;\n                    \n                    int count = 1;\n                    int dx[] = {1,-1,0,0,0,0};\n                    int dy[] = {0,0,1,-1,0,0};\n                    int dz[] = {0,0,0,0,1,-1};\n                    \n                    while(!q.empty() && count < 10) {\n                        auto [cx, cy, cz] = q.front();\n                        q.pop();\n                        \n                        for(int d = 0; d < 6; d++) {\n                            int nx = cx + dx[d];\n                            int ny = cy + dy[d];\n                            int nz = cz + dz[d];\n                            \n                            if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                               obj1[nx][ny][nz] == 1 && obj2[nx][ny][nz] == 1 &&\n                               !used1[nx][ny][nz] && !used2[nx][ny][nz] && count < 10) {\n                                used1[nx][ny][nz] = true;\n                                used2[nx][ny][nz] = true;\n                                b1[nx * D * D + ny * D + nz] = block_id;\n                                b2[nx * D * D + ny * D + nz] = block_id;\n                                q.push({nx, ny, nz});\n                                count++;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Second pass: match blocks with rotation\n    for(int i = 0; i < blocks1_list.size(); i++) {\n        if(used_blocks1[i]) continue;\n        \n        auto orientations = get_all_orientations(blocks1_list[i].first);\n        \n        for(int j = 0; j < blocks2_list.size(); j++) {\n            if(used_blocks2[j]) continue;\n            \n            Block norm2 = blocks2_list[j].first.normalized();\n            \n            if(orientations.count(norm2) > 0) {\n                // Check if blocks don't overlap with already used cells\n                bool can_place1 = true, can_place2 = true;\n                \n                for(auto [x,y,z] : blocks1_list[i].first.cells) {\n                    if(used1[x][y][z]) {\n                        can_place1 = false;\n                        break;\n                    }\n                }\n                \n                for(auto [x,y,z] : blocks2_list[j].first.cells) {\n                    if(used2[x][y][z]) {\n                        can_place2 = false;\n                        break;\n                    }\n                }\n                \n                if(can_place1 && can_place2) {\n                    block_id++;\n                    \n                    for(auto [x,y,z] : blocks1_list[i].first.cells) {\n                        b1[x * D * D + y * D + z] = block_id;\n                        used1[x][y][z] = true;\n                    }\n                    \n                    for(auto [x,y,z] : blocks2_list[j].first.cells) {\n                        b2[x * D * D + y * D + z] = block_id;\n                        used2[x][y][z] = true;\n                    }\n                    \n                    used_blocks1[i] = true;\n                    used_blocks2[j] = true;\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Fill remaining cells\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] == 1 && !used1[x][y][z]) {\n                    block_id++;\n                    Block block = extract_block_bfs(obj1, used1, x, y, z, 8);\n                    for(auto [cx,cy,cz] : block.cells) {\n                        b1[cx * D * D + cy * D + cz] = block_id;\n                    }\n                }\n                \n                if(obj2[x][y][z] == 1 && !used2[x][y][z]) {\n                    block_id++;\n                    Block block = extract_block_bfs(obj2, used2, x, y, z, 8);\n                    for(auto [cx,cy,cz] : block.cells) {\n                        b2[cx * D * D + cy * D + cz] = block_id;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Output\n    cout << block_id << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b1[i];\n    }\n    cout << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b2[i];\n    }\n    cout << endl;\n}\n\nint main() {\n    read_input();\n    create_and_output();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nclass Solution {\n    int N, M, K;\n    vector<pair<int, int>> vertices;\n    vector<Edge> edges;\n    vector<vector<pair<int, pair<int, long long>>>> adj;\n    vector<pair<int, int>> residents;\n    vector<vector<int>> resident_dist;\n    vector<vector<int>> covering_vertices; // For each resident, which vertices can cover it\n    \n    // Dijkstra from source\n    pair<vector<long long>, vector<int>> dijkstra(int source) {\n        vector<long long> dist(N, LLONG_MAX);\n        vector<int> parent_edge(N, -1);\n        priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n        \n        dist[source] = 0;\n        pq.push({0, source});\n        \n        while (!pq.empty()) {\n            auto [d, u] = pq.top();\n            pq.pop();\n            \n            if (d > dist[u]) continue;\n            \n            for (auto [v, info] : adj[u]) {\n                long long w = info.second;\n                if (dist[u] + w < dist[v]) {\n                    dist[v] = dist[u] + w;\n                    parent_edge[v] = info.first;\n                    pq.push({dist[v], v});\n                }\n            }\n        }\n        \n        return {dist, parent_edge};\n    }\n    \n    // Get minimum spanning tree of a set of vertices\n    pair<long long, vector<int>> getMSTCost(const set<int>& terminals) {\n        if (terminals.empty() || (terminals.size() == 1 && *terminals.begin() == 0)) {\n            return {0, vector<int>(M, 0)};\n        }\n        \n        // Use MST heuristic for Steiner tree\n        // First, compute shortest paths between all terminal pairs\n        map<pair<int,int>, long long> terminal_dist;\n        map<pair<int,int>, vector<int>> terminal_paths;\n        \n        for (int t : terminals) {\n            auto [dist, parent_edge] = dijkstra(t);\n            for (int s : terminals) {\n                if (s != t && dist[s] != LLONG_MAX) {\n                    terminal_dist[{min(t,s), max(t,s)}] = dist[s];\n                    // Build path\n                    vector<int> path;\n                    int curr = s;\n                    while (parent_edge[curr] != -1) {\n                        path.push_back(parent_edge[curr]);\n                        int e = parent_edge[curr];\n                        curr = (edges[e].u == curr) ? edges[e].v : edges[e].u;\n                    }\n                    terminal_paths[{min(t,s), max(t,s)}] = path;\n                }\n            }\n        }\n        \n        // Build MST of terminals\n        vector<int> edge_used(M, 0);\n        set<int> connected;\n        connected.insert(0);\n        \n        long long total_cost = 0;\n        \n        while (connected.size() < terminals.size()) {\n            long long min_cost = LLONG_MAX;\n            pair<int,int> best_pair;\n            \n            for (int u : connected) {\n                for (int v : terminals) {\n                    if (connected.find(v) == connected.end()) {\n                        auto key = make_pair(min(u,v), max(u,v));\n                        if (terminal_dist.count(key) && terminal_dist[key] < min_cost) {\n                            min_cost = terminal_dist[key];\n                            best_pair = key;\n                        }\n                    }\n                }\n            }\n            \n            if (min_cost == LLONG_MAX) break;\n            \n            // Add edges from path\n            for (int e : terminal_paths[best_pair]) {\n                edge_used[e] = 1;\n                total_cost += edges[e].w;\n            }\n            connected.insert(best_pair.first);\n            connected.insert(best_pair.second);\n        }\n        \n        // Remove redundant edges\n        for (int i = 0; i < M; i++) {\n            if (edge_used[i]) {\n                edge_used[i] = 0;\n                // Check if still connected\n                set<int> reachable;\n                function<void(int)> dfs = [&](int u) {\n                    reachable.insert(u);\n                    for (auto [v, info] : adj[u]) {\n                        if (edge_used[info.first] && reachable.find(v) == reachable.end()) {\n                            dfs(v);\n                        }\n                    }\n                };\n                dfs(0);\n                \n                bool all_connected = true;\n                for (int t : terminals) {\n                    if (reachable.find(t) == reachable.end()) {\n                        all_connected = false;\n                        break;\n                    }\n                }\n                \n                if (!all_connected) {\n                    edge_used[i] = 1;\n                } else {\n                    total_cost -= edges[i].w;\n                }\n            }\n        }\n        \n        return {total_cost, edge_used};\n    }\n    \n    long long computeCost(const vector<int>& powers, const vector<int>& edge_used) {\n        long long cost = 0;\n        for (int i = 0; i < N; i++) {\n            cost += (long long)powers[i] * powers[i];\n        }\n        for (int i = 0; i < M; i++) {\n            if (edge_used[i]) cost += edges[i].w;\n        }\n        return cost;\n    }\n    \n    bool allResidentsCovered(const set<int>& active, const vector<int>& powers) {\n        for (int r = 0; r < K; r++) {\n            bool covered = false;\n            for (int v : active) {\n                if (resident_dist[r][v] <= powers[v]) {\n                    covered = true;\n                    break;\n                }\n            }\n            if (!covered) return false;\n        }\n        return true;\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> M >> K;\n        \n        vertices.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> vertices[i].first >> vertices[i].second;\n        }\n        \n        edges.resize(M);\n        adj.resize(N);\n        \n        for (int i = 0; i < M; i++) {\n            cin >> edges[i].u >> edges[i].v >> edges[i].w;\n            edges[i].u--; edges[i].v--;\n            edges[i].id = i;\n            adj[edges[i].u].push_back({edges[i].v, {i, edges[i].w}});\n            adj[edges[i].v].push_back({edges[i].u, {i, edges[i].w}});\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].first >> residents[i].second;\n        }\n        \n        // Precompute distances\n        resident_dist.resize(K, vector<int>(N));\n        covering_vertices.resize(K);\n        \n        for (int r = 0; r < K; r++) {\n            for (int v = 0; v < N; v++) {\n                long long dx = residents[r].first - vertices[v].first;\n                long long dy = residents[r].second - vertices[v].second;\n                resident_dist[r][v] = (int)ceil(sqrt(dx * dx + dy * dy));\n                if (resident_dist[r][v] <= 5000) {\n                    covering_vertices[r].push_back(v);\n                }\n            }\n        }\n        \n        // Initial greedy solution\n        set<int> active_vertices;\n        active_vertices.insert(0);\n        vector<int> vertex_power(N, 0);\n        vector<bool> covered(K, false);\n        \n        auto [dist_from_0, _] = dijkstra(0);\n        \n        // Greedy set cover\n        while (count(covered.begin(), covered.end(), false) > 0) {\n            double best_efficiency = 1e18;\n            int best_v = -1;\n            int best_power = 0;\n            \n            for (int v = 0; v < N; v++) {\n                if (dist_from_0[v] == LLONG_MAX) continue;\n                \n                int new_covered = 0;\n                int req_power = vertex_power[v];\n                \n                for (int r = 0; r < K; r++) {\n                    if (!covered[r] && resident_dist[r][v] <= 5000) {\n                        new_covered++;\n                        req_power = max(req_power, resident_dist[r][v]);\n                    }\n                }\n                \n                if (new_covered > 0 && req_power <= 5000) {\n                    set<int> temp_active = active_vertices;\n                    temp_active.insert(v);\n                    auto [mst_cost, _] = getMSTCost(temp_active);\n                    \n                    long long power_increase = (long long)req_power * req_power - \n                                             (long long)vertex_power[v] * vertex_power[v];\n                    long long edge_increase = mst_cost;\n                    for (int a : active_vertices) {\n                        if (a != v) {\n                            auto [prev_cost, _] = getMSTCost({0, a});\n                            edge_increase -= prev_cost;\n                        }\n                    }\n                    edge_increase = max(0LL, edge_increase);\n                    \n                    double efficiency = (power_increase + edge_increase) / (double)new_covered;\n                    \n                    if (efficiency < best_efficiency) {\n                        best_efficiency = efficiency;\n                        best_v = v;\n                        best_power = req_power;\n                    }\n                }\n            }\n            \n            if (best_v == -1) break;\n            \n            active_vertices.insert(best_v);\n            vertex_power[best_v] = best_power;\n            \n            for (int r = 0; r < K; r++) {\n                if (resident_dist[r][best_v] <= best_power) {\n                    covered[r] = true;\n                }\n            }\n        }\n        \n        // Try to remove vertices\n        vector<int> vertices_to_check(active_vertices.begin(), active_vertices.end());\n        for (int v : vertices_to_check) {\n            if (v == 0) continue;\n            \n            set<int> temp_active = active_vertices;\n            temp_active.erase(v);\n            \n            // Check if all residents still covered\n            bool all_covered = true;\n            for (int r = 0; r < K; r++) {\n                bool r_covered = false;\n                for (int u : temp_active) {\n                    if (resident_dist[r][u] <= vertex_power[u]) {\n                        r_covered = true;\n                        break;\n                    }\n                }\n                if (!r_covered) {\n                    all_covered = false;\n                    break;\n                }\n            }\n            \n            if (all_covered) {\n                active_vertices = temp_active;\n                vertex_power[v] = 0;\n            }\n        }\n        \n        // Minimize powers using binary search\n        for (int v : active_vertices) {\n            if (vertex_power[v] == 0) continue;\n            \n            int left = 0, right = vertex_power[v];\n            int best_power = vertex_power[v];\n            \n            while (left < right) {\n                int mid = (left + right) / 2;\n                \n                // Check if this power works\n                vector<int> temp_power = vertex_power;\n                temp_power[v] = mid;\n                \n                if (allResidentsCovered(active_vertices, temp_power)) {\n                    best_power = mid;\n                    right = mid;\n                } else {\n                    left = mid + 1;\n                }\n            }\n            \n            vertex_power[v] = best_power;\n        }\n        \n        // Build final MST\n        auto [final_cost, edge_used] = getMSTCost(active_vertices);\n        \n        // Clear power for non-connected vertices\n        set<int> connected;\n        function<void(int)> dfs = [&](int u) {\n            connected.insert(u);\n            for (auto [v, info] : adj[u]) {\n                if (edge_used[info.first] && connected.find(v) == connected.end()) {\n                    dfs(v);\n                }\n            }\n        };\n        dfs(0);\n        \n        for (int v = 0; v < N; v++) {\n            if (connected.find(v) == connected.end()) {\n                vertex_power[v] = 0;\n            }\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            cout << vertex_power[i] << (i == N-1 ? \"\\n\" : \" \");\n        }\n        for (int i = 0; i < M; i++) {\n            cout << edge_used[i] << (i == M-1 ? \"\\n\" : \" \");\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nvector<vector<int>> pyramid(N);\nvector<tuple<int,int,int,int>> moves;\n\nvoid swapBalls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    moves.push_back({x1, y1, x2, y2});\n}\n\n// Count violations for a specific position\nint positionViolations(int x, int y) {\n    int violations = 0;\n    if (x < N - 1) {\n        if (pyramid[x][y] > pyramid[x + 1][y]) violations++;\n        if (pyramid[x][y] > pyramid[x + 1][y + 1]) violations++;\n    }\n    return violations;\n}\n\n// Count total violations\nint countViolations() {\n    int violations = 0;\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            violations += positionViolations(x, y);\n        }\n    }\n    return violations;\n}\n\n// Heapify from a position downward\nvoid heapifyDown(int x, int y) {\n    if (x >= N - 1) return;\n    \n    int leftChild = pyramid[x + 1][y];\n    int rightChild = pyramid[x + 1][y + 1];\n    \n    // Find minimum among parent and children\n    if (pyramid[x][y] > leftChild && leftChild <= rightChild) {\n        swapBalls(x, y, x + 1, y);\n        heapifyDown(x + 1, y);\n    } else if (pyramid[x][y] > rightChild) {\n        swapBalls(x, y, x + 1, y + 1);\n        heapifyDown(x + 1, y + 1);\n    }\n}\n\n// Try to bubble up small values\nvoid bubbleUp(int x, int y) {\n    if (x == 0) return;\n    \n    // Check possible parent positions\n    vector<pair<int,int>> parents;\n    if (y > 0) parents.push_back({x - 1, y - 1});\n    if (y < x) parents.push_back({x - 1, y});\n    \n    for (auto [px, py] : parents) {\n        if (px >= 0 && py >= 0 && py <= px) {\n            if (pyramid[x][y] < pyramid[px][py]) {\n                // Check if swap would not create new violations\n                int currentViolations = positionViolations(px, py);\n                swapBalls(x, y, px, py);\n                int newViolations = positionViolations(px, py);\n                \n                if (newViolations <= currentViolations) {\n                    bubbleUp(px, py);\n                    return;\n                } else {\n                    // Revert if it made things worse\n                    swapBalls(x, y, px, py);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x + 1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Phase 1: Initial heapify from bottom-up\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            heapifyDown(x, y);\n        }\n    }\n    \n    // Phase 2: Find small values in lower levels and bubble them up\n    vector<tuple<int, int, int>> valuePositions;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            valuePositions.push_back({pyramid[x][y], x, y});\n        }\n    }\n    sort(valuePositions.begin(), valuePositions.end());\n    \n    // Try to move smallest values upward\n    for (int i = 0; i < min(100, (int)valuePositions.size()); i++) {\n        auto [val, x, y] = valuePositions[i];\n        // Find current position of this value\n        bool found = false;\n        for (int cx = 0; cx < N && !found; cx++) {\n            for (int cy = 0; cy <= cx && !found; cy++) {\n                if (pyramid[cx][cy] == val) {\n                    bubbleUp(cx, cy);\n                    found = true;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Final cleanup - fix remaining violations\n    int maxCleanupIter = 1000;\n    for (int iter = 0; iter < maxCleanupIter && moves.size() < 9500; iter++) {\n        if (countViolations() == 0) break;\n        \n        bool improved = false;\n        for (int x = 0; x < N - 1; x++) {\n            for (int y = 0; y <= x; y++) {\n                if (pyramid[x][y] > pyramid[x + 1][y]) {\n                    swapBalls(x, y, x + 1, y);\n                    heapifyDown(x + 1, y);\n                    improved = true;\n                }\n                if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                    swapBalls(x, y, x + 1, y + 1);\n                    heapifyDown(x + 1, y + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Output\n    cout << moves.size() << endl;\n    for (auto [x1, y1, x2, y2] : moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {-1, 0, 1, 0};\nconst int dy[] = {0, 1, 0, -1};\n\nstruct Container {\n    int number;\n    int x, y;\n};\n\nclass Warehouse {\n    int D, N;\n    int entrance_x, entrance_y;\n    vector<vector<int>> grid; // -1: obstacle, -2: empty, >=0: container number\n    vector<Container> containers;\n    vector<pair<int,int>> obstacles;\n    \npublic:\n    Warehouse() {\n        cin >> D >> N;\n        entrance_x = 0;\n        entrance_y = (D - 1) / 2;\n        \n        grid.resize(D, vector<int>(D, -2));\n        \n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n            grid[x][y] = -1;\n            obstacles.push_back({x, y});\n        }\n    }\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < D && y >= 0 && y < D;\n    }\n    \n    bool isReachable(int tx, int ty) {\n        if (!isValid(tx, ty) || grid[tx][ty] == -1) return false;\n        if (tx == entrance_x && ty == entrance_y) return true;\n        \n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        q.push({entrance_x, entrance_y});\n        visited[entrance_x][entrance_y] = true;\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                if (!isValid(nx, ny) || visited[nx][ny]) continue;\n                if (grid[nx][ny] != -2 && !(nx == tx && ny == ty)) continue;\n                \n                if (nx == tx && ny == ty) return true;\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return false;\n    }\n    \n    int getDistance(int x, int y) {\n        if (!isReachable(x, y)) return INT_MAX;\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n        q.push({entrance_x, entrance_y});\n        dist[entrance_x][entrance_y] = 0;\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front();\n            q.pop();\n            \n            if (cx == x && cy == y) return dist[x][y];\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = cx + dx[dir];\n                int ny = cy + dy[dir];\n                \n                if (!isValid(nx, ny) || grid[nx][ny] != -2) continue;\n                if (dist[nx][ny] != INT_MAX) continue;\n                \n                dist[nx][ny] = dist[cx][cy] + 1;\n                q.push({nx, ny});\n            }\n        }\n        \n        return INT_MAX;\n    }\n    \n    pair<int,int> placeContainer(int container_num) {\n        // Find all reachable empty positions\n        vector<pair<int, pair<int,int>>> candidates;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == entrance_x && j == entrance_y) continue;\n                if (grid[i][j] != -2) continue;\n                \n                int dist = getDistance(i, j);\n                if (dist != INT_MAX) {\n                    candidates.push_back({dist, {i, j}});\n                }\n            }\n        }\n        \n        if (candidates.empty()) {\n            // Should not happen in valid test cases\n            return {0, 0};\n        }\n        \n        // Sort by distance\n        sort(candidates.begin(), candidates.end());\n        \n        // Place based on container number relative to total containers\n        int total_containers = D * D - 1 - N;\n        int idx = (container_num * candidates.size()) / total_containers;\n        idx = min(idx, (int)candidates.size() - 1);\n        \n        // Try to place at the calculated index, but also consider nearby positions\n        // to avoid blocking\n        int best_idx = idx;\n        int range = min(5, (int)candidates.size());\n        \n        for (int offset = 0; offset < range; offset++) {\n            for (int sign : {1, -1}) {\n                int test_idx = idx + sign * offset;\n                if (test_idx >= 0 && test_idx < candidates.size()) {\n                    auto [x, y] = candidates[test_idx].second;\n                    \n                    // Check if this placement would block fewer cells\n                    int blocked_count = 0;\n                    grid[x][y] = container_num; // Temporarily place\n                    \n                    for (int i = 0; i < D; i++) {\n                        for (int j = 0; j < D; j++) {\n                            if (grid[i][j] == -2 && !isReachable(i, j)) {\n                                blocked_count++;\n                            }\n                        }\n                    }\n                    \n                    grid[x][y] = -2; // Remove temporary placement\n                    \n                    if (blocked_count <= 2) { // Acceptable blocking\n                        best_idx = test_idx;\n                        goto found;\n                    }\n                }\n            }\n        }\n        \n        found:\n        auto [px, py] = candidates[best_idx].second;\n        grid[px][py] = container_num;\n        containers.push_back({container_num, px, py});\n        \n        return {px, py};\n    }\n    \n    vector<pair<int,int>> getRetrievalOrder() {\n        vector<pair<int,int>> result;\n        vector<bool> retrieved(containers.size(), false);\n        \n        while (result.size() < containers.size()) {\n            int best_idx = -1;\n            int best_number = INT_MAX;\n            \n            // Find the smallest numbered container that's accessible\n            for (int i = 0; i < containers.size(); i++) {\n                if (retrieved[i]) continue;\n                \n                if (isReachable(containers[i].x, containers[i].y)) {\n                    if (containers[i].number < best_number) {\n                        best_number = containers[i].number;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx == -1) {\n                // Should not happen, but fallback to any accessible container\n                for (int i = 0; i < containers.size(); i++) {\n                    if (retrieved[i]) continue;\n                    if (isReachable(containers[i].x, containers[i].y)) {\n                        best_idx = i;\n                        break;\n                    }\n                }\n            }\n            \n            retrieved[best_idx] = true;\n            grid[containers[best_idx].x][containers[best_idx].y] = -2;\n            result.push_back({containers[best_idx].x, containers[best_idx].y});\n        }\n        \n        return result;\n    }\n    \n    void run() {\n        int total_containers = D * D - 1 - N;\n        \n        // Place containers as they arrive\n        for (int i = 0; i < total_containers; i++) {\n            int container_num;\n            cin >> container_num;\n            \n            auto [x, y] = placeContainer(container_num);\n            cout << x << \" \" << y << endl;\n            cout.flush();\n        }\n        \n        // Determine retrieval order\n        auto retrieval_order = getRetrievalOrder();\n        for (auto [x, y] : retrieval_order) {\n            cout << x << \" \" << y << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Warehouse warehouse;\n    warehouse.run();\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\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    // Extract adjacency information\n    set<pair<int, int>> adjacencies;\n    \n    // Check internal adjacencies\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            // Check right neighbor\n            if (j + 1 < n && grid[i][j] != grid[i][j+1]) {\n                int c1 = min(grid[i][j], grid[i][j+1]);\n                int c2 = max(grid[i][j], grid[i][j+1]);\n                adjacencies.insert({c1, c2});\n            }\n            \n            // Check bottom neighbor\n            if (i + 1 < n && grid[i][j] != grid[i+1][j]) {\n                int c1 = min(grid[i][j], grid[i+1][j]);\n                int c2 = max(grid[i][j], grid[i+1][j]);\n                adjacencies.insert({c1, c2});\n            }\n        }\n    }\n    \n    // Check boundary adjacencies (with color 0)\n    set<int> boundaryWards;\n    for (int i = 0; i < n; i++) {\n        boundaryWards.insert(grid[0][i]);\n        boundaryWards.insert(grid[n-1][i]);\n        boundaryWards.insert(grid[i][0]);\n        boundaryWards.insert(grid[i][n-1]);\n    }\n    \n    for (int ward : boundaryWards) {\n        adjacencies.insert({0, ward});\n    }\n    \n    // Build adjacency list\n    vector<vector<int>> adj(m + 1);\n    for (auto [c1, c2] : adjacencies) {\n        adj[c1].push_back(c2);\n        adj[c2].push_back(c1);\n    }\n    \n    // Create a compact grid representation\n    vector<vector<int>> result(n, vector<int>(n, 0));\n    vector<bool> placed(m + 1, false);\n    placed[0] = true; // Color 0 is implicitly placed\n    \n    // Direction vectors\n    int dx[] = {0, 1, 0, -1};\n    int dy[] = {1, 0, -1, 0};\n    \n    // Start with boundary wards\n    queue<int> toPlace;\n    for (int ward : boundaryWards) {\n        toPlace.push(ward);\n        placed[ward] = true;\n    }\n    \n    // Place boundary wards near edges\n    int idx = 0;\n    for (int ward : boundaryWards) {\n        if (idx < n/4) {\n            result[1][2 + idx * 2] = ward;\n        } else if (idx < n/2) {\n            result[2 + (idx - n/4) * 2][n-2] = ward;\n        } else if (idx < 3*n/4) {\n            result[n-2][n-3 - (idx - n/2) * 2] = ward;\n        } else {\n            result[n-3 - (idx - 3*n/4) * 2][1] = ward;\n        }\n        idx++;\n        if (idx * 2 >= n) break;\n    }\n    \n    // BFS to place remaining wards based on adjacencies\n    while (!toPlace.empty()) {\n        int ward = toPlace.front();\n        toPlace.pop();\n        \n        for (int neighbor : adj[ward]) {\n            if (!placed[neighbor] && neighbor != 0) {\n                // Find a position adjacent to ward's position\n                bool found = false;\n                for (int i = 0; i < n && !found; i++) {\n                    for (int j = 0; j < n && !found; j++) {\n                        if (result[i][j] == ward) {\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 && result[ni][nj] == 0) {\n                                    result[ni][nj] = neighbor;\n                                    placed[neighbor] = true;\n                                    toPlace.push(neighbor);\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Place any remaining wards\n    for (int ward = 1; ward <= m; ward++) {\n        if (!placed[ward]) {\n            // Find empty position, preferably near its neighbors\n            bool found = false;\n            for (int i = 1; i < n-1 && !found; i++) {\n                for (int j = 1; j < n-1 && !found; j++) {\n                    if (result[i][j] == 0) {\n                        result[i][j] = ward;\n                        placed[ward] = true;\n                        found = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Ensure all required adjacencies exist by expanding regions if needed\n    for (auto [c1, c2] : adjacencies) {\n        if (c1 == 0) continue; // Boundary adjacencies handled by placement\n        \n        // Check if adjacency exists\n        bool adjacent = false;\n        for (int i = 0; i < n && !adjacent; i++) {\n            for (int j = 0; j < n && !adjacent; j++) {\n                if (result[i][j] == c1) {\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 && result[ni][nj] == c2) {\n                            adjacent = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // If not adjacent, try to make them adjacent\n        if (!adjacent) {\n            // Find positions of c1 and c2 and try to grow one toward the other\n            vector<pair<int,int>> pos1, pos2;\n            for (int i = 0; i < n; i++) {\n                for (int j = 0; j < n; j++) {\n                    if (result[i][j] == c1) pos1.push_back({i, j});\n                    if (result[i][j] == c2) pos2.push_back({i, j});\n                }\n            }\n            \n            if (!pos1.empty() && !pos2.empty()) {\n                // Try to extend c1 toward c2\n                int minDist = n * n;\n                int bestX = -1, bestY = -1;\n                for (auto [x1, y1] : pos1) {\n                    for (int d = 0; d < 4; d++) {\n                        int nx = x1 + dx[d];\n                        int ny = y1 + dy[d];\n                        if (nx >= 0 && nx < n && ny >= 0 && ny < n && result[nx][ny] == 0) {\n                            for (auto [x2, y2] : pos2) {\n                                int dist = abs(nx - x2) + abs(ny - y2);\n                                if (dist < minDist) {\n                                    minDist = dist;\n                                    bestX = nx;\n                                    bestY = ny;\n                                }\n                            }\n                        }\n                    }\n                }\n                if (bestX != -1) {\n                    result[bestX][bestY] = c1;\n                }\n            }\n        }\n    }\n    \n    // Output the result\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<double> weight_estimate;\nvector<double> weight_lower, weight_upper;\nvector<vector<int>> comparison_matrix; // -1: i<j, 0: unknown, 1: i>j\n\nchar query(vector<int> left, vector<int> right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid update_bounds_from_comparison(const vector<int>& left, const vector<int>& right, char result) {\n    double left_min = 0, left_max = 0;\n    double right_min = 0, right_max = 0;\n    \n    for (int i : left) {\n        left_min += weight_lower[i];\n        left_max += weight_upper[i];\n    }\n    for (int i : right) {\n        right_min += weight_lower[i];\n        right_max += weight_upper[i];\n    }\n    \n    if (result == '<') {\n        // left_max < right_min ideally\n        if (left_max >= right_min) {\n            double ratio = right_min / left_max;\n            for (int i : left) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : right) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else if (result == '>') {\n        // right_max < left_min ideally\n        if (right_max >= left_min) {\n            double ratio = left_min / right_max;\n            for (int i : right) {\n                weight_upper[i] = min(weight_upper[i], weight_upper[i] * ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n            for (int i : left) {\n                weight_lower[i] = max(weight_lower[i], weight_lower[i] / ratio);\n                weight_estimate[i] = (weight_lower[i] + weight_upper[i]) / 2;\n            }\n        }\n    } else { // '='\n        // Weights should be equal\n        double avg = (left_min + left_max + right_min + right_max) / 4;\n        double per_item_left = avg / left.size();\n        double per_item_right = avg / right.size();\n        \n        for (int i : left) {\n            weight_estimate[i] = per_item_left;\n            weight_lower[i] = per_item_left * 0.8;\n            weight_upper[i] = per_item_left * 1.2;\n        }\n        for (int i : right) {\n            weight_estimate[i] = per_item_right;\n            weight_lower[i] = per_item_right * 0.8;\n            weight_upper[i] = per_item_right * 1.2;\n        }\n    }\n}\n\ndouble calculate_variance(const vector<vector<int>>& groups) {\n    vector<double> group_sums(D, 0);\n    for (int g = 0; g < D; g++) {\n        for (int item : groups[g]) {\n            group_sums[g] += weight_estimate[item];\n        }\n    }\n    \n    double mean = 0;\n    for (double s : group_sums) mean += s;\n    mean /= D;\n    \n    double variance = 0;\n    for (double s : group_sums) {\n        variance += (s - mean) * (s - mean);\n    }\n    return variance / D;\n}\n\nvoid local_search(vector<int>& assignment) {\n    vector<double> group_sums(D, 0);\n    vector<vector<int>> groups(D);\n    \n    for (int i = 0; i < N; i++) {\n        groups[assignment[i]].push_back(i);\n        group_sums[assignment[i]] += weight_estimate[i];\n    }\n    \n    bool improved = true;\n    int iterations = 0;\n    while (improved && iterations < 100) {\n        improved = false;\n        iterations++;\n        \n        for (int g1 = 0; g1 < D; g1++) {\n            for (int g2 = g1 + 1; g2 < D; g2++) {\n                // Try swapping items between groups\n                for (int i : groups[g1]) {\n                    for (int j : groups[g2]) {\n                        double curr_diff = abs(group_sums[g1] - group_sums[g2]);\n                        double new_sum_g1 = group_sums[g1] - weight_estimate[i] + weight_estimate[j];\n                        double new_sum_g2 = group_sums[g2] - weight_estimate[j] + weight_estimate[i];\n                        double new_diff = abs(new_sum_g1 - new_sum_g2);\n                        \n                        if (new_diff < curr_diff) {\n                            // Perform swap\n                            assignment[i] = g2;\n                            assignment[j] = g1;\n                            group_sums[g1] = new_sum_g1;\n                            group_sums[g2] = new_sum_g2;\n                            \n                            // Update groups\n                            groups[g1].erase(find(groups[g1].begin(), groups[g1].end(), i));\n                            groups[g1].push_back(j);\n                            groups[g2].erase(find(groups[g2].begin(), groups[g2].end(), j));\n                            groups[g2].push_back(i);\n                            \n                            improved = true;\n                            break;\n                        }\n                    }\n                    if (improved) break;\n                }\n                if (improved) break;\n            }\n            if (improved) break;\n        }\n    }\n}\n\nvoid solve() {\n    cin >> N >> D >> Q;\n    \n    weight_estimate.resize(N, 1000.0);\n    weight_lower.resize(N, 100.0);\n    weight_upper.resize(N, 10000.0);\n    comparison_matrix.resize(N, vector<int>(N, 0));\n    \n    int queries_used = 0;\n    \n    // Phase 1: Strategic individual comparisons\n    vector<pair<double, pair<int, int>>> uncertain_pairs;\n    \n    // First, do some initial random sampling to get rough estimates\n    for (int round = 0; round < 3 && queries_used < Q / 3; round++) {\n        for (int i = 0; i < N && queries_used < Q / 3; i++) {\n            int j = (i + 1 + round * 7) % N;\n            if (i != j && comparison_matrix[i][j] == 0) {\n                char result = query({i}, {j});\n                queries_used++;\n                \n                if (result == '<') {\n                    comparison_matrix[i][j] = -1;\n                    comparison_matrix[j][i] = 1;\n                    weight_estimate[i] *= 0.85;\n                    weight_estimate[j] *= 1.15;\n                } else if (result == '>') {\n                    comparison_matrix[i][j] = 1;\n                    comparison_matrix[j][i] = -1;\n                    weight_estimate[i] *= 1.15;\n                    weight_estimate[j] *= 0.85;\n                } else {\n                    weight_estimate[i] = weight_estimate[j] = (weight_estimate[i] + weight_estimate[j]) / 2;\n                }\n                \n                update_bounds_from_comparison({i}, {j}, result);\n            }\n        }\n    }\n    \n    // Phase 2: Group comparisons for refinement\n    while (queries_used < Q * 2 / 3) {\n        vector<pair<double, int>> sorted_items;\n        for (int i = 0; i < N; i++) {\n            sorted_items.push_back({weight_estimate[i], i});\n        }\n        sort(sorted_items.begin(), sorted_items.end());\n        \n        // Compare different percentiles\n        int size = max(2, N / 10);\n        vector<int> light, heavy, mid_low, mid_high;\n        \n        for (int i = 0; i < size && i < N/2; i++) {\n            light.push_back(sorted_items[i].second);\n            heavy.push_back(sorted_items[N - 1 - i].second);\n        }\n        \n        int mid = N / 2;\n        for (int i = max(0, mid - size/2); i < mid && i < N; i++) {\n            mid_low.push_back(sorted_items[i].second);\n        }\n        for (int i = mid; i < min(N, mid + size/2); i++) {\n            mid_high.push_back(sorted_items[i].second);\n        }\n        \n        if (!light.empty() && !heavy.empty()) {\n            char result = query(light, heavy);\n            queries_used++;\n            update_bounds_from_comparison(light, heavy, result);\n        }\n        \n        if (queries_used < Q * 2 / 3 && !mid_low.empty() && !mid_high.empty()) {\n            char result = query(mid_low, mid_high);\n            queries_used++;\n            update_bounds_from_comparison(mid_low, mid_high, result);\n        }\n    }\n    \n    // Initial partitioning\n    vector<pair<double, int>> final_sorted;\n    for (int i = 0; i < N; i++) {\n        final_sorted.push_back({weight_estimate[i], i});\n    }\n    sort(final_sorted.begin(), final_sorted.end(), greater<pair<double, int>>());\n    \n    vector<double> group_sums(D, 0);\n    vector<int> assignment(N);\n    \n    // Greedy assignment\n    for (auto [weight, item] : final_sorted) {\n        int min_group = 0;\n        for (int g = 1; g < D; g++) {\n            if (group_sums[g] < group_sums[min_group]) {\n                min_group = g;\n            }\n        }\n        assignment[item] = min_group;\n        group_sums[min_group] += weight;\n    }\n    \n    // Local search optimization\n    local_search(assignment);\n    \n    // Phase 3: Use remaining queries to verify and refine partition\n    vector<vector<int>> final_groups(D);\n    for (int i = 0; i < N; i++) {\n        final_groups[assignment[i]].push_back(i);\n    }\n    \n    while (queries_used < Q && D > 1) {\n        // Compare pairs of groups to verify balance\n        for (int g1 = 0; g1 < D && queries_used < Q; g1++) {\n            for (int g2 = g1 + 1; g2 < D && queries_used < Q; g2++) {\n                if (!final_groups[g1].empty() && !final_groups[g2].empty()) {\n                    // Sample from each group\n                    int sample_size = min(5, min((int)final_groups[g1].size(), (int)final_groups[g2].size()));\n                    vector<int> sample1, sample2;\n                    \n                    for (int i = 0; i < sample_size; i++) {\n                        sample1.push_back(final_groups[g1][i % final_groups[g1].size()]);\n                        sample2.push_back(final_groups[g2][i % final_groups[g2].size()]);\n                    }\n                    \n                    char result = query(sample1, sample2);\n                    queries_used++;\n                    update_bounds_from_comparison(sample1, sample2, result);\n                }\n            }\n        }\n    }\n    \n    // Final local search with updated estimates\n    if (queries_used >= Q * 0.9) {\n        local_search(assignment);\n    }\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}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    solve();\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        int stack_size = n / m;\n        for (int j = 0; j < stack_size; j++) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    for (int target = 1; target <= n; target++) {\n        // Find current position of target box\n        int target_stack = -1;\n        int target_pos = -1;\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    target_stack = i;\n                    target_pos = j;\n                    break;\n                }\n            }\n            if (target_stack != -1) break;\n        }\n        \n        // If target is not at the top, move boxes above it\n        if (target_pos < (int)stacks[target_stack].size() - 1) {\n            // Collect boxes to be moved\n            vector<int> boxes_to_move;\n            for (int j = target_pos + 1; j < (int)stacks[target_stack].size(); j++) {\n                boxes_to_move.push_back(stacks[target_stack][j]);\n            }\n            \n            // Analyze what we're moving\n            int min_box = *min_element(boxes_to_move.begin(), boxes_to_move.end());\n            double avg_box = accumulate(boxes_to_move.begin(), boxes_to_move.end(), 0.0) / boxes_to_move.size();\n            \n            // Count how many are \"soon\" (within next 30)\n            int soon_count = 0;\n            for (int box : boxes_to_move) {\n                if (box <= target + 30) soon_count++;\n            }\n            \n            // Find best destination\n            int best_dest = -1;\n            double best_score = -1e9;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == target_stack) continue;\n                \n                double score = 0;\n                int dest_stack_size = stacks[i].size();\n                \n                if (stacks[i].empty()) {\n                    // Empty stack is excellent\n                    score = 100000;\n                    \n                    // Extra bonus if moving soon-needed boxes to empty\n                    if (min_box <= target + 20) {\n                        score += 50000;\n                    }\n                    \n                    // Prefer empty stacks for smaller groups\n                    score += 10000.0 / (boxes_to_move.size() + 1);\n                } else {\n                    int top_box = stacks[i].back();\n                    \n                    // Base score: prefer smaller stacks\n                    score = 10000.0 / (dest_stack_size + 1);\n                    \n                    // Strong preference for stacks where top box is far future\n                    if (top_box > target + 100) {\n                        score += 20000;\n                    } else if (top_box > target + 50) {\n                        score += 10000;\n                    } else if (top_box > target + 30) {\n                        score += 5000;\n                    }\n                    \n                    // Penalty if we're putting soon boxes on top of other soon boxes\n                    if (min_box <= target + 30 && top_box <= target + 50) {\n                        score -= 10000;\n                    }\n                    \n                    // Check if any box in destination will be blocked and needed soon\n                    int blocking_cost = 0;\n                    for (int box : stacks[i]) {\n                        if (box <= target + 20) {\n                            // This box will be needed soon and we're blocking it\n                            blocking_cost += (21 - (box - target)) * 500;\n                        }\n                    }\n                    score -= blocking_cost;\n                    \n                    // Bonus if the average box value matches well\n                    if (avg_box > target + 50 && top_box > target + 50) {\n                        score += 5000; // Both are \"far\" boxes\n                    }\n                    \n                    // Penalty for height difference (prefer balanced stacks)\n                    score -= abs(dest_stack_size - (int)stacks[target_stack].size()) * 100;\n                }\n                \n                // Consider future accessibility\n                // If we're moving many soon boxes, prefer destinations that won't block them much\n                if (soon_count > 0) {\n                    score -= soon_count * dest_stack_size * 50;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_dest = i;\n                }\n            }\n            \n            // Execute the move\n            operations.push_back({boxes_to_move[0], best_dest + 1});\n            \n            // Update stacks\n            stacks[target_stack].resize(target_pos + 1);\n            for (int box : boxes_to_move) {\n                stacks[best_dest].push_back(box);\n            }\n        }\n        \n        // Carry out the target\n        operations.push_back({target, 0});\n        stacks[target_stack].pop_back();\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nconst int MAX_LENGTH = 100000;\nconst int DIJ[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\nconst char DIR[4] = {'R', 'D', 'L', 'U'};\n\nbool canMove(int i, int j, int dir) {\n    int di = DIJ[dir][0], dj = DIJ[dir][1];\n    int i2 = i + di, j2 = j + dj;\n    \n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    \n    if (di == 0) {\n        return v[i][min(j, j2)] == '0';\n    } else {\n        return h[min(i, i2)][j] == '0';\n    }\n}\n\n// Simple BFS to find path\nstring findPath(int si, int sj, int ei, int ej, int maxLen) {\n    if (si == ei && sj == ej) return \"\";\n    \n    queue<tuple<int, int, string>> q;\n    set<pair<int, int>> visited;\n    q.push({si, sj, \"\"});\n    visited.insert({si, sj});\n    \n    while (!q.empty()) {\n        auto [ci, cj, path] = q.front();\n        q.pop();\n        \n        if ((int)path.size() > maxLen) continue;\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            \n            if (visited.count({ni, nj})) continue;\n            \n            string newPath = path + DIR[dir];\n            \n            if (ni == ei && nj == ej) {\n                return newPath;\n            }\n            \n            visited.insert({ni, nj});\n            q.push({ni, nj, newPath});\n        }\n    }\n    return \"\";\n}\n\nint main() {\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    d.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N - 1; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    string result;\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    \n    // Phase 1: Visit all squares using DFS\n    function<void(int, int)> dfs = [&](int i, int j) {\n        visited[i][j] = true;\n        \n        // Sort neighbors by dirt value\n        vector<tuple<int, int, int>> neighbors;\n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(i, j, dir)) continue;\n            int ni = i + DIJ[dir][0];\n            int nj = j + DIJ[dir][1];\n            if (!visited[ni][nj]) {\n                neighbors.push_back({d[ni][nj], dir, ni * N + nj});\n            }\n        }\n        \n        // Sort by dirt value (descending), then by position for stability\n        sort(neighbors.begin(), neighbors.end(), [](const auto& a, const auto& b) {\n            if (get<0>(a) != get<0>(b)) return get<0>(a) > get<0>(b);\n            return get<2>(a) < get<2>(b);\n        });\n        \n        for (auto [dirt, dir, pos] : neighbors) {\n            int ni = i + DIJ[dir][0];\n            int nj = j + DIJ[dir][1];\n            if (!visited[ni][nj]) {\n                result += DIR[dir];\n                dfs(ni, nj);\n                result += DIR[(dir + 2) % 4];\n            }\n        }\n    };\n    \n    dfs(0, 0);\n    \n    // Phase 2: Use remaining moves to revisit high-dirt squares\n    int remainingMoves = MAX_LENGTH - (int)result.size() - 200;\n    \n    if (remainingMoves > 100) {\n        // Collect high-dirt squares\n        vector<pair<int, pair<int, int>>> highDirtSquares;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == 0 && j == 0) continue;  // Skip origin\n                highDirtSquares.push_back({d[i][j], {i, j}});\n            }\n        }\n        sort(highDirtSquares.rbegin(), highDirtSquares.rend());\n        \n        // Add cycles to top dirt squares\n        int cycles = 0;\n        int maxCycles = min(20, remainingMoves / (4 * N));\n        \n        for (auto [dirt, pos] : highDirtSquares) {\n            if (cycles >= maxCycles) break;\n            auto [ti, tj] = pos;\n            \n            // Find path to target\n            string pathTo = findPath(0, 0, ti, tj, min(remainingMoves / 2, 2 * N));\n            if (pathTo.empty()) continue;\n            \n            // Find path back\n            string pathBack = findPath(ti, tj, 0, 0, min(remainingMoves / 2, 2 * N));\n            if (pathBack.empty()) continue;\n            \n            int cycleLen = (int)pathTo.size() + (int)pathBack.size();\n            if (cycleLen > remainingMoves) continue;\n            \n            // Add this cycle\n            result += pathTo + pathBack;\n            remainingMoves -= cycleLen;\n            cycles++;\n            \n            // Add multiple cycles for very high dirt squares\n            if (dirt > 300) {\n                int extraCycles = min(2, remainingMoves / cycleLen);\n                for (int c = 0; c < extraCycles; c++) {\n                    result += pathTo + pathBack;\n                    remainingMoves -= cycleLen;\n                    cycles++;\n                }\n            }\n            \n            // Stop if we're running low on moves\n            if (remainingMoves < 100) break;\n        }\n        \n        // Fill remaining moves with small cycles to nearby high-dirt areas\n        if (remainingMoves > 50) {\n            // Find adjacent high-dirt square\n            int maxDirt = 0;\n            int bestDir = -1;\n            for (int dir = 0; dir < 4; dir++) {\n                if (!canMove(0, 0, dir)) continue;\n                int ni = DIJ[dir][0];\n                int nj = DIJ[dir][1];\n                if (d[ni][nj] > maxDirt) {\n                    maxDirt = d[ni][nj];\n                    bestDir = dir;\n                }\n            }\n            \n            // Add small back-and-forth cycles\n            if (bestDir >= 0) {\n                int smallCycles = remainingMoves / 2;\n                for (int c = 0; c < smallCycles && c < 30; c++) {\n                    result += DIR[bestDir];\n                    result += DIR[(bestDir + 2) % 4];\n                }\n            }\n        }\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int i, j;\n};\n\nint manhattan(Position a, Position b) {\n    return abs(a.i - b.i) + abs(a.j - b.j) + 1;\n}\n\nclass SuperstringOptimizer {\nprivate:\n    vector<string> words;\n    vector<vector<int>> overlap;\n    int n;\n    \n    int computeOverlap(const string& a, const string& b) {\n        int maxLen = min(a.length(), b.length());\n        for (int len = maxLen; len >= 1; len--) {\n            if (a.substr(a.length() - len) == b.substr(0, len)) {\n                return len;\n            }\n        }\n        return 0;\n    }\n    \n    string buildFromOrder(const vector<int>& order) {\n        if (order.empty()) return \"\";\n        string result = words[order[0]];\n        for (int i = 1; i < order.size(); i++) {\n            result += words[order[i]].substr(overlap[order[i-1]][order[i]]);\n        }\n        return result;\n    }\n    \n    int calculateOrderLength(const vector<int>& order) {\n        if (order.empty()) return 0;\n        int len = words[order[0]].length();\n        for (int i = 1; i < order.size(); i++) {\n            len += words[order[i]].length() - overlap[order[i-1]][order[i]];\n        }\n        return len;\n    }\n    \n    // 2-opt local search\n    void improve2Opt(vector<int>& order) {\n        bool improved = true;\n        while (improved) {\n            improved = false;\n            int currentLen = calculateOrderLength(order);\n            \n            for (int i = 0; i < order.size() - 1; i++) {\n                for (int j = i + 1; j < order.size(); j++) {\n                    // Try reversing segment [i+1, j]\n                    vector<int> newOrder = order;\n                    reverse(newOrder.begin() + i + 1, newOrder.begin() + j + 1);\n                    \n                    int newLen = calculateOrderLength(newOrder);\n                    if (newLen < currentLen) {\n                        order = newOrder;\n                        currentLen = newLen;\n                        improved = true;\n                    }\n                    \n                    // Try swapping i and j\n                    newOrder = order;\n                    swap(newOrder[i], newOrder[j]);\n                    newLen = calculateOrderLength(newOrder);\n                    if (newLen < currentLen) {\n                        order = newOrder;\n                        currentLen = newLen;\n                        improved = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Branch and bound for small instances\n    string solveBranchAndBound(const vector<int>& indices) {\n        int m = indices.size();\n        if (m > 12) return \"\"; // Too large for B&B\n        \n        vector<int> bestOrder;\n        int bestLen = INT_MAX;\n        \n        function<void(vector<int>&, vector<bool>&, int)> search = \n            [&](vector<int>& current, vector<bool>& used, int currentLen) {\n            if (current.size() == m) {\n                if (currentLen < bestLen) {\n                    bestLen = currentLen;\n                    bestOrder = current;\n                }\n                return;\n            }\n            \n            // Pruning\n            if (currentLen >= bestLen) return;\n            \n            for (int i = 0; i < m; i++) {\n                if (!used[i]) {\n                    int addLen = words[indices[i]].length();\n                    if (!current.empty()) {\n                        addLen -= overlap[indices[current.back()]][indices[i]];\n                    }\n                    \n                    current.push_back(i);\n                    used[i] = true;\n                    search(current, used, currentLen + addLen);\n                    current.pop_back();\n                    used[i] = false;\n                }\n            }\n        };\n        \n        vector<int> current;\n        vector<bool> used(m, false);\n        \n        // Try different starting points\n        for (int start = 0; start < min(m, 3); start++) {\n            current = {start};\n            used.assign(m, false);\n            used[start] = true;\n            search(current, used, words[indices[start]].length());\n        }\n        \n        if (!bestOrder.empty()) {\n            vector<int> actualOrder;\n            for (int idx : bestOrder) {\n                actualOrder.push_back(indices[idx]);\n            }\n            return buildFromOrder(actualOrder);\n        }\n        \n        return \"\";\n    }\n    \npublic:\n    SuperstringOptimizer(vector<string>& w) : words(w), n(w.size()) {\n        overlap.resize(n, vector<int>(n, 0));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (i != j) {\n                    overlap[i][j] = computeOverlap(words[i], words[j]);\n                }\n            }\n        }\n    }\n    \n    string buildOptimal() {\n        // Remove substrings\n        vector<int> indices;\n        for (int i = 0; i < n; i++) {\n            bool isSubstring = false;\n            for (int j = 0; j < n; j++) {\n                if (i != j && words[j].find(words[i]) != string::npos) {\n                    isSubstring = true;\n                    break;\n                }\n            }\n            if (!isSubstring) {\n                indices.push_back(i);\n            }\n        }\n        \n        int m = indices.size();\n        \n        // Try branch and bound for small instances\n        if (m <= 12) {\n            string bbResult = solveBranchAndBound(indices);\n            if (!bbResult.empty()) {\n                // Verify and add missing words\n                for (const string& w : words) {\n                    if (bbResult.find(w) == string::npos) {\n                        bbResult += w;\n                    }\n                }\n                return bbResult;\n            }\n        }\n        \n        // For larger instances, use multiple greedy + local search\n        string bestResult;\n        \n        for (int trial = 0; trial < min(m, 30); trial++) {\n            vector<int> order;\n            vector<bool> used(m, false);\n            \n            // Choose starting word\n            int start;\n            if (trial < m) {\n                start = trial;\n            } else {\n                // Random start\n                start = rand() % m;\n            }\n            \n            order.push_back(indices[start]);\n            used[start] = true;\n            \n            // Greedy construction with randomization\n            while (order.size() < m) {\n                int last = order.back();\n                vector<pair<int, int>> candidates;\n                \n                for (int i = 0; i < m; i++) {\n                    if (!used[i]) {\n                        candidates.push_back({overlap[last][indices[i]], i});\n                    }\n                }\n                \n                // Sort by overlap (descending)\n                sort(candidates.begin(), candidates.end(), greater<pair<int,int>>());\n                \n                // Pick from top candidates with some randomization\n                int pick = 0;\n                if (trial >= m && candidates.size() > 3) {\n                    // Add randomization for diversity\n                    pick = rand() % min(3, (int)candidates.size());\n                }\n                \n                int nextIdx = candidates[pick].second;\n                order.push_back(indices[nextIdx]);\n                used[nextIdx] = true;\n            }\n            \n            // Convert to actual indices\n            vector<int> actualOrder;\n            for (int i = 0; i < order.size(); i++) {\n                actualOrder.push_back(order[i]);\n            }\n            \n            // Local optimization\n            improve2Opt(actualOrder);\n            \n            // Build string\n            string result = buildFromOrder(actualOrder);\n            \n            // Add missing words\n            for (const string& w : words) {\n                if (result.find(w) == string::npos) {\n                    result += w;\n                }\n            }\n            \n            if (bestResult.empty() || result.length() < bestResult.length()) {\n                bestResult = result;\n            }\n        }\n        \n        return bestResult;\n    }\n};\n\n// Optimal path finding with DP\nvector<pair<int, int>> findOptimalPath(const string& s, Position startPos,\n                                       const vector<vector<Position>>& charPositions) {\n    int n = s.length();\n    if (n == 0) return {};\n    \n    const int MAX_DP_LEN = 1500;\n    \n    if (n <= MAX_DP_LEN) {\n        // Full DP\n        vector<vector<int>> dp(n);\n        vector<vector<int>> parent(n);\n        \n        for (int i = 0; i < n; i++) {\n            int charIdx = s[i] - 'A';\n            dp[i].resize(charPositions[charIdx].size(), INT_MAX);\n            parent[i].resize(charPositions[charIdx].size(), -1);\n        }\n        \n        // Initialize\n        int firstCharIdx = s[0] - 'A';\n        for (int j = 0; j < charPositions[firstCharIdx].size(); j++) {\n            dp[0][j] = manhattan(startPos, charPositions[firstCharIdx][j]);\n        }\n        \n        // Fill DP\n        for (int i = 1; i < n; i++) {\n            int currCharIdx = s[i] - 'A';\n            int prevCharIdx = s[i-1] - 'A';\n            \n            for (int j = 0; j < charPositions[currCharIdx].size(); j++) {\n                for (int k = 0; k < charPositions[prevCharIdx].size(); k++) {\n                    int cost = dp[i-1][k] + manhattan(charPositions[prevCharIdx][k],\n                                                     charPositions[currCharIdx][j]);\n                    if (cost < dp[i][j]) {\n                        dp[i][j] = cost;\n                        parent[i][j] = k;\n                    }\n                }\n            }\n        }\n        \n        // Backtrack\n        int bestEnd = 0;\n        for (int j = 1; j < dp[n-1].size(); j++) {\n            if (dp[n-1][j] < dp[n-1][bestEnd]) {\n                bestEnd = j;\n            }\n        }\n        \n        vector<int> choices(n);\n        choices[n-1] = bestEnd;\n        for (int i = n - 1; i > 0; i--) {\n            choices[i-1] = parent[i][choices[i]];\n        }\n        \n        vector<pair<int, int>> result;\n        for (int i = 0; i < n; i++) {\n            Position pos = charPositions[s[i] - 'A'][choices[i]];\n            result.push_back({pos.i, pos.j});\n        }\n        return result;\n    }\n    \n    // For long strings, use segmented DP with overlap\n    vector<pair<int, int>> result;\n    Position curr = startPos;\n    \n    for (int start = 0; start < n; ) {\n        int end = min(start + MAX_DP_LEN, n);\n        string segment = s.substr(start, end - start);\n        \n        vector<pair<int, int>> segmentPath = findOptimalPath(segment, curr, charPositions);\n        for (const auto& move : segmentPath) {\n            result.push_back(move);\n            curr = {move.first, move.second};\n        }\n        \n        start = end;\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n    \n    int N, M;\n    cin >> N >> M;\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    vector<vector<Position>> charPositions(26);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            charPositions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n    \n    vector<string> words(M);\n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    // Build optimized superstring\n    SuperstringOptimizer optimizer(words);\n    string superstring = optimizer.buildOptimal();\n    \n    // Safety check\n    if (superstring.length() > 4950) {\n        set<string> unique;\n        for (const string& w : words) {\n            bool isSub = false;\n            for (const string& u : unique) {\n                if (u.find(w) != string::npos) {\n                    isSub = true;\n                    break;\n                }\n            }\n            if (!isSub) unique.insert(w);\n        }\n        superstring = \"\";\n        for (const string& w : unique) {\n            superstring += w;\n        }\n    }\n    \n    // Find optimal path\n    vector<pair<int, int>> moves = findOptimalPath(superstring, {si, sj}, charPositions);\n    \n    // Output\n    for (const auto& move : moves) {\n        cout << move.first << \" \" << move.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, M;\ndouble eps;\n\nint queryDrill(int i, int j) {\n    cout << \"q 1 \" << i << \" \" << j << endl;\n    cout.flush();\n    int v;\n    cin >> v;\n    return v;\n}\n\nint queryDivine(vector<pair<int,int>>& pts) {\n    cout << \"q \" << pts.size();\n    for (auto [i, j] : pts) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    cout.flush();\n    int v;\n    cin >> v;\n    return v;\n}\n\nbool submitAnswer(vector<pair<int,int>>& oil) {\n    cout << \"a \" << oil.size();\n    for (auto [i, j] : oil) {\n        cout << \" \" << i << \" \" << j;\n    }\n    cout << endl;\n    cout.flush();\n    int result;\n    cin >> result;\n    return result == 1;\n}\n\nint main() {\n    cin >> N >> M >> eps;\n    \n    // Read oil field shapes (but we won't use them in this simple solution)\n    for (int m = 0; m < M; m++) {\n        int d;\n        cin >> d;\n        for (int k = 0; k < d; k++) {\n            int i, j;\n            cin >> i >> j;\n        }\n    }\n    \n    vector<vector<int>> oil(N, vector<int>(N, -1));\n    vector<pair<int,int>> confirmedOil;\n    \n    // Strategy: Use large divinations first, then drill promising areas\n    \n    // Phase 1: Divide into 4 quadrants and divine each\n    vector<vector<pair<int,int>>> quadrants(4);\n    int mid = N / 2;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int q = (i >= mid ? 2 : 0) + (j >= mid ? 1 : 0);\n            quadrants[q].push_back({i, j});\n        }\n    }\n    \n    vector<int> quadrantResults;\n    for (int q = 0; q < 4; q++) {\n        if (quadrants[q].size() >= 2) {\n            int result = queryDivine(quadrants[q]);\n            quadrantResults.push_back(result);\n        } else {\n            quadrantResults.push_back(0);\n        }\n    }\n    \n    // Phase 2: For each promising quadrant, divide further\n    for (int q = 0; q < 4; q++) {\n        if (quadrantResults[q] > 0 || quadrantResults[q] > quadrants[q].size() * eps) {\n            // This quadrant likely has oil\n            \n            // Divide quadrant into smaller blocks\n            int blockSize = 3;\n            int startI = (q >= 2) ? mid : 0;\n            int endI = (q >= 2) ? N : mid;\n            int startJ = (q % 2 == 1) ? mid : 0;\n            int endJ = (q % 2 == 1) ? N : mid;\n            \n            for (int bi = startI; bi < endI; bi += blockSize) {\n                for (int bj = startJ; bj < endJ; bj += blockSize) {\n                    vector<pair<int,int>> block;\n                    for (int i = bi; i < min(endI, bi + blockSize); i++) {\n                        for (int j = bj; j < min(endJ, bj + blockSize); j++) {\n                            block.push_back({i, j});\n                        }\n                    }\n                    \n                    if (block.size() >= 2) {\n                        int blockResult = queryDivine(block);\n                        if (blockResult > 0) {\n                            // Drill this block\n                            for (auto [i, j] : block) {\n                                if (oil[i][j] == -1) {\n                                    oil[i][j] = queryDrill(i, j);\n                                    if (oil[i][j] > 0) {\n                                        confirmedOil.push_back({i, j});\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Check areas adjacent to confirmed oil\n    set<pair<int,int>> toCheck;\n    for (auto [oi, oj] : confirmedOil) {\n        for (int di = -1; di <= 1; di++) {\n            for (int dj = -1; dj <= 1; dj++) {\n                if (abs(di) + abs(dj) == 1) {\n                    int ni = oi + di;\n                    int nj = oj + dj;\n                    if (ni >= 0 && ni < N && nj >= 0 && nj < N && oil[ni][nj] == -1) {\n                        toCheck.insert({ni, nj});\n                    }\n                }\n            }\n        }\n    }\n    \n    for (auto [i, j] : toCheck) {\n        oil[i][j] = queryDrill(i, j);\n        if (oil[i][j] > 0) {\n            confirmedOil.push_back({i, j});\n        }\n    }\n    \n    // Phase 4: Do overlapping divinations for any remaining uncertain areas\n    for (int offset = 0; offset < 2; offset++) {\n        for (int bi = offset * 2; bi < N - 2; bi += 4) {\n            for (int bj = offset * 2; bj < N - 2; bj += 4) {\n                vector<pair<int,int>> block;\n                for (int i = bi; i < min(N, bi + 4); i++) {\n                    for (int j = bj; j < min(N, bj + 4); j++) {\n                        if (oil[i][j] == -1) {\n                            block.push_back({i, j});\n                        }\n                    }\n                }\n                \n                if (block.size() >= 3) {\n                    int result = queryDivine(block);\n                    if (result > block.size() * eps * 2) {\n                        for (auto [i, j] : block) {\n                            if (oil[i][j] == -1) {\n                                oil[i][j] = queryDrill(i, j);\n                                if (oil[i][j] > 0) {\n                                    confirmedOil.push_back({i, j});\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Submit answer\n    if (!submitAnswer(confirmedOil)) {\n        // If wrong, drill more squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (oil[i][j] == -1) {\n                    oil[i][j] = queryDrill(i, j);\n                    if (oil[i][j] > 0) {\n                        confirmedOil.push_back({i, j});\n                    }\n                }\n            }\n        }\n        submitAnswer(confirmedOil);\n    }\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <numeric>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Calculate percentile areas for each position\n    vector<int> p75_areas(N);  // 75th percentile\n    vector<int> p90_areas(N);  // 90th percentile\n    \n    for (int k = 0; k < N; k++) {\n        vector<int> areas_k;\n        for (int d = 0; d < D; d++) {\n            areas_k.push_back(a[d][k]);\n        }\n        sort(areas_k.begin(), areas_k.end());\n        \n        int idx75 = (3 * D) / 4;\n        int idx90 = (9 * D) / 10;\n        p75_areas[k] = areas_k[min(idx75, D-1)];\n        p90_areas[k] = areas_k[min(idx90, D-1)];\n    }\n    \n    // Calculate optimal heights using dynamic programming approach\n    // Goal: minimize total expected cost\n    vector<int> heights(N);\n    vector<int> y_start(N);\n    \n    // Use p90 areas for robust height allocation\n    vector<double> target_heights(N);\n    double total_target = 0;\n    \n    for (int k = 0; k < N; k++) {\n        // Balance between area needs and aspect ratio\n        target_heights[k] = sqrt((double)p90_areas[k]);\n        total_target += target_heights[k];\n    }\n    \n    // Allocate heights proportionally\n    int used_height = 0;\n    for (int k = 0; k < N; k++) {\n        if (k == N - 1) {\n            heights[k] = W - used_height;\n        } else {\n            double proportion = target_heights[k] / total_target;\n            int h = max(1, (int)(W * proportion + 0.5));\n            \n            // Ensure minimum viable height\n            int min_h = (p90_areas[k] + W - 1) / W;\n            h = max(h, min_h);\n            \n            // Leave space for remaining strips\n            h = min(h, W - used_height - (N - k - 1));\n            heights[k] = h;\n        }\n        \n        y_start[k] = used_height;\n        used_height += heights[k];\n    }\n    \n    // Calculate stable widths for each strip based on percentiles\n    vector<int> stable_widths(N);\n    for (int k = 0; k < N; k++) {\n        // Use 75th percentile for stable width\n        stable_widths[k] = (p75_areas[k] + heights[k] - 1) / heights[k];\n        stable_widths[k] = min(stable_widths[k], W);\n    }\n    \n    // Create layout for each day\n    vector<vector<int>> widths_per_day(D, vector<int>(N));\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            // Start with stable width\n            int width = stable_widths[k];\n            \n            // Check if we need to adjust to meet area requirement\n            int current_area = heights[k] * width;\n            if (current_area < a[d][k]) {\n                // Must expand to avoid penalty\n                width = (a[d][k] + heights[k] - 1) / heights[k];\n                width = min(width, W);\n            }\n            \n            widths_per_day[d][k] = width;\n        }\n    }\n    \n    // Apply smoothing to reduce partition changes\n    // If a width change is small, keep it consistent across adjacent days\n    for (int k = 0; k < N; k++) {\n        for (int d = 1; d < D - 1; d++) {\n            int prev_w = widths_per_day[d-1][k];\n            int curr_w = widths_per_day[d][k];\n            int next_w = widths_per_day[d+1][k];\n            \n            // If surrounded by similar widths, adjust to median\n            if (abs(prev_w - next_w) <= 10) {\n                int median_w = max({prev_w, curr_w, next_w}) - \n                              min({prev_w, curr_w, next_w});\n                if (median_w == 0) median_w = prev_w;\n                \n                // Check if median width still satisfies area requirement\n                int area_with_median = heights[k] * median_w;\n                if (area_with_median >= a[d][k]) {\n                    widths_per_day[d][k] = median_w;\n                }\n            }\n        }\n    }\n    \n    // Output rectangles\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << y_start[k] << \" \" << 0 << \" \" \n                 << (y_start[k] + heights[k]) << \" \" << widths_per_day[d][k] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> board[i][j];\n        }\n    }\n    \n    vector<vector<vector<long long>>> stamps(M, vector<vector<long long>>(3, vector<long long>(3)));\n    for (int m = 0; m < M; m++) {\n        for (int i = 0; i < 3; i++) {\n            for (int j = 0; j < 3; j++) {\n                cin >> stamps[m][i][j];\n            }\n        }\n    }\n    \n    vector<tuple<int, int, int>> operations;\n    \n    for (int op = 0; op < K; op++) {\n        int best_m = -1, best_p = -1, best_q = -1;\n        double best_score = -1e18;\n        \n        double progress = (double)op / K;\n        \n        // Try all stamps and positions\n        for (int m = 0; m < M; m++) {\n            for (int p = 0; p <= N - 3; p++) {\n                for (int q = 0; q <= N - 3; q++) {\n                    double score = 0;\n                    \n                    // Evaluate stamp placement\n                    for (int i = 0; i < 3; i++) {\n                        for (int j = 0; j < 3; j++) {\n                            long long old_val = board[p + i][q + j];\n                            long long stamp_val = stamps[m][i][j];\n                            long long new_val = old_val + stamp_val;\n                            \n                            long long old_mod = old_val % MOD;\n                            long long new_mod = new_val % MOD;\n                            \n                            // Base score: actual change in modulo value\n                            long long delta = new_mod - old_mod;\n                            score += delta;\n                            \n                            // Calculate room before wraparound\n                            long long room = MOD - 1 - old_mod;\n                            \n                            if (stamp_val <= room) {\n                                // No wraparound - always beneficial\n                                score += stamp_val * 2.5;  // Slightly increased from 2\n                                \n                                // Progressive bonuses for high values\n                                if (new_mod >= 0.98 * MOD) {\n                                    score += 120000;  // Fine-tuned bonus\n                                } else if (new_mod >= 0.95 * MOD) {\n                                    score += 60000;\n                                } else if (new_mod >= 0.90 * MOD) {\n                                    score += 25000;\n                                } else if (new_mod >= 0.85 * MOD) {\n                                    score += 12000;\n                                }\n                                \n                                // Efficiency bonus for good space utilization\n                                if (progress > 0.5 && room > 0 && stamp_val > 0) {\n                                    double efficiency = (double)stamp_val / room;\n                                    if (efficiency > 0.75) {\n                                        score += efficiency * 35000;\n                                    } else if (efficiency > 0.5) {\n                                        score += efficiency * 15000;\n                                    }\n                                }\n                            } else {\n                                // Wraparound case\n                                // Consider net effect\n                                if (delta > 0) {\n                                    // Still gaining even with wrap\n                                    score += delta * 0.7;\n                                }\n                                \n                                // Penalty based on value lost\n                                if (old_mod >= 0.95 * MOD) {\n                                    score -= old_mod * 0.7;\n                                } else if (old_mod >= 0.90 * MOD) {\n                                    score -= old_mod * 0.45;\n                                } else if (old_mod >= 0.85 * MOD) {\n                                    score -= old_mod * 0.25;\n                                } else if (old_mod >= 0.80 * MOD) {\n                                    score -= old_mod * 0.1;\n                                }\n                                // Minimal penalty for low values\n                            }\n                        }\n                    }\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_m = m;\n                        best_p = p;\n                        best_q = q;\n                    }\n                }\n            }\n        }\n        \n        // Apply the best operation\n        if (best_m != -1) {\n            operations.push_back({best_m, best_p, best_q});\n            for (int i = 0; i < 3; i++) {\n                for (int j = 0; j < 3; j++) {\n                    board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                }\n            }\n        }\n    }\n    \n    cout << operations.size() << \"\\n\";\n    for (auto [m, p, q] : operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Position {\n    int r, c;\n    bool operator==(const Position& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator!=(const Position& other) const {\n        return !(*this == other);\n    }\n};\n\nstruct State {\n    vector<vector<int>> grid;\n    vector<Position> crane_pos;\n    vector<int> crane_holding;\n    vector<queue<int>> receiving_queues;\n    int total_dispatched;\n    \n    State(const vector<vector<int>>& A) : \n        grid(N, vector<int>(N, -1)),\n        crane_pos(N),\n        crane_holding(N, -1),\n        receiving_queues(N),\n        total_dispatched(0) {\n        \n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n            for (int j = 0; j < N; j++) {\n                receiving_queues[i].push(A[i][j]);\n            }\n        }\n    }\n};\n\nPosition applyMove(Position pos, char move) {\n    if (move == 'U' && pos.r > 0) return {pos.r - 1, pos.c};\n    if (move == 'D' && pos.r < N-1) return {pos.r + 1, pos.c};\n    if (move == 'L' && pos.c > 0) return {pos.r, pos.c - 1};\n    if (move == 'R' && pos.c < N-1) return {pos.r, pos.c + 1};\n    return pos;\n}\n\n// Check if moves are valid (no collisions, no swaps)\nbool checkMoves(const vector<Position>& current, const vector<char>& actions, \n                vector<Position>& result) {\n    result = current;\n    \n    for (int i = 0; i < N; i++) {\n        if (actions[i] == 'U' || actions[i] == 'D' || \n            actions[i] == 'L' || actions[i] == 'R') {\n            result[i] = applyMove(current[i], actions[i]);\n        }\n    }\n    \n    // Check for same destination\n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (result[i] == result[j]) return false;\n            // Check for swapping\n            if (current[i] == result[j] && current[j] == result[i]) {\n                return false;\n            }\n        }\n    }\n    \n    return true;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state(A);\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        // Receive containers\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty() && state.grid[i][0] == -1) {\n                bool blocked = false;\n                for (int j = 0; j < N; j++) {\n                    if (state.crane_pos[j].r == i && state.crane_pos[j].c == 0 && \n                        state.crane_holding[j] != -1) {\n                        blocked = true;\n                        break;\n                    }\n                }\n                if (!blocked) {\n                    state.grid[i][0] = state.receiving_queues[i].front();\n                    state.receiving_queues[i].pop();\n                }\n            }\n        }\n        \n        // Plan actions\n        vector<char> actions(N, '.');\n        \n        for (int crane = 0; crane < N; crane++) {\n            Position pos = state.crane_pos[crane];\n            bool isLarge = (crane == 0);\n            \n            if (state.crane_holding[crane] != -1) {\n                // Holding container\n                int container = state.crane_holding[crane];\n                int target_row = container / N;\n                \n                if (pos.c == N - 1 && pos.r == target_row) {\n                    if (state.grid[pos.r][pos.c] == -1) {\n                        actions[crane] = 'Q';\n                    }\n                } else {\n                    // Move towards target\n                    if (pos.c < N - 1) {\n                        Position next = applyMove(pos, 'R');\n                        if (next != pos && (isLarge || state.grid[next.r][next.c] == -1)) {\n                            actions[crane] = 'R';\n                        }\n                    } else if (pos.r < target_row) {\n                        Position next = applyMove(pos, 'D');\n                        if (next != pos && (isLarge || state.grid[next.r][next.c] == -1)) {\n                            actions[crane] = 'D';\n                        }\n                    } else if (pos.r > target_row) {\n                        Position next = applyMove(pos, 'U');\n                        if (next != pos && (isLarge || state.grid[next.r][next.c] == -1)) {\n                            actions[crane] = 'U';\n                        }\n                    }\n                }\n            } else {\n                // Not holding\n                if (state.grid[pos.r][pos.c] != -1) {\n                    actions[crane] = 'P';\n                } else if (pos.c > 0) {\n                    actions[crane] = 'L';\n                } else if (pos.r > 0 && crane > 0) {\n                    actions[crane] = 'U';\n                } else if (pos.r < N-1 && crane > 0) {\n                    actions[crane] = 'D';\n                }\n            }\n        }\n        \n        // Validate and fix conflicts\n        vector<Position> new_positions;\n        if (!checkMoves(state.crane_pos, actions, new_positions)) {\n            // Try to resolve by making some cranes stay\n            for (int skip = 0; skip < N; skip++) {\n                char saved = actions[skip];\n                actions[skip] = '.';\n                if (checkMoves(state.crane_pos, actions, new_positions)) {\n                    break;\n                }\n                actions[skip] = saved;\n            }\n            \n            // If still invalid, make all stay\n            if (!checkMoves(state.crane_pos, actions, new_positions)) {\n                for (int i = 0; i < N; i++) {\n                    if (actions[i] != 'P' && actions[i] != 'Q') {\n                        actions[i] = '.';\n                    }\n                }\n                new_positions = state.crane_pos;\n            }\n        }\n        \n        // Execute actions\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            Position& pos = state.crane_pos[crane];\n            \n            if (action == 'P') {\n                if (state.grid[pos.r][pos.c] != -1 && state.crane_holding[crane] == -1) {\n                    state.crane_holding[crane] = state.grid[pos.r][pos.c];\n                    state.grid[pos.r][pos.c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (state.crane_holding[crane] != -1 && state.grid[pos.r][pos.c] == -1) {\n                    state.grid[pos.r][pos.c] = state.crane_holding[crane];\n                    state.crane_holding[crane] = -1;\n                }\n            }\n            \n            commands[crane] += action;\n        }\n        \n        // Update positions\n        state.crane_pos = new_positions;\n        \n        // Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (state.grid[i][N-1] != -1) {\n                state.grid[i][N-1] = -1;\n                state.total_dispatched++;\n            }\n        }\n        \n        // Check if done\n        if (state.total_dispatched == N * N) break;\n    }\n    \n    // Trim commands to same length\n    size_t max_len = 0;\n    for (const auto& cmd : commands) {\n        max_len = max(max_len, cmd.length());\n    }\n    \n    for (auto& cmd : commands) {\n        while (cmd.length() < max_len) {\n            cmd += '.';\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <set>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_OPS = 100000;\nconst int INF = 1e9;\n\nvector<string> operations;\nint grid[N][N];\nint cur_r = 0, cur_c = 0;\nint loaded = 0;\n\n// Direction vectors\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct Task {\n    int sr, sc, dr, dc, amount;\n    double efficiency;\n    bool operator<(const Task& other) const {\n        return efficiency > other.efficiency; // Higher efficiency first\n    }\n};\n\n// BFS to find shortest path\nvector<int> find_path(int sr, int sc, int tr, int tc) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    \n    dist[sr][sc] = 0;\n    q.push({sr, sc});\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        \n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == INF) {\n                dist[nr][nc] = dist[r][c] + 1;\n                parent[nr][nc] = d;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path;\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int d = parent[r][c];\n        path.push_back(d);\n        r -= dr[d];\n        c -= dc[d];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Move to target location\nvoid move_to(int tr, int tc) {\n    if (cur_r == tr && cur_c == tc) return;\n    \n    vector<int> path = find_path(cur_r, cur_c, tr, tc);\n    for (int d : path) {\n        operations.push_back(string(1, dir_char[d]));\n        cur_r += dr[d];\n        cur_c += dc[d];\n    }\n}\n\n// Load soil from current position\nvoid load_soil(int amount) {\n    if (amount <= 0 || grid[cur_r][cur_c] <= 0) return;\n    amount = min(amount, grid[cur_r][cur_c]);\n    operations.push_back(\"+\" + to_string(amount));\n    grid[cur_r][cur_c] -= amount;\n    loaded += amount;\n}\n\n// Unload soil to current position  \nvoid unload_soil(int amount) {\n    if (amount <= 0 || loaded <= 0 || grid[cur_r][cur_c] >= 0) return;\n    amount = min(amount, min(loaded, -grid[cur_r][cur_c]));\n    operations.push_back(\"-\" + to_string(amount));\n    grid[cur_r][cur_c] += amount;\n    loaded -= amount;\n}\n\n// Unload all to current position (handles both positive and negative targets)\nvoid unload_all() {\n    if (loaded <= 0) return;\n    int amount = min(loaded, -grid[cur_r][cur_c]);\n    if (amount > 0) {\n        operations.push_back(\"-\" + to_string(amount));\n        grid[cur_r][cur_c] += amount;\n        loaded -= amount;\n    }\n}\n\nint manhattan_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\n// Calculate efficiency score for a transport task\ndouble calc_efficiency(int sr, int sc, int dr, int dc, int amount, int curr_r, int curr_c) {\n    int dist_to_src = manhattan_dist(curr_r, curr_c, sr, sc);\n    int transport_dist = manhattan_dist(sr, sc, dr, dc);\n    int total_dist = dist_to_src + transport_dist;\n    \n    // Cost = load + unload + movement\n    int cost = 2 * amount + dist_to_src * 100 + transport_dist * (100 + amount);\n    \n    // Efficiency = amount transported / estimated cost\n    // Higher is better\n    return (double)amount / (double)cost;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    // Read grid\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    // Main processing loop\n    while (operations.size() < MAX_OPS - 1000) {\n        // Find all tasks\n        vector<Task> tasks;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] > 0) {\n                    // Find all possible destinations for this source\n                    for (int di = 0; di < N; di++) {\n                        for (int dj = 0; dj < N; dj++) {\n                            if (grid[di][dj] < 0) {\n                                int amount = min(grid[i][j], -grid[di][dj]);\n                                double eff = calc_efficiency(i, j, di, dj, amount, cur_r, cur_c);\n                                tasks.push_back({i, j, di, dj, amount, eff});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (tasks.empty()) break;\n        \n        // Sort by efficiency\n        sort(tasks.begin(), tasks.end());\n        \n        // Execute the best task\n        Task best = tasks[0];\n        \n        // Move to source\n        move_to(best.sr, best.sc);\n        \n        // Load what we can\n        int to_load = min(grid[best.sr][best.sc], best.amount);\n        if (to_load > 0) {\n            load_soil(to_load);\n            \n            // Move to destination\n            move_to(best.dr, best.dc);\n            \n            // Unload\n            unload_all();\n        }\n        \n        // Check if done\n        bool all_zero = true;\n        for (int i = 0; i < N && all_zero; i++) {\n            for (int j = 0; j < N && all_zero; j++) {\n                if (grid[i][j] != 0) all_zero = false;\n            }\n        }\n        if (all_zero) break;\n    }\n    \n    // If there's still loaded soil at the end, try to unload it\n    if (loaded > 0) {\n        for (int i = 0; i < N && loaded > 0; i++) {\n            for (int j = 0; j < N && loaded > 0; j++) {\n                if (grid[i][j] < 0) {\n                    move_to(i, j);\n                    unload_all();\n                }\n            }\n        }\n    }\n    \n    // Output operations\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 <random>\n#include <numeric>\n#include <set>\n#include <cmath>\n#include <map>\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));\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    random_device rd;\n    mt19937 gen(rd());\n    \n    // Track progress metrics\n    vector<double> generation_best(T+1, 0);\n    vector<int> global_best_traits(M, 0);\n    double prev_best = 0;\n    int stagnation_count = 0;\n    \n    for (int t = 0; t < T; t++) {\n        // Update global best traits\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                global_best_traits[j] = max(global_best_traits[j], X[i][j]);\n            }\n        }\n        \n        // Calculate comprehensive metrics\n        vector<int> seed_values(seed_count);\n        vector<double> seed_scores(seed_count);\n        vector<vector<double>> trait_percentile(seed_count, vector<double>(M));\n        \n        // Calculate trait distributions\n        vector<vector<int>> trait_values(M);\n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += X[i][j];\n                trait_values[j].push_back(X[i][j]);\n            }\n        }\n        \n        // Calculate percentiles for each trait\n        vector<double> trait_means(M, 0);\n        vector<int> p25(M), p50(M), p75(M), p90(M), p95(M);\n        for (int j = 0; j < M; j++) {\n            sort(trait_values[j].begin(), trait_values[j].end());\n            p25[j] = trait_values[j][seed_count/4];\n            p50[j] = trait_values[j][seed_count/2];\n            p75[j] = trait_values[j][3*seed_count/4];\n            p90[j] = trait_values[j][9*seed_count/10];\n            p95[j] = trait_values[j][19*seed_count/20];\n            \n            for (int val : trait_values[j]) {\n                trait_means[j] += val;\n            }\n            trait_means[j] /= seed_count;\n        }\n        \n        // Calculate percentile rank for each seed's traits\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                int val = X[i][j];\n                double percentile = 0;\n                for (int k = 0; k < seed_count; k++) {\n                    if (trait_values[j][k] < val) percentile++;\n                }\n                trait_percentile[i][j] = percentile / seed_count;\n            }\n        }\n        \n        // Advanced scoring with multiple factors\n        double current_best = 0;\n        for (int i = 0; i < seed_count; i++) {\n            double score = seed_values[i];\n            \n            // Calculate various metrics\n            double min_trait = 1000.0;\n            double harmonic_mean = 0;\n            int elite_count = 0;\n            int good_count = 0;\n            int weak_count = 0;\n            double percentile_sum = 0;\n            \n            for (int j = 0; j < M; j++) {\n                min_trait = min(min_trait, (double)X[i][j]);\n                if (X[i][j] > 0) harmonic_mean += 1.0 / X[i][j];\n                \n                if (X[i][j] >= p90[j]) elite_count++;\n                if (X[i][j] >= p75[j]) good_count++;\n                if (X[i][j] < p25[j]) weak_count++;\n                \n                percentile_sum += trait_percentile[i][j];\n            }\n            \n            harmonic_mean = M / harmonic_mean;\n            \n            // Multi-factor scoring\n            score = seed_values[i];\n            \n            // Reward balanced excellence\n            score += min_trait * 3.0;  // Strong bonus for high minimum\n            score += harmonic_mean * 1.5;  // Reward harmonic mean\n            \n            // Reward elite traits more heavily\n            score += elite_count * 30.0;\n            score += good_count * 10.0;\n            score -= weak_count * 15.0;  // Penalty for weak traits\n            \n            // Percentile-based bonus\n            score += percentile_sum * 20.0;\n            \n            // Special bonus for nearly perfect seeds\n            if (min_trait >= p75[0]) {  // All traits above 75th percentile\n                score *= 1.2;\n            }\n            \n            seed_scores[i] = score;\n            current_best = max(current_best, (double)seed_values[i]);\n        }\n        \n        // Track progress\n        generation_best[t] = current_best;\n        if (current_best <= prev_best * 1.01) {\n            stagnation_count++;\n        } else {\n            stagnation_count = 0;\n        }\n        prev_best = current_best;\n        \n        // Create sorted index\n        vector<pair<double, int>> scored_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            scored_seeds.push_back({seed_scores[i], i});\n        }\n        sort(scored_seeds.begin(), scored_seeds.end(), greater<pair<double,int>>());\n        \n        // Adaptive strategy based on progress\n        enum Strategy { EXPLORE, EXPLOIT, CONVERGE };\n        Strategy strategy;\n        \n        if (t < 2) {\n            strategy = EXPLORE;\n        } else if (t >= T - 2 || (t >= T - 3 && stagnation_count >= 2)) {\n            strategy = CONVERGE;\n        } else if (stagnation_count >= 3) {\n            strategy = EXPLORE;  // Break out of local optimum\n        } else {\n            strategy = EXPLOIT;\n        }\n        \n        // Select seeds based on strategy\n        vector<int> selected_seeds;\n        set<int> used;\n        \n        if (strategy == EXPLORE) {\n            // Diversity-focused selection\n            // Use clustering to maintain diversity\n            \n            // Select elite seeds\n            int elite_size = N * N / 3;\n            for (int i = 0; i < elite_size && i < scored_seeds.size(); i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n            \n            // Add seeds with unique trait strengths\n            for (int j = 0; j < M && selected_seeds.size() < N*N; j++) {\n                // Find seed with best trait j that's not already selected\n                int best_idx = -1;\n                int best_val = -1;\n                for (int i = 0; i < seed_count; i++) {\n                    if (used.find(i) == used.end() && X[i][j] > best_val) {\n                        best_val = X[i][j];\n                        best_idx = i;\n                    }\n                }\n                if (best_idx != -1) {\n                    selected_seeds.push_back(best_idx);\n                    used.insert(best_idx);\n                }\n            }\n            \n            // Fill remaining with good diverse seeds\n            for (auto& p : scored_seeds) {\n                if (selected_seeds.size() >= N*N) break;\n                if (used.find(p.second) == used.end()) {\n                    selected_seeds.push_back(p.second);\n                    used.insert(p.second);\n                }\n            }\n            \n        } else if (strategy == EXPLOIT) {\n            // Balanced selection with focus on breeding potential\n            \n            // Calculate breeding potential between pairs\n            map<pair<int,int>, double> breeding_potential;\n            \n            // Take top candidates\n            vector<int> candidates;\n            int candidate_count = min(N*N*2, seed_count);\n            for (int i = 0; i < candidate_count; i++) {\n                candidates.push_back(scored_seeds[i].second);\n            }\n            \n            // Calculate breeding potential for pairs\n            for (int i = 0; i < candidates.size(); i++) {\n                for (int j = i+1; j < candidates.size(); j++) {\n                    int s1 = candidates[i];\n                    int s2 = candidates[j];\n                    \n                    double potential = 0;\n                    double complement_bonus = 0;\n                    \n                    for (int k = 0; k < M; k++) {\n                        // Expected value of offspring\n                        double expected = (X[s1][k] + X[s2][k]) / 2.0;\n                        \n                        // Best case scenario\n                        double best_case = max(X[s1][k], X[s2][k]);\n                        \n                        // Probability of getting best (simplified model)\n                        double prob_best = 0.5;\n                        \n                        // If one is much better, increase expected value\n                        if (abs(X[s1][k] - X[s2][k]) > 20) {\n                            expected = best_case * 0.7 + min(X[s1][k], X[s2][k]) * 0.3;\n                        }\n                        \n                        potential += expected;\n                        \n                        // Bonus for complementary strengths\n                        if ((X[s1][k] >= p90[k]) != (X[s2][k] >= p90[k])) {\n                            complement_bonus += 10;\n                        }\n                    }\n                    \n                    breeding_potential[{min(i,j), max(i,j)}] = potential + complement_bonus;\n                }\n            }\n            \n            // Select seeds that form good breeding pairs\n            set<int> selected_indices;\n            vector<pair<double, pair<int,int>>> sorted_pairs;\n            for (auto& bp : breeding_potential) {\n                sorted_pairs.push_back({bp.second, bp.first});\n            }\n            sort(sorted_pairs.begin(), sorted_pairs.end(), greater<pair<double,pair<int,int>>>());\n            \n            // Greedily select pairs\n            for (auto& sp : sorted_pairs) {\n                int idx1 = sp.second.first;\n                int idx2 = sp.second.second;\n                \n                if (selected_indices.size() >= N*N) break;\n                \n                if (selected_indices.find(idx1) == selected_indices.end()) {\n                    selected_seeds.push_back(candidates[idx1]);\n                    selected_indices.insert(idx1);\n                    used.insert(candidates[idx1]);\n                }\n                \n                if (selected_indices.size() < N*N && \n                    selected_indices.find(idx2) == selected_indices.end()) {\n                    selected_seeds.push_back(candidates[idx2]);\n                    selected_indices.insert(idx2);\n                    used.insert(candidates[idx2]);\n                }\n            }\n            \n            // Fill any remaining spots\n            for (int i = 0; i < candidates.size() && selected_seeds.size() < N*N; i++) {\n                if (used.find(candidates[i]) == used.end()) {\n                    selected_seeds.push_back(candidates[i]);\n                    used.insert(candidates[i]);\n                }\n            }\n            \n        } else {  // CONVERGE\n            // Pure exploitation of best seeds\n            for (int i = 0; i < N*N && i < scored_seeds.size(); i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n        }\n        \n        // Placement strategy\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        \n        if (strategy == CONVERGE) {\n            // Concentric placement - best in center\n            vector<pair<double, pair<int,int>>> positions;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double center_i = (N - 1) / 2.0;\n                    double center_j = (N - 1) / 2.0;\n                    double dist = sqrt(pow(i - center_i, 2) + pow(j - center_j, 2));\n                    positions.push_back({dist, {i, j}});\n                }\n            }\n            \n            sort(positions.begin(), positions.end());\n            \n            for (int k = 0; k < N*N; k++) {\n                A[positions[k].second.first][positions[k].second.second] = selected_seeds[k];\n            }\n            \n        } else if (strategy == EXPLOIT) {\n            // Smart placement considering breeding\n            // Place complementary seeds adjacent\n            \n            vector<bool> placed(selected_seeds.size(), false);\n            \n            // Start with best seed in favorable position\n            A[N/2][N/2] = selected_seeds[0];\n            placed[0] = true;\n            \n            // Iteratively place seeds to maximize breeding potential\n            for (int count = 1; count < N*N; count++) {\n                double best_placement_score = -1;\n                int best_seed_idx = -1;\n                int best_i = -1, best_j = -1;\n                \n                for (int idx = 0; idx < selected_seeds.size(); idx++) {\n                    if (placed[idx]) continue;\n                    \n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            if (A[i][j] != -1) continue;\n                            \n                            // Calculate placement score\n                            double score = 0;\n                            int neighbor_count = 0;\n                            \n                            // Check all four neighbors\n                            int di[] = {-1, 1, 0, 0};\n                            int dj[] = {0, 0, -1, 1};\n                            \n                            for (int d = 0; d < 4; d++) {\n                                int ni = i + di[d];\n                                int nj = j + dj[d];\n                                \n                                if (ni >= 0 && ni < N && nj >= 0 && nj < N && A[ni][nj] != -1) {\n                                    neighbor_count++;\n                                    \n                                    // Calculate breeding compatibility\n                                    for (int k = 0; k < M; k++) {\n                                        score += max(X[selected_seeds[idx]][k], X[A[ni][nj]][k]);\n                                    }\n                                }\n                            }\n                            \n                            // Prefer positions with more neighbors\n                            score += neighbor_count * 100;\n                            \n                            if (score > best_placement_score) {\n                                best_placement_score = score;\n                                best_seed_idx = idx;\n                                best_i = i;\n                                best_j = j;\n                            }\n                        }\n                    }\n                }\n                \n                if (best_seed_idx != -1) {\n                    A[best_i][best_j] = selected_seeds[best_seed_idx];\n                    placed[best_seed_idx] = true;\n                } else {\n                    // Fallback: place in first empty spot\n                    for (int idx = 0; idx < selected_seeds.size(); idx++) {\n                        if (!placed[idx]) {\n                            bool found = false;\n                            for (int i = 0; i < N && !found; i++) {\n                                for (int j = 0; j < N && !found; j++) {\n                                    if (A[i][j] == -1) {\n                                        A[i][j] = selected_seeds[idx];\n                                        placed[idx] = true;\n                                        found = true;\n                                    }\n                                }\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n        } else {  // EXPLORE\n            // Random placement for diversity\n            shuffle(selected_seeds.begin(), selected_seeds.end(), gen);\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    A[i][j] = selected_seeds[idx++];\n                }\n            }\n        }\n        \n        // Output placement\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                } else {\n                    cout << endl;\n                }\n            }\n        }\n        cout.flush();\n        \n        // Read new generation\n        X.clear();\n        X.resize(seed_count, vector<int>(M));\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[4] = {0, 1, 0, -1};  // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> grid(N), target(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    for (int i = 0; i < N; i++) cin >> target[i];\n    \n    // Use simple 2-vertex arm (root + 1 fingertip)\n    cout << \"2\\n\";\n    cout << \"0 1\\n\";  // vertex 1 has parent 0, length 1\n    cout << N/2 << \" \" << N/2 << \"\\n\";  // Start at center\n    \n    // Track state\n    int rootX = N/2, rootY = N/2;\n    int dir = 0;  // direction of arm (0=R, 1=D, 2=L, 3=U)\n    bool holding = false;\n    \n    vector<string> operations;\n    int maxTurns = 90000;\n    \n    for (int turn = 0; turn < maxTurns; turn++) {\n        // Check if we're done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (target[i][j] == '1' && grid[i][j] != '1') {\n                    done = false;\n                    break;\n                }\n            }\n            if (!done) break;\n        }\n        if (done) break;\n        \n        // Current fingertip position (before any operations this turn)\n        int tipX = rootX + dx[dir];\n        int tipY = rootY + dy[dir];\n        \n        // Plan this turn's operations\n        string op = \"....\";  // 2*V = 4 characters\n        \n        // Find nearest goal\n        int goalX = -1, goalY = -1;\n        int minDist = INT_MAX;\n        \n        if (holding) {\n            // Find nearest empty target position\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (target[i][j] == '1' && grid[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goalX = i;\n                            goalY = j;\n                        }\n                    }\n                }\n            }\n        } else {\n            // Find nearest takoyaki that needs to be moved\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] == '1' && target[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goalX = i;\n                            goalY = j;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (goalX == -1) {\n            operations.push_back(op);\n            continue;\n        }\n        \n        // First, try to rotate to face the goal\n        int bestDir = dir;\n        int bestDist = abs(tipX - goalX) + abs(tipY - goalY);\n        \n        for (int d = 0; d < 4; d++) {\n            int newTipX = rootX + dx[d];\n            int newTipY = rootY + dy[d];\n            int dist = abs(newTipX - goalX) + abs(newTipY - goalY);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestDir = d;\n            }\n        }\n        \n        if (bestDir != dir) {\n            int diff = (bestDir - dir + 4) % 4;\n            if (diff == 1) {\n                op[1] = 'R';\n                dir = bestDir;\n            } else if (diff == 3) {\n                op[1] = 'L';\n                dir = bestDir;\n            } else if (diff == 2) {\n                // Need 2 rotations, do one now\n                op[1] = 'R';\n                dir = (dir + 1) % 4;\n            }\n        }\n        \n        // Recalculate tip position after rotation\n        tipX = rootX + dx[dir];\n        tipY = rootY + dy[dir];\n        \n        // Then, move towards goal if needed\n        if (abs(tipX - goalX) + abs(tipY - goalY) > 0) {\n            int newRootX = rootX, newRootY = rootY;\n            \n            if (goalX < tipX && rootX > 0) {\n                newRootX--;\n                op[0] = 'U';\n            } else if (goalX > tipX && rootX < N-1) {\n                newRootX++;\n                op[0] = 'D';\n            } else if (goalY < tipY && rootY > 0) {\n                newRootY--;\n                op[0] = 'L';\n            } else if (goalY > tipY && rootY < N-1) {\n                newRootY++;\n                op[0] = 'R';\n            }\n            \n            rootX = newRootX;\n            rootY = newRootY;\n        }\n        \n        // Recalculate final tip position\n        tipX = rootX + dx[dir];\n        tipY = rootY + dy[dir];\n        \n        // Try to pick or place\n        if (tipX >= 0 && tipX < N && tipY >= 0 && tipY < N) {\n            if (!holding && grid[tipX][tipY] == '1' && target[tipX][tipY] == '0') {\n                // Pick up\n                op[3] = 'P';  // op[V + 1] where V=2\n                grid[tipX][tipY] = '0';\n                holding = true;\n            } else if (holding && grid[tipX][tipY] == '0' && target[tipX][tipY] == '1') {\n                // Place\n                op[3] = 'P';\n                grid[tipX][tipY] = '1';\n                holding = false;\n            }\n        }\n        \n        operations.push_back(op);\n    }\n    \n    // Output all operations\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nclass Solution {\nprivate:\n    int N;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    \npublic:\n    void solve() {\n        cin >> N;\n        mackerels.resize(N);\n        sardines.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> mackerels[i].x >> mackerels[i].y;\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> sardines[i].x >> sardines[i].y;\n        }\n        \n        // Try different grid sizes and pick the best result\n        int best_score = 0;\n        int best_x1 = 0, best_y1 = 0, best_x2 = 1000, best_y2 = 1000;\n        \n        for (int grid_size : {40, 60, 80, 100, 120}) {\n            auto [x1, y1, x2, y2, score] = findBestRectangleWithGrid(grid_size);\n            if (score > best_score) {\n                best_score = score;\n                best_x1 = x1;\n                best_y1 = y1;\n                best_x2 = x2;\n                best_y2 = y2;\n            }\n        }\n        \n        // Fine-tune the best rectangle\n        optimizeRectangle(best_x1, best_y1, best_x2, best_y2);\n        \n        // Output rectangle\n        cout << \"4\\n\";\n        cout << best_x1 << \" \" << best_y1 << \"\\n\";\n        cout << best_x2 << \" \" << best_y1 << \"\\n\";\n        cout << best_x2 << \" \" << best_y2 << \"\\n\";\n        cout << best_x1 << \" \" << best_y2 << \"\\n\";\n    }\n    \nprivate:\n    tuple<int, int, int, int, int> findBestRectangleWithGrid(int grid_size) {\n        int cell_size = (MAX_COORD + grid_size - 1) / grid_size;\n        \n        // Build grid with scores\n        vector<vector<int>> grid(grid_size, vector<int>(grid_size, 0));\n        \n        for (const auto& p : mackerels) {\n            int gx = min(p.x / cell_size, grid_size - 1);\n            int gy = min(p.y / cell_size, grid_size - 1);\n            grid[gx][gy]++;\n        }\n        \n        for (const auto& p : sardines) {\n            int gx = min(p.x / cell_size, grid_size - 1);\n            int gy = min(p.y / cell_size, grid_size - 1);\n            grid[gx][gy]--;\n        }\n        \n        // Apply 2D Kadane's algorithm\n        int best_score = 0;\n        int best_x1 = 0, best_y1 = 0, best_x2 = 10000, best_y2 = 10000;\n        \n        // Try all possible left boundaries\n        for (int left = 0; left < grid_size; left++) {\n            vector<int> temp(grid_size, 0);\n            \n            // Try all possible right boundaries\n            for (int right = left; right < grid_size; right++) {\n                // Check if width would be too large\n                int width = (right - left + 1) * cell_size;\n                if (width > 200000) break;\n                \n                // Add current column to temp array\n                for (int i = 0; i < grid_size; i++) {\n                    temp[i] += grid[right][i];\n                }\n                \n                // Apply 1D Kadane on temp array\n                int current_sum = 0;\n                int max_sum = 0;\n                int start = 0, end = -1;\n                int temp_start = 0;\n                \n                for (int i = 0; i < grid_size; i++) {\n                    current_sum += temp[i];\n                    \n                    // Check if height would be too large\n                    int height = (i - temp_start + 1) * cell_size;\n                    if (height > 200000) {\n                        // Reset and start from current position\n                        current_sum = temp[i];\n                        temp_start = i;\n                    }\n                    \n                    if (current_sum > max_sum) {\n                        max_sum = current_sum;\n                        start = temp_start;\n                        end = i;\n                    }\n                    \n                    if (current_sum < 0) {\n                        current_sum = 0;\n                        temp_start = i + 1;\n                    }\n                }\n                \n                // Update best rectangle if this one is better\n                if (max_sum > best_score) {\n                    best_score = max_sum;\n                    best_x1 = left * cell_size;\n                    best_y1 = start * cell_size;\n                    best_x2 = min((right + 1) * cell_size, MAX_COORD);\n                    best_y2 = min((end + 1) * cell_size, MAX_COORD);\n                }\n            }\n        }\n        \n        return {best_x1, best_y1, best_x2, best_y2, best_score};\n    }\n    \n    void optimizeRectangle(int& x1, int& y1, int& x2, int& y2) {\n        // Calculate score efficiently\n        auto calcScore = [&](int rx1, int ry1, int rx2, int ry2) {\n            int score = 0;\n            for (const auto& p : mackerels) {\n                if (p.x >= rx1 && p.x <= rx2 && p.y >= ry1 && p.y <= ry2) {\n                    score++;\n                }\n            }\n            for (const auto& p : sardines) {\n                if (p.x >= rx1 && p.x <= rx2 && p.y >= ry1 && p.y <= ry2) {\n                    score--;\n                }\n            }\n            return score;\n        };\n        \n        int current_score = calcScore(x1, y1, x2, y2);\n        \n        // Multi-scale optimization\n        vector<int> scales = {5000, 2000, 1000, 500, 100, 50, 10, 1};\n        \n        for (int scale : scales) {\n            bool improved = true;\n            \n            while (improved) {\n                improved = false;\n                \n                // Try adjusting each boundary\n                // Adjust x1\n                for (int delta : {-scale, scale}) {\n                    int new_x1 = x1 + delta;\n                    if (new_x1 >= 0 && new_x1 < x2) {\n                        int new_score = calcScore(new_x1, y1, x2, y2);\n                        if (new_score > current_score) {\n                            x1 = new_x1;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                }\n                \n                // Adjust x2\n                for (int delta : {-scale, scale}) {\n                    int new_x2 = x2 + delta;\n                    if (new_x2 > x1 && new_x2 <= MAX_COORD &&\n                        2 * ((new_x2 - x1) + (y2 - y1)) <= 400000) {\n                        int new_score = calcScore(x1, y1, new_x2, y2);\n                        if (new_score > current_score) {\n                            x2 = new_x2;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                }\n                \n                // Adjust y1\n                for (int delta : {-scale, scale}) {\n                    int new_y1 = y1 + delta;\n                    if (new_y1 >= 0 && new_y1 < y2) {\n                        int new_score = calcScore(x1, new_y1, x2, y2);\n                        if (new_score > current_score) {\n                            y1 = new_y1;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                }\n                \n                // Adjust y2\n                for (int delta : {-scale, scale}) {\n                    int new_y2 = y2 + delta;\n                    if (new_y2 > y1 && new_y2 <= MAX_COORD &&\n                        2 * ((x2 - x1) + (new_y2 - y1)) <= 400000) {\n                        int new_score = calcScore(x1, y1, x2, new_y2);\n                        if (new_score > current_score) {\n                            y2 = new_y2;\n                            current_score = new_score;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Final fine-tuning with coordinate-level precision\n        // Use actual fish positions as potential boundaries\n        set<int> x_coords, y_coords;\n        \n        for (const auto& p : mackerels) {\n            if (abs(p.x - x1) <= 100) x_coords.insert(p.x);\n            if (abs(p.x - x2) <= 100) x_coords.insert(p.x);\n            if (abs(p.y - y1) <= 100) y_coords.insert(p.y);\n            if (abs(p.y - y2) <= 100) y_coords.insert(p.y);\n        }\n        \n        for (const auto& p : sardines) {\n            if (abs(p.x - x1) <= 100) x_coords.insert(p.x);\n            if (abs(p.x - x2) <= 100) x_coords.insert(p.x);\n            if (abs(p.y - y1) <= 100) y_coords.insert(p.y);\n            if (abs(p.y - y2) <= 100) y_coords.insert(p.y);\n        }\n        \n        // Try these specific coordinates as boundaries\n        for (int new_x1 : x_coords) {\n            if (new_x1 >= max(0, x1 - 100) && new_x1 <= min(x1 + 100, x2 - 1)) {\n                int new_score = calcScore(new_x1, y1, x2, y2);\n                if (new_score > current_score) {\n                    x1 = new_x1;\n                    current_score = new_score;\n                }\n            }\n        }\n        \n        for (int new_x2 : x_coords) {\n            if (new_x2 >= max(x1 + 1, x2 - 100) && new_x2 <= min(MAX_COORD, x2 + 100) &&\n                2 * ((new_x2 - x1) + (y2 - y1)) <= 400000) {\n                int new_score = calcScore(x1, y1, new_x2, y2);\n                if (new_score > current_score) {\n                    x2 = new_x2;\n                    current_score = new_score;\n                }\n            }\n        }\n        \n        for (int new_y1 : y_coords) {\n            if (new_y1 >= max(0, y1 - 100) && new_y1 <= min(y1 + 100, y2 - 1)) {\n                int new_score = calcScore(x1, new_y1, x2, y2);\n                if (new_score > current_score) {\n                    y1 = new_y1;\n                    current_score = new_score;\n                }\n            }\n        }\n        \n        for (int new_y2 : y_coords) {\n            if (new_y2 >= max(y1 + 1, y2 - 100) && new_y2 <= min(MAX_COORD, y2 + 100) &&\n                2 * ((x2 - x1) + (new_y2 - y1)) <= 400000) {\n                int new_score = calcScore(x1, y1, x2, new_y2);\n                if (new_score > current_score) {\n                    y2 = new_y2;\n                    current_score = new_score;\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    double obs_w, obs_h;\n    double est_w, est_h;\n    double sum_error_w, sum_error_h;\n    int count;\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nstruct PlacedRect {\n    int x, y, w, h;\n};\n\nclass Packer {\nprivate:\n    int N, T;\n    double sigma;\n    vector<Rectangle> rects;\n    double best_score = 1e18;\n    vector<Placement> best_placement;\n    vector<double> scores;\n    \n    // Simulate placement and calculate bounding box\n    pair<vector<PlacedRect>, pair<int,int>> simulatePlacement(const vector<Placement>& placements) {\n        vector<PlacedRect> placed;\n        \n        for (const auto& p : placements) {\n            int w = p.r ? (int)round(rects[p.p].est_h) : (int)round(rects[p.p].est_w);\n            int h = p.r ? (int)round(rects[p.p].est_w) : (int)round(rects[p.p].est_h);\n            \n            int x = 0, y = 0;\n            \n            if (p.d == 'U') {\n                if (p.b >= 0) {\n                    x = placed[p.b].x + placed[p.b].w;\n                }\n                for (const auto& rect : placed) {\n                    if (x < rect.x + rect.w && x + w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n            } else {\n                if (p.b >= 0) {\n                    y = placed[p.b].y + placed[p.b].h;\n                }\n                for (const auto& rect : placed) {\n                    if (y < rect.y + rect.h && y + h > rect.y) {\n                        x = max(x, rect.x + rect.w);\n                    }\n                }\n            }\n            \n            placed.push_back({x, y, w, h});\n        }\n        \n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.w);\n            maxY = max(maxY, rect.y + rect.h);\n        }\n        \n        return {placed, {maxX, maxY}};\n    }\n    \n    // Efficient bottom-left packing\n    vector<Placement> createBottomLeftPacking(const vector<bool>& rotations) {\n        vector<Placement> result;\n        vector<PlacedRect> placed;\n        \n        for (int i = 0; i < N; i++) {\n            int w = rotations[i] ? (int)round(rects[i].est_h) : (int)round(rects[i].est_w);\n            int h = rotations[i] ? (int)round(rects[i].est_w) : (int)round(rects[i].est_h);\n            \n            if (i == 0) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n                placed.push_back({0, 0, w, h});\n                continue;\n            }\n            \n            // Find position with minimum y, then minimum x\n            int bestX = INT_MAX, bestY = INT_MAX;\n            int bestRef = -1;\n            char bestDir = 'U';\n            \n            // Try placing at x=0\n            int y = 0;\n            for (const auto& rect : placed) {\n                if (w > rect.x) {\n                    y = max(y, rect.y + rect.h);\n                }\n            }\n            if (y < bestY || (y == bestY && 0 < bestX)) {\n                bestY = y;\n                bestX = 0;\n                bestRef = -1;\n                bestDir = 'U';\n            }\n            \n            // Try right of each rectangle\n            for (int j = 0; j < (int)placed.size(); j++) {\n                int x = placed[j].x + placed[j].w;\n                y = 0;\n                for (const auto& rect : placed) {\n                    if (x < rect.x + rect.w && x + w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n                if (y < bestY || (y == bestY && x < bestX)) {\n                    bestY = y;\n                    bestX = x;\n                    bestRef = j;\n                    bestDir = 'U';\n                }\n            }\n            \n            // Also try above rectangles for better packing\n            for (int j = 0; j < min(3, (int)placed.size()); j++) {\n                int x = 0;\n                y = placed[j].y + placed[j].h;\n                for (const auto& rect : placed) {\n                    if (y < rect.y + rect.h && y + h > rect.y) {\n                        x = max(x, rect.x + rect.w);\n                    }\n                }\n                if (y < bestY || (y == bestY && x < bestX)) {\n                    bestY = y;\n                    bestX = x;\n                    bestRef = j;\n                    bestDir = 'L';\n                }\n            }\n            \n            result.push_back({i, rotations[i] ? 1 : 0, bestRef, bestDir});\n            placed.push_back({bestX, bestY, w, h});\n        }\n        \n        return result;\n    }\n    \n    // Shelf packing with adaptive shelf height\n    vector<Placement> createShelfPacking(const vector<bool>& rotations, int items_per_shelf) {\n        vector<Placement> result;\n        int shelf_start = -1;\n        int items_in_shelf = 0;\n        \n        for (int i = 0; i < N; i++) {\n            if (items_in_shelf == 0) {\n                // Start new shelf\n                if (i == 0) {\n                    result.push_back({i, rotations[i] ? 1 : 0, -1, 'L'});\n                } else {\n                    result.push_back({i, rotations[i] ? 1 : 0, shelf_start, 'L'});\n                }\n                shelf_start = i;\n                items_in_shelf = 1;\n            } else if (items_in_shelf < items_per_shelf) {\n                // Add to current shelf\n                result.push_back({i, rotations[i] ? 1 : 0, i-1, 'U'});\n                items_in_shelf++;\n            } else {\n                // Start new shelf\n                result.push_back({i, rotations[i] ? 1 : 0, shelf_start, 'L'});\n                shelf_start = i;\n                items_in_shelf = 1;\n            }\n        }\n        \n        return result;\n    }\n    \n    // Grid packing\n    vector<Placement> createGridPacking(const vector<bool>& rotations, int cols) {\n        vector<Placement> result;\n        \n        for (int i = 0; i < N; i++) {\n            if (i == 0) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n            } else if (i % cols == 0) {\n                // New row\n                result.push_back({i, rotations[i] ? 1 : 0, i - cols, 'L'});\n            } else {\n                // Same row\n                result.push_back({i, rotations[i] ? 1 : 0, i - 1, 'U'});\n            }\n        }\n        \n        return result;\n    }\n    \n    pair<int, int> query(const vector<Placement>& placements) {\n        cout << placements.size() << endl;\n        for (const auto& p : placements) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << endl;\n        }\n        cout.flush();\n        \n        int W, H;\n        cin >> W >> H;\n        scores.push_back(W + H);\n        return {W, H};\n    }\n    \n    void updateEstimates(int W_measured, int H_measured, const vector<Placement>& placements) {\n        // Calculate expected bounding box based on current estimates\n        auto [placed, expected] = simulatePlacement(placements);\n        int W_expected = expected.first;\n        int H_expected = expected.second;\n        \n        // Calculate error\n        double error_W = (double)W_measured / W_expected;\n        double error_H = (double)H_measured / H_expected;\n        double avg_error = sqrt(error_W * error_H);\n        \n        // Update all rectangles based on error pattern\n        for (int i = 0; i < N; i++) {\n            rects[i].count++;\n            \n            // Adaptive learning rate\n            double lr = 0.2 / sqrt(rects[i].count);\n            \n            // Update estimates toward observed values scaled by error\n            if (avg_error > 0.5 && avg_error < 2.0) {  // Reasonable error range\n                rects[i].est_w = rects[i].est_w * (1 - lr) + rects[i].obs_w * avg_error * lr;\n                rects[i].est_h = rects[i].est_h * (1 - lr) + rects[i].obs_h * avg_error * lr;\n            } else {\n                // Fallback to simple averaging\n                rects[i].est_w = rects[i].est_w * 0.95 + rects[i].obs_w * 0.05;\n                rects[i].est_h = rects[i].est_h * 0.95 + rects[i].obs_h * 0.05;\n            }\n            \n            // Keep estimates reasonable\n            rects[i].est_w = max(rects[i].obs_w * 0.5, min(rects[i].est_w, rects[i].obs_w * 1.5));\n            rects[i].est_h = max(rects[i].obs_h * 0.5, min(rects[i].est_h, rects[i].obs_h * 1.5));\n        }\n    }\n    \n    vector<bool> optimizeRotations(int strategy, double aspect_ratio = 0) {\n        vector<bool> rotations(N);\n        \n        for (int i = 0; i < N; i++) {\n            double w = rects[i].est_w;\n            double h = rects[i].est_h;\n            \n            switch (strategy) {\n                case 0:  // Minimize height\n                    rotations[i] = (w > h);\n                    break;\n                case 1:  // Minimize width\n                    rotations[i] = (h > w);\n                    break;\n                case 2:  // Target aspect ratio\n                    if (aspect_ratio > 0) {\n                        double current = w / h;\n                        double rotated = h / w;\n                        rotations[i] = (abs(rotated - aspect_ratio) < abs(current - aspect_ratio));\n                    } else {\n                        rotations[i] = (w > h * 1.2);\n                    }\n                    break;\n                case 3:  // Uniform orientation\n                    rotations[i] = (h > w * 1.1);\n                    break;\n                default:  // Mixed\n                    rotations[i] = ((i + strategy) % 3 == 0) ? (w > h) : (h > w);\n            }\n        }\n        \n        return rotations;\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> T >> sigma;\n        rects.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> rects[i].obs_w >> rects[i].obs_h;\n            rects[i].est_w = rects[i].obs_w;\n            rects[i].est_h = rects[i].obs_h;\n            rects[i].count = 0;\n        }\n        \n        // Adjust initial estimates based on sigma\n        double noise_factor = 1.0 - min(0.3, sigma / 30000.0);\n        for (int i = 0; i < N; i++) {\n            rects[i].est_w *= noise_factor;\n            rects[i].est_h *= noise_factor;\n        }\n        \n        for (int turn = 0; turn < T; turn++) {\n            vector<Placement> placements;\n            \n            // Progressive strategy\n            if (turn < T / 3) {\n                // Exploration phase\n                int strategy = turn % 6;\n                auto rotations = optimizeRotations(turn % 4);\n                \n                if (strategy < 3) {\n                    placements = createBottomLeftPacking(rotations);\n                } else if (strategy == 3) {\n                    placements = createShelfPacking(rotations, max(3, N/5));\n                } else if (strategy == 4) {\n                    placements = createShelfPacking(rotations, max(4, N/4));\n                } else {\n                    placements = createGridPacking(rotations, (int)sqrt(N));\n                }\n            } else if (turn < 2 * T / 3) {\n                // Refinement phase\n                auto rotations = optimizeRotations(0);  // Usually minimize height\n                if (turn % 2 == 0) {\n                    placements = createBottomLeftPacking(rotations);\n                } else {\n                    placements = createShelfPacking(rotations, max(4, N/4));\n                }\n            } else {\n                // Exploitation phase\n                if (best_placement.size() > 0 && turn % 3 == 0) {\n                    placements = best_placement;\n                } else {\n                    auto rotations = optimizeRotations(0);\n                    placements = createBottomLeftPacking(rotations);\n                }\n            }\n            \n            auto [W, H] = query(placements);\n            \n            // Track best\n            double score = W + H;\n            if (score < best_score) {\n                best_score = score;\n                best_placement = placements;\n            }\n            \n            updateEstimates(W, H, placements);\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.solve();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass ForestOptimizer {\n    int N, M, H;\n    vector<int> beauty;\n    vector<vector<int>> adj;\n    \n    long long calculateScore(const vector<int>& parent) {\n        long long score = 1;\n        for (int i = 0; i < N; i++) {\n            int depth = 0;\n            int curr = i;\n            while (parent[curr] != -1) {\n                depth++;\n                curr = parent[curr];\n                if (depth > H) return -1; // Invalid configuration\n            }\n            score += (long long)(depth + 1) * beauty[i];\n        }\n        return score;\n    }\n    \n    int getDepth(int v, const vector<int>& parent) {\n        int depth = 0;\n        int curr = v;\n        while (parent[curr] != -1) {\n            depth++;\n            curr = parent[curr];\n        }\n        return depth;\n    }\n    \n    int getSubtreeHeight(int v, const vector<int>& parent) {\n        int maxHeight = 0;\n        for (int u = 0; u < N; u++) {\n            if (parent[u] == v) {\n                maxHeight = max(maxHeight, 1 + getSubtreeHeight(u, parent));\n            }\n        }\n        return maxHeight;\n    }\n    \n    long long evaluateSubtree(int root, const vector<bool>& used, int maxDepth) {\n        if (used[root]) return 0;\n        \n        long long score = beauty[root];\n        queue<pair<int, int>> q;\n        q.push({root, 0});\n        vector<bool> visited = used;\n        visited[root] = true;\n        \n        while (!q.empty()) {\n            auto [u, depth] = q.front();\n            q.pop();\n            \n            if (depth >= maxDepth) continue;\n            \n            vector<pair<int, int>> neighbors;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    neighbors.push_back({beauty[v], v});\n                }\n            }\n            sort(neighbors.rbegin(), neighbors.rend());\n            \n            for (auto [b, v] : neighbors) {\n                visited[v] = true;\n                score += (long long)(depth + 2) * b;\n                q.push({v, depth + 1});\n            }\n        }\n        \n        return score;\n    }\n    \n    vector<int> buildOptimalForest() {\n        vector<int> parent(N, -1);\n        vector<bool> used(N, false);\n        \n        while (true) {\n            int bestRoot = -1;\n            long long bestScore = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (!used[i]) {\n                    long long score = evaluateSubtree(i, used, H);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestRoot = i;\n                    }\n                }\n            }\n            \n            if (bestRoot == -1) break;\n            \n            used[bestRoot] = true;\n            queue<pair<int, int>> q;\n            q.push({bestRoot, 0});\n            \n            while (!q.empty()) {\n                auto [u, depth] = q.front();\n                q.pop();\n                \n                if (depth >= H) continue;\n                \n                vector<pair<int, int>> neighbors;\n                for (int v : adj[u]) {\n                    if (!used[v]) {\n                        neighbors.push_back({beauty[v], v});\n                    }\n                }\n                sort(neighbors.rbegin(), neighbors.rend());\n                \n                for (auto [_, v] : neighbors) {\n                    parent[v] = u;\n                    used[v] = true;\n                    q.push({v, depth + 1});\n                }\n            }\n        }\n        \n        return parent;\n    }\n    \n    vector<int> buildGreedyForest() {\n        vector<int> parent(N, -1);\n        vector<bool> visited(N, false);\n        \n        vector<pair<int, int>> nodes;\n        for (int i = 0; i < N; i++) {\n            nodes.push_back({beauty[i], i});\n        }\n        sort(nodes.rbegin(), nodes.rend());\n        \n        for (auto [_, root] : nodes) {\n            if (visited[root]) continue;\n            \n            visited[root] = true;\n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            \n            while (!q.empty()) {\n                auto [u, depth] = q.front();\n                q.pop();\n                \n                if (depth >= H) continue;\n                \n                vector<pair<int, int>> neighbors;\n                for (int v : adj[u]) {\n                    if (!visited[v]) {\n                        neighbors.push_back({beauty[v], v});\n                    }\n                }\n                sort(neighbors.rbegin(), neighbors.rend());\n                \n                for (auto [_, v] : neighbors) {\n                    parent[v] = u;\n                    visited[v] = true;\n                    q.push({v, depth + 1});\n                }\n            }\n        }\n        \n        return parent;\n    }\n    \n    vector<int> improveWithLocalSearch(vector<int> parent, int iterations = 200) {\n        long long currentScore = calculateScore(parent);\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            bool improved = false;\n            \n            // Only move leaf nodes to avoid depth constraint violations\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                \n                // Check if v is a leaf\n                bool isLeaf = true;\n                for (int u = 0; u < N; u++) {\n                    if (parent[u] == v) {\n                        isLeaf = false;\n                        break;\n                    }\n                }\n                \n                if (!isLeaf) continue; // Only move leaves\n                \n                int oldParent = parent[v];\n                int oldDepth = getDepth(v, parent);\n                long long oldContrib = (long long)(oldDepth + 1) * beauty[v];\n                \n                int bestParent = oldParent;\n                long long bestImprovement = 0;\n                \n                // Try each neighbor as new parent\n                for (int newParent : adj[v]) {\n                    if (newParent == oldParent) continue;\n                    \n                    // Check for cycle\n                    bool hasCycle = false;\n                    int curr = newParent;\n                    int steps = 0;\n                    while (parent[curr] != -1 && steps <= H + 1) {\n                        if (curr == v) {\n                            hasCycle = true;\n                            break;\n                        }\n                        curr = parent[curr];\n                        steps++;\n                    }\n                    if (hasCycle) continue;\n                    \n                    // Check depth constraint\n                    int newDepth = getDepth(newParent, parent) + 1;\n                    if (newDepth > H) continue;\n                    \n                    long long newContrib = (long long)(newDepth + 1) * beauty[v];\n                    long long improvement = newContrib - oldContrib;\n                    \n                    if (improvement > bestImprovement) {\n                        bestImprovement = improvement;\n                        bestParent = newParent;\n                    }\n                }\n                \n                // Try making v a root if it has high beauty\n                if (beauty[v] > 80) {\n                    long long newContrib = beauty[v];\n                    long long improvement = newContrib - oldContrib;\n                    if (improvement > bestImprovement) {\n                        bestImprovement = improvement;\n                        bestParent = -1;\n                    }\n                }\n                \n                if (bestParent != oldParent) {\n                    parent[v] = bestParent;\n                    currentScore += bestImprovement;\n                    improved = true;\n                }\n            }\n            \n            if (!improved && iter > 50) break;\n        }\n        \n        return parent;\n    }\n    \npublic:\n    ForestOptimizer(int n, int m, int h) : N(n), M(m), H(h) {\n        beauty.resize(N);\n        adj.resize(N);\n    }\n    \n    void input() {\n        for (int i = 0; i < N; i++) {\n            cin >> beauty[i];\n        }\n        \n        for (int i = 0; i < M; i++) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        \n        // Skip coordinates\n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n    \n    vector<int> solve() {\n        vector<int> bestParent;\n        long long bestScore = 0;\n        \n        // Strategy 1: Optimal with subtree evaluation\n        vector<int> parent1 = buildOptimalForest();\n        parent1 = improveWithLocalSearch(parent1);\n        long long score1 = calculateScore(parent1);\n        if (score1 > 0 && score1 > bestScore) {\n            bestScore = score1;\n            bestParent = parent1;\n        }\n        \n        // Strategy 2: Pure greedy\n        vector<int> parent2 = buildGreedyForest();\n        parent2 = improveWithLocalSearch(parent2);\n        long long score2 = calculateScore(parent2);\n        if (score2 > 0 && score2 > bestScore) {\n            bestScore = score2;\n            bestParent = parent2;\n        }\n        \n        // Verify the solution\n        for (int i = 0; i < N; i++) {\n            int depth = getDepth(i, bestParent);\n            if (depth > H) {\n                // Fallback to simple greedy if something went wrong\n                return buildGreedyForest();\n            }\n        }\n        \n        return bestParent;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    ForestOptimizer optimizer(N, M, H);\n    optimizer.input();\n    \n    vector<int> result = optimizer.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct OniInfo {\n    int r, c;\n    vector<pair<char, int>> removal_options; // (direction, cost)\n};\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> operations;\n    \n    while (true) {\n        // First, identify all Oni and their removal options\n        vector<OniInfo> oni_list;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                OniInfo oni;\n                oni.r = i;\n                oni.c = j;\n                \n                // Check UP\n                bool up_safe = true;\n                for (int k = 0; k < i; k++) {\n                    if (board[k][j] == 'o') {\n                        up_safe = false;\n                        break;\n                    }\n                }\n                if (up_safe) {\n                    oni.removal_options.push_back({'U', i + 1});\n                }\n                \n                // Check DOWN\n                bool down_safe = true;\n                for (int k = i + 1; k < N; k++) {\n                    if (board[k][j] == 'o') {\n                        down_safe = false;\n                        break;\n                    }\n                }\n                if (down_safe) {\n                    oni.removal_options.push_back({'D', N - i});\n                }\n                \n                // Check LEFT\n                bool left_safe = true;\n                for (int k = 0; k < j; k++) {\n                    if (board[i][k] == 'o') {\n                        left_safe = false;\n                        break;\n                    }\n                }\n                if (left_safe) {\n                    oni.removal_options.push_back({'L', j + 1});\n                }\n                \n                // Check RIGHT\n                bool right_safe = true;\n                for (int k = j + 1; k < N; k++) {\n                    if (board[i][k] == 'o') {\n                        right_safe = false;\n                        break;\n                    }\n                }\n                if (right_safe) {\n                    oni.removal_options.push_back({'R', N - j});\n                }\n                \n                oni_list.push_back(oni);\n            }\n        }\n        \n        if (oni_list.empty()) break;\n        \n        // Find the best batch operation\n        double best_score = 1e9;\n        char best_dir = ' ';\n        int best_line = -1;\n        int best_shifts = 0;\n        vector<pair<int,int>> best_targets;\n        \n        // Try each possible line and direction\n        for (int line = 0; line < N; line++) {\n            // UP direction\n            vector<pair<int,int>> up_targets;\n            int max_shift = 0;\n            \n            for (const auto& oni : oni_list) {\n                if (oni.c != line) continue;\n                for (auto [dir, cost] : oni.removal_options) {\n                    if (dir == 'U') {\n                        up_targets.push_back({oni.r, oni.c});\n                        max_shift = max(max_shift, cost);\n                        break;\n                    }\n                }\n            }\n            \n            if (!up_targets.empty()) {\n                // Calculate score with refined heuristics\n                double score = (double)(2 * max_shift) / up_targets.size();\n                \n                // Heavy bonus for large batches\n                if (up_targets.size() >= 4) score *= 0.5;\n                else if (up_targets.size() == 3) score *= 0.65;\n                else if (up_targets.size() == 2) score *= 0.8;\n                \n                // Bonus if we're removing Oni that have limited options\n                int limited_options_count = 0;\n                for (auto [r, c] : up_targets) {\n                    for (const auto& oni : oni_list) {\n                        if (oni.r == r && oni.c == c && oni.removal_options.size() == 1) {\n                            limited_options_count++;\n                        }\n                    }\n                }\n                score *= (1.0 - 0.05 * limited_options_count);\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'U';\n                    best_line = line;\n                    best_shifts = max_shift;\n                    best_targets = up_targets;\n                }\n            }\n            \n            // DOWN direction\n            vector<pair<int,int>> down_targets;\n            max_shift = 0;\n            \n            for (const auto& oni : oni_list) {\n                if (oni.c != line) continue;\n                for (auto [dir, cost] : oni.removal_options) {\n                    if (dir == 'D') {\n                        down_targets.push_back({oni.r, oni.c});\n                        max_shift = max(max_shift, cost);\n                        break;\n                    }\n                }\n            }\n            \n            if (!down_targets.empty()) {\n                double score = (double)(2 * max_shift) / down_targets.size();\n                \n                if (down_targets.size() >= 4) score *= 0.5;\n                else if (down_targets.size() == 3) score *= 0.65;\n                else if (down_targets.size() == 2) score *= 0.8;\n                \n                int limited_options_count = 0;\n                for (auto [r, c] : down_targets) {\n                    for (const auto& oni : oni_list) {\n                        if (oni.r == r && oni.c == c && oni.removal_options.size() == 1) {\n                            limited_options_count++;\n                        }\n                    }\n                }\n                score *= (1.0 - 0.05 * limited_options_count);\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'D';\n                    best_line = line;\n                    best_shifts = max_shift;\n                    best_targets = down_targets;\n                }\n            }\n            \n            // LEFT direction\n            vector<pair<int,int>> left_targets;\n            max_shift = 0;\n            \n            for (const auto& oni : oni_list) {\n                if (oni.r != line) continue;\n                for (auto [dir, cost] : oni.removal_options) {\n                    if (dir == 'L') {\n                        left_targets.push_back({oni.r, oni.c});\n                        max_shift = max(max_shift, cost);\n                        break;\n                    }\n                }\n            }\n            \n            if (!left_targets.empty()) {\n                double score = (double)(2 * max_shift) / left_targets.size();\n                \n                if (left_targets.size() >= 4) score *= 0.5;\n                else if (left_targets.size() == 3) score *= 0.65;\n                else if (left_targets.size() == 2) score *= 0.8;\n                \n                int limited_options_count = 0;\n                for (auto [r, c] : left_targets) {\n                    for (const auto& oni : oni_list) {\n                        if (oni.r == r && oni.c == c && oni.removal_options.size() == 1) {\n                            limited_options_count++;\n                        }\n                    }\n                }\n                score *= (1.0 - 0.05 * limited_options_count);\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'L';\n                    best_line = line;\n                    best_shifts = max_shift;\n                    best_targets = left_targets;\n                }\n            }\n            \n            // RIGHT direction\n            vector<pair<int,int>> right_targets;\n            max_shift = 0;\n            \n            for (const auto& oni : oni_list) {\n                if (oni.r != line) continue;\n                for (auto [dir, cost] : oni.removal_options) {\n                    if (dir == 'R') {\n                        right_targets.push_back({oni.r, oni.c});\n                        max_shift = max(max_shift, cost);\n                        break;\n                    }\n                }\n            }\n            \n            if (!right_targets.empty()) {\n                double score = (double)(2 * max_shift) / right_targets.size();\n                \n                if (right_targets.size() >= 4) score *= 0.5;\n                else if (right_targets.size() == 3) score *= 0.65;\n                else if (right_targets.size() == 2) score *= 0.8;\n                \n                int limited_options_count = 0;\n                for (auto [r, c] : right_targets) {\n                    for (const auto& oni : oni_list) {\n                        if (oni.r == r && oni.c == c && oni.removal_options.size() == 1) {\n                            limited_options_count++;\n                        }\n                    }\n                }\n                score *= (1.0 - 0.05 * limited_options_count);\n                \n                if (score < best_score) {\n                    best_score = score;\n                    best_dir = 'R';\n                    best_line = line;\n                    best_shifts = max_shift;\n                    best_targets = right_targets;\n                }\n            }\n        }\n        \n        // Execute the best batch\n        for (int t = 0; t < best_shifts; t++) {\n            operations.push_back({best_dir, best_line});\n        }\n        \n        char reverse = best_dir;\n        if (reverse == 'U') reverse = 'D';\n        else if (reverse == 'D') reverse = 'U';\n        else if (reverse == 'L') reverse = 'R';\n        else if (reverse == 'R') reverse = 'L';\n        \n        for (int t = 0; t < best_shifts; t++) {\n            operations.push_back({reverse, best_line});\n        }\n        \n        // Update board\n        for (auto [i, j] : best_targets) {\n            board[i][j] = '.';\n        }\n    }\n    \n    // Output\n    for (auto [dir, pos] : operations) {\n        cout << dir << \" \" << pos << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N), b(N);\n    mt19937 rng(42);\n    \n    // Initialize based on target distribution\n    vector<double> prob(N);\n    for (int i = 0; i < N; i++) {\n        prob[i] = max(1, T[i]);\n    }\n    \n    discrete_distribution<int> dist(prob.begin(), prob.end());\n    for (int i = 0; i < N; i++) {\n        a[i] = dist(rng);\n        b[i] = dist(rng);\n    }\n    \n    // Fast simulation\n    auto simulate = [&](int maxSteps) -> vector<int> {\n        vector<int> count(N, 0);\n        int curr = 0;\n        count[0]++;\n        \n        for (int step = 2; step <= maxSteps; step++) {\n            if (count[curr] % 2 == 1) {\n                curr = a[curr];\n            } else {\n                curr = b[curr];\n            }\n            count[curr]++;\n        }\n        \n        return count;\n    };\n    \n    // Calculate error\n    auto calcError = [&](const vector<int>& counts, int simLen) -> int {\n        double scale = (double)L / simLen;\n        int error = 0;\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            error += abs(projected - T[i]);\n        }\n        return error;\n    };\n    \n    // Get individual errors\n    auto getErrors = [&](const vector<int>& counts, int simLen) -> vector<int> {\n        double scale = (double)L / simLen;\n        vector<int> errors(N);\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            errors[i] = projected - T[i];\n        }\n        return errors;\n    };\n    \n    // Store best solution\n    vector<int> bestA = a, bestB = b;\n    int bestError = INT_MAX;\n    \n    // Multi-stage optimization with increasing accuracy\n    vector<int> stages = {20000, 40000, 60000, 80000, 100000};\n    \n    for (int stage = 0; stage < (int)stages.size(); stage++) {\n        int simLen = min(stages[stage], L);\n        \n        // Initial evaluation\n        auto counts = simulate(simLen);\n        int currentError = calcError(counts, simLen);\n        \n        if (currentError < bestError) {\n            bestError = currentError;\n            bestA = a;\n            bestB = b;\n        }\n        \n        // Optimization iterations\n        int numIters = 400 - stage * 60; // Fewer iterations for longer simulations\n        \n        for (int iter = 0; iter < numIters; iter++) {\n            // Get current errors\n            counts = simulate(simLen);\n            auto errors = getErrors(counts, simLen);\n            currentError = calcError(counts, simLen);\n            \n            // Find nodes with largest absolute errors\n            vector<pair<int, int>> absErrors;\n            for (int i = 0; i < N; i++) {\n                absErrors.push_back({abs(errors[i]), i});\n            }\n            sort(absErrors.rbegin(), absErrors.rend());\n            \n            // Pick one of the top error nodes\n            int pickIdx = min(iter % 10, (int)absErrors.size() - 1);\n            int targetNode = absErrors[pickIdx].second;\n            \n            // Save current state\n            int oldA = a[targetNode];\n            int oldB = b[targetNode];\n            \n            // Modification strategy\n            if (errors[targetNode] > 0) {\n                // This node gets too many visits\n                // Find nodes that need more visits\n                int bestTarget = -1;\n                int maxDeficit = 0;\n                for (int i = 0; i < N; i++) {\n                    if (-errors[i] > maxDeficit) {\n                        maxDeficit = -errors[i];\n                        bestTarget = i;\n                    }\n                }\n                \n                if (bestTarget != -1) {\n                    // Redirect to deficit node\n                    if (iter % 2 == 0) {\n                        a[targetNode] = bestTarget;\n                    } else {\n                        b[targetNode] = bestTarget;\n                    }\n                    \n                    // Also make a surplus node point to deficit\n                    for (int i = 0; i < N; i++) {\n                        if (i != targetNode && errors[i] > 10) {\n                            if (rng() % 3 == 0) {\n                                if (rng() % 2 == 0) a[i] = bestTarget;\n                                else b[i] = bestTarget;\n                                break;\n                            }\n                        }\n                    }\n                }\n            } else if (errors[targetNode] < 0) {\n                // This node needs more visits\n                // Find nodes with excess visits\n                int bestSource = -1;\n                int maxSurplus = 0;\n                for (int i = 0; i < N; i++) {\n                    if (errors[i] > maxSurplus) {\n                        maxSurplus = errors[i];\n                        bestSource = i;\n                    }\n                }\n                \n                if (bestSource != -1) {\n                    // Make surplus node point here\n                    if (iter % 2 == 0) {\n                        a[bestSource] = targetNode;\n                    } else {\n                        b[bestSource] = targetNode;\n                    }\n                    \n                    // Also redirect targetNode to other deficit nodes\n                    for (int i = 0; i < N; i++) {\n                        if (i != targetNode && errors[i] < -10) {\n                            if (rng() % 3 == 0) {\n                                if (rng() % 2 == 0) a[targetNode] = i;\n                                else b[targetNode] = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Evaluate change\n            auto newCounts = simulate(simLen);\n            int newError = calcError(newCounts, simLen);\n            \n            if (newError < bestError) {\n                bestError = newError;\n                bestA = a;\n                bestB = b;\n            } else if (newError > currentError) {\n                // Simulated annealing\n                double temp = 200.0 * exp(-4.0 * iter / numIters);\n                double prob = exp(-(newError - currentError) / temp);\n                \n                if (uniform_real_distribution<>(0, 1)(rng) > prob) {\n                    // Revert\n                    a[targetNode] = oldA;\n                    b[targetNode] = oldB;\n                }\n            }\n            \n            // Early exit if very good\n            if (bestError < L * 0.001) break;\n        }\n        \n        // Use best solution for next stage\n        a = bestA;\n        b = bestB;\n    }\n    \n    // Final fine-tuning with longer simulation\n    int finalSimLen = min(150000, L);\n    \n    for (int finalIter = 0; finalIter < 100; finalIter++) {\n        auto counts = simulate(finalSimLen);\n        auto errors = getErrors(counts, finalSimLen);\n        int currentError = calcError(counts, finalSimLen);\n        \n        if (currentError < bestError) {\n            bestError = currentError;\n            bestA = a;\n            bestB = b;\n        }\n        \n        // Find worst error\n        int worstIdx = 0;\n        int worstError = 0;\n        for (int i = 0; i < N; i++) {\n            if (abs(errors[i]) > worstError) {\n                worstError = abs(errors[i]);\n                worstIdx = i;\n            }\n        }\n        \n        if (worstError < 2) break;\n        \n        // Single targeted change\n        if (errors[worstIdx] > 0) {\n            // Find most deficit node\n            int target = 0;\n            for (int i = 1; i < N; i++) {\n                if (errors[i] < errors[target]) {\n                    target = i;\n                }\n            }\n            \n            if (finalIter % 2 == 0) a[worstIdx] = target;\n            else b[worstIdx] = target;\n        } else {\n            // Find most surplus node\n            int source = 0;\n            for (int i = 1; i < N; i++) {\n                if (errors[i] > errors[source]) {\n                    source = i;\n                }\n            }\n            \n            if (finalIter % 2 == 0) a[source] = worstIdx;\n            else b[source] = worstIdx;\n        }\n        \n        // Check improvement\n        auto newCounts = simulate(finalSimLen);\n        int newError = calcError(newCounts, finalSimLen);\n        \n        if (newError < bestError) {\n            bestError = newError;\n            bestA = a;\n            bestB = b;\n        } else if (newError > currentError * 1.05) {\n            // Revert if significantly worse\n            a = bestA;\n            b = bestB;\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << \" \" << bestB[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n    double uncertainty;\n};\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    \n    UnionFind(int n) : parent(n), size(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (size[px] < size[py]) swap(px, py);\n        parent[py] = px;\n        size[px] += size[py];\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\ndouble dist(const City& a, const City& b) {\n    double dx = a.cx - b.cx;\n    double dy = a.cy - b.cy;\n    return sqrt(dx * dx + dy * dy);\n}\n\ndouble maxPossibleDist(const City& a, const City& b) {\n    double dx = max(abs(a.rx - b.lx), abs(a.lx - b.rx));\n    double dy = max(abs(a.ry - b.ly), abs(a.ly - b.ry));\n    return sqrt(dx * dx + dy * dy);\n}\n\nvector<pair<int, int>> query(const vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v});\n    }\n    return edges;\n}\n\n// K-means++ initialization for better initial centers\nvector<int> kMeansPlusPlus(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<int> centers;\n    vector<double> minDist(n, 1e9);\n    \n    // Choose first center randomly\n    centers.push_back(rand() % n);\n    \n    for (int i = 1; i < k; i++) {\n        // Update distances\n        for (int j = 0; j < n; j++) {\n            double d = dist(cities[j], cities[centers.back()]);\n            minDist[j] = min(minDist[j], d);\n        }\n        \n        // Choose next center with probability proportional to distance squared\n        double sum = 0;\n        for (int j = 0; j < n; j++) sum += minDist[j] * minDist[j];\n        \n        double r = (double)rand() / RAND_MAX * sum;\n        double cumSum = 0;\n        for (int j = 0; j < n; j++) {\n            cumSum += minDist[j] * minDist[j];\n            if (cumSum >= r) {\n                centers.push_back(j);\n                break;\n            }\n        }\n    }\n    \n    return centers;\n}\n\n// Balanced k-means clustering\nvector<vector<int>> balancedKMeans(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<vector<int>> clusters(k);\n    \n    // Initialize centers\n    vector<int> centerIds = kMeansPlusPlus(cities, k, targetSizes);\n    vector<pair<double, double>> centers(k);\n    for (int i = 0; i < k; i++) {\n        centers[i] = {cities[centerIds[i]].cx, cities[centerIds[i]].cy};\n    }\n    \n    // Assign cities to clusters with size constraints\n    for (int iter = 0; iter < 20; iter++) {\n        // Calculate distances to all centers\n        vector<vector<pair<double, int>>> distances(k);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < k; j++) {\n                double dx = cities[i].cx - centers[j].first;\n                double dy = cities[i].cy - centers[j].second;\n                double d = sqrt(dx * dx + dy * dy);\n                distances[j].push_back({d, i});\n            }\n        }\n        \n        // Sort by distance for each cluster\n        for (int i = 0; i < k; i++) {\n            sort(distances[i].begin(), distances[i].end());\n        }\n        \n        // Assign cities greedily with size constraints\n        clusters.assign(k, vector<int>());\n        vector<bool> assigned(n, false);\n        \n        for (int round = 0; round < n; round++) {\n            for (int c = 0; c < k; c++) {\n                if (clusters[c].size() >= targetSizes[c]) continue;\n                \n                for (auto [d, city] : distances[c]) {\n                    if (!assigned[city]) {\n                        clusters[c].push_back(city);\n                        assigned[city] = true;\n                        break;\n                    }\n                }\n                \n                if (clusters[c].size() >= targetSizes[c]) continue;\n            }\n        }\n        \n        // Update centers\n        for (int i = 0; i < k; i++) {\n            if (clusters[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : clusters[i]) {\n                cx += cities[city].cx;\n                cy += cities[city].cy;\n            }\n            centers[i] = {cx / clusters[i].size(), cy / clusters[i].size()};\n        }\n    }\n    \n    return clusters;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<City> cities(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        cities[i].uncertainty = sqrt((cities[i].rx - cities[i].lx) * (cities[i].rx - cities[i].lx) + \n                                    (cities[i].ry - cities[i].ly) * (cities[i].ry - cities[i].ly));\n    }\n    \n    // Use balanced k-means for initial grouping\n    vector<vector<int>> groups = balancedKMeans(cities, M, G);\n    \n    // Ensure exact group sizes\n    for (int i = 0; i < M; i++) {\n        while (groups[i].size() > G[i]) {\n            groups[(i + 1) % M].push_back(groups[i].back());\n            groups[i].pop_back();\n        }\n    }\n    \n    // Process each group to find MST\n    vector<vector<pair<int, int>>> groupEdges(M);\n    map<pair<int, int>, bool> knownEdges;  // Track which edges we know exactly\n    int queriesUsed = 0;\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L && queriesUsed < Q) {\n            // Query entire small group\n            auto edges = query(groups[g]);\n            groupEdges[g] = edges;\n            for (auto& e : edges) {\n                knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n            }\n            queriesUsed++;\n        } else {\n            // Smart querying for large groups\n            UnionFind uf(N);\n            set<pair<int, int>> mstEdges;\n            \n            // Priority queue for potential edges (estimated distance, u, v)\n            priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n            \n            // Add all potential edges\n            for (int i = 0; i < sz; i++) {\n                for (int j = i + 1; j < sz; j++) {\n                    double d = dist(cities[groups[g][i]], cities[groups[g][j]]);\n                    pq.push({d, groups[g][i], groups[g][j]});\n                }\n            }\n            \n            // Process edges and query when uncertain\n            while (!pq.empty() && mstEdges.size() < sz - 1) {\n                auto [d, u, v] = pq.top();\n                pq.pop();\n                \n                if (uf.connected(u, v)) continue;\n                \n                // Check if we know this edge\n                pair<int, int> edge = {min(u, v), max(u, v)};\n                \n                if (!knownEdges.count(edge) && queriesUsed < Q) {\n                    // Query a subset containing this edge and nearby cities\n                    vector<int> subset = {u, v};\n                    \n                    // Add nearby cities up to L\n                    vector<pair<double, int>> neighbors;\n                    for (int c : groups[g]) {\n                        if (c != u && c != v) {\n                            double d1 = dist(cities[u], cities[c]);\n                            double d2 = dist(cities[v], cities[c]);\n                            neighbors.push_back({min(d1, d2), c});\n                        }\n                    }\n                    sort(neighbors.begin(), neighbors.end());\n                    \n                    for (auto [d, c] : neighbors) {\n                        subset.push_back(c);\n                        if (subset.size() >= L) break;\n                    }\n                    \n                    if (subset.size() >= 2) {\n                        auto edges = query(subset);\n                        for (auto& e : edges) {\n                            knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n                            \n                            // Add to MST if it connects our components\n                            if (!uf.connected(e.first, e.second)) {\n                                uf.unite(e.first, e.second);\n                                mstEdges.insert({e.first, e.second});\n                            }\n                        }\n                        queriesUsed++;\n                    }\n                } else {\n                    // Use this edge if no cycle\n                    if (!uf.connected(u, v)) {\n                        uf.unite(u, v);\n                        mstEdges.insert({u, v});\n                    }\n                }\n            }\n            \n            // Ensure connectivity (failsafe)\n            if (mstEdges.size() < sz - 1) {\n                for (int i = 0; i < sz; i++) {\n                    for (int j = i + 1; j < sz; j++) {\n                        if (!uf.connected(groups[g][i], groups[g][j])) {\n                            uf.unite(groups[g][i], groups[g][j]);\n                            mstEdges.insert({groups[g][i], groups[g][j]});\n                            if (mstEdges.size() >= sz - 1) break;\n                        }\n                    }\n                    if (mstEdges.size() >= sz - 1) break;\n                }\n            }\n            \n            groupEdges[g] = vector<pair<int, int>>(mstEdges.begin(), mstEdges.end());\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int c : groups[g]) cout << c << \" \";\n        cout << endl;\n        for (auto& e : groupEdges[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Point {\n    int i, 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 tie(i, j) < tie(other.i, other.j);\n    }\n};\n\nvector<string> actions;\nset<Point> blocks;\nset<Point> usefulBlocks; // Blocks we want to keep\nPoint current;\nvector<Point> targets;\nint currentTargetIdx = 0;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\nPoint getNext(Point p, int dir) {\n    return {p.i + di[dir], p.j + dj[dir]};\n}\n\nPoint slideFrom(Point p, int dir) {\n    while (true) {\n        Point next = getNext(p, dir);\n        if (!inBounds(next.i, next.j) || blocks.count(next)) break;\n        p = next;\n    }\n    return p;\n}\n\nvoid addAction(char type, int dir) {\n    actions.push_back(string(1, type) + \" \" + dirs[dir]);\n    \n    if (type == 'M') {\n        current = getNext(current, dir);\n    } else if (type == 'S') {\n        current = slideFrom(current, dir);\n    } else if (type == 'A') {\n        Point next = getNext(current, dir);\n        if (inBounds(next.i, next.j)) {\n            if (blocks.count(next)) {\n                blocks.erase(next);\n                usefulBlocks.erase(next);\n            } else {\n                blocks.insert(next);\n            }\n        }\n    }\n}\n\n// Check if a block would be useful for future targets\nbool isBlockUseful(Point block) {\n    int useCount = 0;\n    \n    // Check next 5 targets\n    for (int idx = currentTargetIdx; idx < min(currentTargetIdx + 5, M); idx++) {\n        Point t = targets[idx];\n        \n        // Check if block is adjacent to target (useful as stopper)\n        if (abs(block.i - t.i) + abs(block.j - t.j) == 1) {\n            // Check if it's on the right side for stopping\n            if ((block.i == t.i && (block.j == t.j + 1 || block.j == t.j - 1)) ||\n                (block.j == t.j && (block.i == t.i + 1 || block.i == t.i - 1))) {\n                useCount++;\n            }\n        }\n    }\n    \n    return useCount >= 2; // Useful if helps with at least 2 targets\n}\n\n// BFS for shortest path\nvector<int> findPath(Point start, Point goal) {\n    if (start == goal) return {};\n    \n    queue<pair<Point, vector<int>>> q;\n    set<Point> visited;\n    q.push({start, {}});\n    visited.insert(start);\n    \n    while (!q.empty()) {\n        auto [p, path] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(p, d);\n            if (!inBounds(next.i, next.j) || blocks.count(next) || visited.count(next)) \n                continue;\n            \n            visited.insert(next);\n            auto newPath = path;\n            newPath.push_back(d);\n            \n            if (next == goal) return newPath;\n            q.push({next, newPath});\n        }\n    }\n    \n    return {};\n}\n\n// Try to reach target efficiently\nvoid moveToTarget(Point target) {\n    if (current == target) return;\n    \n    // Clear blocks on target\n    if (blocks.count(target)) {\n        for (int d = 0; d < 4; d++) {\n            Point adj = getNext(target, d);\n            if (inBounds(adj.i, adj.j) && !blocks.count(adj)) {\n                auto path = findPath(current, adj);\n                if (!path.empty()) {\n                    for (int dir : path) {\n                        addAction('M', dir);\n                    }\n                    for (int dd = 0; dd < 4; dd++) {\n                        if (getNext(current, dd) == target) {\n                            addAction('A', dd);\n                            break;\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n    }\n    \n    int dist = abs(current.i - target.i) + abs(current.j - target.j);\n    bool slideDone = false;\n    \n    // Try sliding if aligned\n    if (current.i == target.i || current.j == target.j) {\n        // Check direct slide\n        for (int d = 0; d < 4; d++) {\n            if (slideFrom(current, d) == target) {\n                addAction('S', d);\n                slideDone = true;\n                break;\n            }\n        }\n        \n        // Try with blocker if distance warrants it\n        if (!slideDone && dist >= 3) { // More aggressive threshold\n            int dir = -1;\n            Point blocker;\n            \n            if (current.i == target.i) {\n                dir = (current.j < target.j) ? 3 : 2;\n                blocker = getNext(target, dir);\n            } else {\n                dir = (current.i < target.i) ? 1 : 0;\n                blocker = getNext(target, dir);\n            }\n            \n            if (inBounds(blocker.i, blocker.j) && !blocks.count(blocker)) {\n                blocks.insert(blocker);\n                bool works = (slideFrom(current, dir) == target);\n                blocks.erase(blocker);\n                \n                if (works) {\n                    bool placed = false;\n                    \n                    // Place blocker if adjacent\n                    for (int d = 0; d < 4; d++) {\n                        if (getNext(current, d) == blocker) {\n                            addAction('A', d);\n                            placed = true;\n                            if (isBlockUseful(blocker)) {\n                                usefulBlocks.insert(blocker);\n                            }\n                            break;\n                        }\n                    }\n                    \n                    // Move to place if not adjacent and close enough\n                    if (!placed) {\n                        for (int d = 0; d < 4; d++) {\n                            Point adj = getNext(blocker, d);\n                            if (adj != target && inBounds(adj.i, adj.j) && !blocks.count(adj)) {\n                                auto path = findPath(current, adj);\n                                if (!path.empty() && path.size() <= 2) { // More aggressive\n                                    for (int move : path) {\n                                        addAction('M', move);\n                                    }\n                                    for (int dd = 0; dd < 4; dd++) {\n                                        if (getNext(current, dd) == blocker) {\n                                            addAction('A', dd);\n                                            placed = true;\n                                            if (isBlockUseful(blocker)) {\n                                                usefulBlocks.insert(blocker);\n                                            }\n                                            break;\n                                        }\n                                    }\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (placed) {\n                        addAction('S', dir);\n                        \n                        // Only remove if not useful\n                        if (!usefulBlocks.count(blocker)) {\n                            for (int d = 0; d < 4; d++) {\n                                if (getNext(current, d) == blocker) {\n                                    addAction('A', d);\n                                    break;\n                                }\n                            }\n                        }\n                        slideDone = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Try alignment for medium-long distances\n    if (!slideDone && dist >= 5 && current.i != target.i && current.j != target.j) {\n        // Calculate alignment options\n        vector<pair<Point, int>> alignOptions;\n        \n        Point alignH = {current.i, target.j};\n        Point alignV = {target.i, current.j};\n        \n        if (inBounds(alignH.i, alignH.j) && !blocks.count(alignH)) {\n            auto path = findPath(current, alignH);\n            if (!path.empty()) {\n                int cost = path.size();\n                int slideGain = abs(target.i - alignH.i) + abs(target.j - alignH.j);\n                if (slideGain >= 3) { // Will benefit from sliding\n                    alignOptions.push_back({alignH, cost});\n                }\n            }\n        }\n        \n        if (inBounds(alignV.i, alignV.j) && !blocks.count(alignV)) {\n            auto path = findPath(current, alignV);\n            if (!path.empty()) {\n                int cost = path.size();\n                int slideGain = abs(target.i - alignV.i) + abs(target.j - alignV.j);\n                if (slideGain >= 3) {\n                    alignOptions.push_back({alignV, cost});\n                }\n            }\n        }\n        \n        // Choose best alignment\n        if (!alignOptions.empty()) {\n            sort(alignOptions.begin(), alignOptions.end(), \n                 [](const auto& a, const auto& b) { return a.second < b.second; });\n            \n            if (alignOptions[0].second < dist - 2) {\n                auto path = findPath(current, alignOptions[0].first);\n                for (int dir : path) {\n                    addAction('M', dir);\n                }\n                moveToTarget(target); // Recursive call now that we're aligned\n                return;\n            }\n        }\n    }\n    \n    // Direct path if sliding didn't work\n    if (!slideDone) {\n        auto path = findPath(current, target);\n        for (int dir : path) {\n            addAction('M', dir);\n            if (actions.size() >= 1590) break;\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    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].i >> targets[i].j;\n    }\n    \n    current = targets[0];\n    \n    // Visit each target\n    for (int i = 1; i < m && actions.size() < 1590; i++) {\n        currentTargetIdx = i;\n        moveToTarget(targets[i]);\n    }\n    \n    // Clean up remaining blocks that aren't needed\n    vector<Point> toRemove;\n    for (const Point& block : blocks) {\n        if (!usefulBlocks.count(block)) {\n            toRemove.push_back(block);\n        }\n    }\n    \n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n    \n    return 0;\n}"},"16":{"ahc001":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\n#include <random>\n#include <chrono>\n\nusing namespace std;\n\nstruct Rectangle {\n    int a, b, c, d;\n    \n    int area() const {\n        if (c <= a || d <= b) return 0;\n        return (c - a) * (d - b);\n    }\n    \n    bool contains(double px, double py) const {\n        return a < px && px < c && b < py && py < d;\n    }\n    \n    bool overlaps(const Rectangle& other) const {\n        if (area() == 0 || other.area() == 0) return false;\n        return !(c <= other.a || other.c <= a || d <= other.b || other.d <= b);\n    }\n};\n\nclass Solver {\nprivate:\n    int n;\n    vector<int> x, y, r;\n    vector<Rectangle> solution;\n    mt19937 rng;\n    \n    double calculate_satisfaction(int i) const {\n        const auto& rect = solution[i];\n        \n        if (!rect.contains(x[i] + 0.5, y[i] + 0.5)) {\n            return 0.0;\n        }\n        \n        int s = rect.area();\n        if (s == 0) return 0.0;\n        \n        double ratio = min(r[i], s) / (double)max(r[i], s);\n        return 1.0 - (1.0 - ratio) * (1.0 - ratio);\n    }\n    \n    bool check_overlap_with_others(const Rectangle& rect, int exclude_id) const {\n        for (int i = 0; i < n; i++) {\n            if (i == exclude_id) continue;\n            if (solution[i].overlaps(rect)) {\n                return true;\n            }\n        }\n        return false;\n    }\n    \n    Rectangle find_non_overlapping_rectangle(int idx) {\n        int px = x[idx];\n        int py = y[idx];\n        int target_area = r[idx];\n        \n        Rectangle best_rect = {0, 0, 0, 0}; // Start with invalid rectangle\n        double best_score = -1;\n        \n        // Calculate dimensions to try\n        int sqrt_area = max(1, (int)sqrt(target_area));\n        vector<pair<int,int>> sizes;\n        \n        // Add various aspect ratios\n        sizes.push_back({sqrt_area, max(1, target_area / sqrt_area)});\n        sizes.push_back({max(1, target_area / sqrt_area), sqrt_area});\n        \n        for (double ratio : {0.5, 0.7, 1.4, 2.0}) {\n            int w = max(1, (int)sqrt(target_area * ratio));\n            int h = max(1, target_area / w);\n            if (w <= 10000 && h <= 10000) {\n                sizes.push_back({w, h});\n            }\n        }\n        \n        // Add smaller fallback sizes\n        sizes.push_back({min(100, sqrt_area), min(100, sqrt_area)});\n        sizes.push_back({10, 10});\n        sizes.push_back({5, 5});\n        sizes.push_back({2, 2});\n        sizes.push_back({1, 1});\n        \n        // Try each size\n        for (auto [w, h] : sizes) {\n            if (w > 10000 || h > 10000) continue;\n            \n            // Try positions that include the target point\n            for (int dx = 0; dx <= min(w-1, px) && dx <= 5; dx++) {\n                for (int dy = 0; dy <= min(h-1, py) && dy <= 5; dy++) {\n                    int a = px - dx;\n                    int b = py - dy;\n                    int c = min(10000, a + w);\n                    int d = min(10000, b + h);\n                    \n                    if (a < 0 || b < 0) continue;\n                    \n                    Rectangle rect = {a, b, c, d};\n                    \n                    if (!rect.contains(px + 0.5, py + 0.5)) continue;\n                    if (check_overlap_with_others(rect, idx)) continue;\n                    \n                    // Valid rectangle found\n                    int area = rect.area();\n                    double ratio = min(target_area, area) / (double)max(target_area, area);\n                    double score = 1.0 - (1.0 - ratio) * (1.0 - ratio);\n                    \n                    if (score > best_score) {\n                        best_score = score;\n                        best_rect = rect;\n                        if (score > 0.99) return best_rect;\n                    }\n                }\n            }\n        }\n        \n        // If we found a valid rectangle, return it\n        if (best_rect.area() > 0) {\n            return best_rect;\n        }\n        \n        // Otherwise, search for ANY non-overlapping rectangle (even if it doesn't contain the point)\n        // Search near the target point first\n        for (int radius = 1; radius <= 100; radius += 5) {\n            for (int a = max(0, px - radius); a <= min(9999, px + radius); a += max(1, radius/10)) {\n                for (int b = max(0, py - radius); b <= min(9999, py + radius); b += max(1, radius/10)) {\n                    Rectangle rect = {a, b, min(10000, a + 1), min(10000, b + 1)};\n                    if (!check_overlap_with_others(rect, idx)) {\n                        return rect; // Will have 0 satisfaction but no overlap\n                    }\n                }\n            }\n        }\n        \n        // Broader search for any free space\n        for (int a = 0; a < 10000; a += 50) {\n            for (int b = 0; b < 10000; b += 50) {\n                Rectangle rect = {a, b, min(10000, a + 1), min(10000, b + 1)};\n                if (!check_overlap_with_others(rect, idx)) {\n                    return rect;\n                }\n            }\n        }\n        \n        // Ultimate fallback - should never reach here if sum of areas = 10000x10000\n        return {0, 0, 1, 1};\n    }\n    \n    void optimization_phase(int time_limit_ms) {\n        auto start_time = chrono::steady_clock::now();\n        auto time_limit = chrono::milliseconds(time_limit_ms);\n        \n        int iterations = 0;\n        \n        while (chrono::steady_clock::now() - start_time < time_limit) {\n            iterations++;\n            \n            int idx = rng() % n;\n            Rectangle old_rect = solution[idx];\n            double old_sat = calculate_satisfaction(idx);\n            \n            // Skip if already near-perfect\n            if (old_sat > 0.999) continue;\n            \n            Rectangle new_rect = old_rect;\n            int current_area = old_rect.area();\n            int target_area = r[idx];\n            \n            // Choose operation based on area difference\n            int area_diff = target_area - current_area;\n            \n            if (abs(area_diff) > 100) {\n                // Need significant change\n                int step = 1 + rng() % min(50, max(1, abs(area_diff) / 10));\n                \n                if (current_area < target_area) {\n                    // Expand\n                    switch(rng() % 4) {\n                        case 0: new_rect.c = min(10000, new_rect.c + step); break;\n                        case 1: new_rect.d = min(10000, new_rect.d + step); break;\n                        case 2: new_rect.a = max(0, new_rect.a - step); break;\n                        case 3: new_rect.b = max(0, new_rect.b - step); break;\n                    }\n                } else {\n                    // Shrink - must check containment\n                    Rectangle temp = new_rect;\n                    switch(rng() % 4) {\n                        case 0: temp.c = max(temp.a + 1, temp.c - step); break;\n                        case 1: temp.d = max(temp.b + 1, temp.d - step); break;\n                        case 2: temp.a = min(temp.c - 1, temp.a + step); break;\n                        case 3: temp.b = min(temp.d - 1, temp.b + step); break;\n                    }\n                    if (temp.contains(x[idx] + 0.5, y[idx] + 0.5)) {\n                        new_rect = temp;\n                    }\n                }\n            } else {\n                // Fine tuning\n                int step = 1 + (rng() % 3);\n                \n                if (current_area < target_area) {\n                    switch(rng() % 4) {\n                        case 0: new_rect.c = min(10000, new_rect.c + step); break;\n                        case 1: new_rect.d = min(10000, new_rect.d + step); break;\n                        case 2: new_rect.a = max(0, new_rect.a - step); break;\n                        case 3: new_rect.b = max(0, new_rect.b - step); break;\n                    }\n                } else if (current_area > target_area) {\n                    Rectangle temp = new_rect;\n                    switch(rng() % 4) {\n                        case 0: temp.c = max(temp.a + 1, temp.c - step); break;\n                        case 1: temp.d = max(temp.b + 1, temp.d - step); break;\n                        case 2: temp.a = min(temp.c - 1, temp.a + step); break;\n                        case 3: temp.b = min(temp.d - 1, temp.b + step); break;\n                    }\n                    if (temp.contains(x[idx] + 0.5, y[idx] + 0.5)) {\n                        new_rect = temp;\n                    }\n                }\n            }\n            \n            // Validate changes\n            if (!new_rect.contains(x[idx] + 0.5, y[idx] + 0.5)) continue;\n            if (check_overlap_with_others(new_rect, idx)) continue;\n            \n            // Calculate improvement\n            solution[idx] = new_rect;\n            double new_sat = calculate_satisfaction(idx);\n            \n            if (new_sat <= old_sat) {\n                solution[idx] = old_rect;\n            }\n        }\n    }\n    \n    void validate_and_fix() {\n        // Final validation - should not be needed but just in case\n        for (int i = 0; i < n; i++) {\n            for (int j = i + 1; j < n; j++) {\n                if (solution[i].overlaps(solution[j])) {\n                    // This should never happen\n                    // Emergency fix: make the smaller one a 1x1 elsewhere\n                    if (solution[i].area() < solution[j].area()) {\n                        for (int a = 0; a < 10000; a += 100) {\n                            for (int b = 0; b < 10000; b += 100) {\n                                Rectangle rect = {a, b, a+1, b+1};\n                                bool ok = true;\n                                for (int k = 0; k < n; k++) {\n                                    if (k != i && solution[k].overlaps(rect)) {\n                                        ok = false;\n                                        break;\n                                    }\n                                }\n                                if (ok) {\n                                    solution[i] = rect;\n                                    goto next_validation;\n                                }\n                            }\n                        }\n                    } else {\n                        for (int a = 0; a < 10000; a += 100) {\n                            for (int b = 0; b < 10000; b += 100) {\n                                Rectangle rect = {a, b, a+1, b+1};\n                                bool ok = true;\n                                for (int k = 0; k < n; k++) {\n                                    if (k != j && solution[k].overlaps(rect)) {\n                                        ok = false;\n                                        break;\n                                    }\n                                }\n                                if (ok) {\n                                    solution[j] = rect;\n                                    goto next_validation;\n                                }\n                            }\n                        }\n                    }\n                    next_validation:;\n                }\n            }\n        }\n    }\n    \npublic:\n    Solver() : rng(42) {} // Fixed seed for debugging\n    \n    void solve() {\n        cin >> n;\n        x.resize(n);\n        y.resize(n);\n        r.resize(n);\n        solution.resize(n);\n        \n        for (int i = 0; i < n; i++) {\n            cin >> x[i] >> y[i] >> r[i];\n        }\n        \n        // Sort by area (largest first)\n        vector<int> order(n);\n        for (int i = 0; i < n; i++) order[i] = i;\n        sort(order.begin(), order.end(), [&](int i, int j) {\n            return r[i] > r[j];\n        });\n        \n        // Initial placement - guaranteed non-overlapping\n        for (int idx : order) {\n            solution[idx] = find_non_overlapping_rectangle(idx);\n        }\n        \n        // Optimization\n        optimization_phase(4000);\n        \n        // Final validation (emergency only)\n        validate_and_fix();\n    }\n    \n    void output() {\n        for (const auto& rect : solution) {\n            cout << rect.a << \" \" << rect.b << \" \" << rect.c << \" \" << rect.d << \"\\n\";\n        }\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    solver.output();\n    \n    return 0;\n}","ahc002":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 50;\nconst int MAX_TILES = 2500;\n\nint si, sj;\nint tile[N][N];\nint points[N][N];\nvector<pair<int,int>> tile_squares[MAX_TILES];\nint tile_value[MAX_TILES];\nvector<int> tile_neighbors[MAX_TILES];\nint num_tiles;\ndouble avg_tile_value;\n\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct State {\n    int i, j;\n    int score;\n    string path;\n    bitset<MAX_TILES> visited;\n    \n    State() : i(si), j(sj), score(0), path(\"\") {\n        visited.reset();\n    }\n    \n    bool operator<(const State& other) const {\n        return score > other.score;\n    }\n};\n\nvoid preprocess() {\n    num_tiles = 0;\n    double total_value = 0;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            num_tiles = max(num_tiles, tile[i][j] + 1);\n            tile_squares[tile[i][j]].push_back({i, j});\n        }\n    }\n    \n    for (int t = 0; t < num_tiles; t++) {\n        tile_value[t] = 0;\n        for (auto [i, j] : tile_squares[t]) {\n            tile_value[t] += points[i][j];\n        }\n        total_value += tile_value[t];\n    }\n    avg_tile_value = total_value / num_tiles;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int curr = tile[i][j];\n            for (int d = 0; d < 4; d++) {\n                int ni = i + di[d];\n                int nj = j + dj[d];\n                if (ni >= 0 && ni < N && nj >= 0 && nj < N) {\n                    int next = tile[ni][nj];\n                    if (next != curr) {\n                        tile_neighbors[curr].push_back(next);\n                    }\n                }\n            }\n        }\n    }\n    \n    for (int t = 0; t < num_tiles; t++) {\n        sort(tile_neighbors[t].begin(), tile_neighbors[t].end());\n        tile_neighbors[t].erase(unique(tile_neighbors[t].begin(), tile_neighbors[t].end()), \n                                tile_neighbors[t].end());\n        sort(tile_neighbors[t].begin(), tile_neighbors[t].end(), \n             [](int a, int b) { return tile_value[a] > tile_value[b]; });\n    }\n}\n\nState beam_search(int beam_width) {\n    vector<State> current, next;\n    \n    State initial;\n    initial.i = si;\n    initial.j = sj;\n    initial.score = points[si][sj];\n    initial.path = \"\";\n    initial.visited[tile[si][sj]] = true;\n    \n    current.push_back(initial);\n    State best = initial;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    int max_depth = min(num_tiles, MAX_TILES);\n    \n    for (int depth = 0; depth < max_depth && !current.empty(); depth++) {\n        next.clear();\n        \n        for (const State& state : current) {\n            if (state.score > best.score) {\n                best = state;\n            }\n            \n            // Check path length to prevent overflow\n            if (state.path.length() >= MAX_TILES) continue;\n            \n            vector<tuple<double, State>> candidates;\n            \n            for (int d = 0; d < 4; d++) {\n                int ni = state.i + di[d];\n                int nj = state.j + dj[d];\n                \n                if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                \n                int next_tile = tile[ni][nj];\n                if (state.visited[next_tile]) continue;\n                \n                State new_state;\n                new_state.i = ni;\n                new_state.j = nj;\n                new_state.path = state.path + dir_char[d];\n                new_state.score = state.score + points[ni][nj];\n                new_state.visited = state.visited;\n                new_state.visited[next_tile] = true;\n                \n                double priority = tile_value[next_tile];\n                \n                // Simple lookahead\n                for (int neighbor : tile_neighbors[next_tile]) {\n                    if (!new_state.visited[neighbor]) {\n                        priority += tile_value[neighbor] * 0.3;\n                    }\n                }\n                \n                priority += dis(gen) * avg_tile_value * 0.1;\n                \n                candidates.push_back({priority, new_state});\n            }\n            \n            sort(candidates.rbegin(), candidates.rend());\n            \n            for (int i = 0; i < min(2, (int)candidates.size()); i++) {\n                next.push_back(get<1>(candidates[i]));\n            }\n        }\n        \n        if (next.size() > beam_width) {\n            nth_element(next.begin(), next.begin() + beam_width, next.end());\n            next.resize(beam_width);\n        }\n        \n        current = next;\n    }\n    \n    return best;\n}\n\nState greedy_simple() {\n    State state;\n    state.i = si;\n    state.j = sj;\n    state.score = points[si][sj];\n    state.path = \"\";\n    state.visited[tile[si][sj]] = true;\n    \n    int max_moves = min(num_tiles, MAX_TILES);\n    \n    for (int move = 0; move < max_moves; move++) {\n        int best_d = -1;\n        double best_value = -1;\n        \n        for (int d = 0; d < 4; d++) {\n            int ni = state.i + di[d];\n            int nj = state.j + dj[d];\n            \n            if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (state.visited[next_tile]) continue;\n            \n            double value = tile_value[next_tile];\n            \n            // Simple lookahead\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!state.visited[neighbor]) {\n                    value += tile_value[neighbor] * 0.3;\n                }\n            }\n            \n            if (value > best_value) {\n                best_value = value;\n                best_d = d;\n            }\n        }\n        \n        if (best_d == -1) break;\n        \n        int ni = state.i + di[best_d];\n        int nj = state.j + dj[best_d];\n        \n        state.i = ni;\n        state.j = nj;\n        state.path += dir_char[best_d];\n        state.score += points[ni][nj];\n        state.visited[tile[ni][nj]] = true;\n    }\n    \n    return state;\n}\n\nState backtrack_search(int max_stack) {\n    State initial;\n    initial.i = si;\n    initial.j = sj;\n    initial.score = points[si][sj];\n    initial.path = \"\";\n    initial.visited[tile[si][sj]] = true;\n    \n    stack<State> search_stack;\n    search_stack.push(initial);\n    \n    State best = initial;\n    \n    random_device rd;\n    mt19937 gen(rd());\n    uniform_real_distribution<> dis(0.0, 1.0);\n    \n    int iterations = 0;\n    int max_iterations = max_stack * 20;\n    \n    while (!search_stack.empty() && iterations < max_iterations) {\n        iterations++;\n        \n        State current = search_stack.top();\n        search_stack.pop();\n        \n        if (current.score > best.score) {\n            best = current;\n        }\n        \n        // Check path length\n        if (current.path.length() >= MAX_TILES) continue;\n        \n        vector<tuple<double, State>> candidates;\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 >= N || nj < 0 || nj >= N) continue;\n            \n            int next_tile = tile[ni][nj];\n            if (current.visited[next_tile]) continue;\n            \n            State new_state;\n            new_state.i = ni;\n            new_state.j = nj;\n            new_state.path = current.path + dir_char[d];\n            new_state.score = current.score + points[ni][nj];\n            new_state.visited = current.visited;\n            new_state.visited[next_tile] = true;\n            \n            double priority = tile_value[next_tile];\n            \n            // Lookahead\n            for (int neighbor : tile_neighbors[next_tile]) {\n                if (!new_state.visited[neighbor]) {\n                    priority += tile_value[neighbor] * 0.4;\n                }\n            }\n            \n            candidates.push_back({priority, new_state});\n        }\n        \n        if (candidates.empty()) continue;\n        \n        sort(candidates.rbegin(), candidates.rend());\n        \n        int branches = min(2, (int)candidates.size());\n        if (dis(gen) < 0.2 && candidates.size() > 2) {\n            branches = 3;\n        }\n        \n        for (int i = branches - 1; i >= 0; i--) {\n            if (search_stack.size() < max_stack) {\n                search_stack.push(get<1>(candidates[i]));\n            }\n        }\n    }\n    \n    return best;\n}\n\nState extend_path(State initial) {\n    State current = initial;\n    \n    int max_extensions = 100; // Prevent infinite loops\n    \n    for (int ext = 0; ext < max_extensions; ext++) {\n        if (current.path.length() >= MAX_TILES) break;\n        \n        int best_d = -1;\n        double best_value = -1;\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 < N && nj >= 0 && nj < N) {\n                int next_tile = tile[ni][nj];\n                if (!current.visited[next_tile] && tile_value[next_tile] > best_value) {\n                    best_value = tile_value[next_tile];\n                    best_d = d;\n                }\n            }\n        }\n        \n        if (best_d == -1) break;\n        \n        int ni = current.i + di[best_d];\n        int nj = current.j + dj[best_d];\n        \n        current.i = ni;\n        current.j = nj;\n        current.path += dir_char[best_d];\n        current.score += points[ni][nj];\n        current.visited[tile[ni][nj]] = true;\n    }\n    \n    return current;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> si >> sj;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> tile[i][j];\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> points[i][j];\n        }\n    }\n    \n    preprocess();\n    \n    // Initialize with simple greedy as fallback\n    State best = greedy_simple();\n    \n    auto start = chrono::high_resolution_clock::now();\n    \n    // Try different strategies\n    State bt1 = backtrack_search(50);\n    bt1 = extend_path(bt1);\n    if (bt1.score > best.score) best = bt1;\n    \n    State b1 = beam_search(30);\n    b1 = extend_path(b1);\n    if (b1.score > best.score) best = b1;\n    \n    State bt2 = backtrack_search(70);\n    bt2 = extend_path(bt2);\n    if (bt2.score > best.score) best = bt2;\n    \n    State b2 = beam_search(40);\n    b2 = extend_path(b2);\n    if (b2.score > best.score) best = b2;\n    \n    // Continue with remaining time\n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start).count();\n        if (elapsed > 1900) break;\n        \n        State bt = backtrack_search(30);\n        bt = extend_path(bt);\n        if (bt.score > best.score) best = bt;\n        \n        State b = beam_search(25);\n        b = extend_path(b);\n        if (b.score > best.score) best = b;\n    }\n    \n    // Ensure we have a valid path\n    if (best.path.empty() && best.score == 0) {\n        best = greedy_simple();\n    }\n    \n    cout << best.path << endl;\n    \n    return 0;\n}","ahc003":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nconst int QUERIES = 1000;\nconst double INF = 1e18;\n\nstruct Edge {\n    double weight = 5000.0;\n    double sum = 0;\n    double sum_sq = 0;\n    int count = 0;\n    double min_obs = INF;\n    double max_obs = -INF;\n    deque<double> recent;  // Efficient recent tracking\n    \n    void update(double obs, int query_num) {\n        count++;\n        sum += obs;\n        sum_sq += obs * obs;\n        min_obs = min(min_obs, obs);\n        max_obs = max(max_obs, obs);\n        \n        recent.push_back(obs);\n        if (recent.size() > 12) recent.pop_front();\n        \n        // Fine-tuned learning schedule\n        double lr;\n        if (query_num < 60) {\n            lr = 0.6;  // Very aggressive start\n        } else if (query_num < 150) {\n            lr = 0.45;\n        } else if (query_num < 300) {\n            lr = 0.3;\n        } else if (query_num < 500) {\n            lr = 0.2;\n        } else if (query_num < 750) {\n            lr = 0.13;\n        } else if (query_num < 900) {\n            lr = 0.08;\n        } else {\n            lr = 0.05;  // Ultra-stable final 100\n        }\n        \n        // Smoother decay with observation count\n        lr = lr / (1.0 + count * 0.035);\n        \n        if (count == 1) {\n            weight = obs;\n        } else {\n            double avg = sum / count;\n            \n            // Phase-dependent blending\n            double blend_obs;\n            if (query_num > 800 && recent.size() >= 8) {\n                // Late game: heavy recent average\n                double recent_sum = 0;\n                for (double r : recent) recent_sum += r;\n                double recent_avg = recent_sum / recent.size();\n                blend_obs = obs * 0.3 + recent_avg * 0.7;\n            } else if (query_num > 500 && recent.size() >= 5) {\n                // Mid-late game: balanced\n                double recent_sum = 0;\n                for (double r : recent) recent_sum += r;\n                double recent_avg = recent_sum / recent.size();\n                blend_obs = obs * 0.4 + recent_avg * 0.3 + avg * 0.3;\n            } else {\n                // Early-mid game: standard blend\n                blend_obs = obs * 0.65 + avg * 0.35;\n            }\n            \n            weight = weight * (1 - lr) + blend_obs * lr;\n        }\n        \n        // Tighter bounds with more observations\n        if (count >= 8) {\n            double lower = min_obs / 1.105;  // Slightly tighter\n            double upper = max_obs / 0.895;\n            weight = max(lower, min(upper, weight));\n        } else if (count >= 4) {\n            double lower = min_obs / 1.11;\n            double upper = max_obs / 0.89;\n            weight = max(lower, min(upper, weight));\n        }\n        \n        weight = max(100.0, min(10000.0, weight));\n    }\n    \n    double get_weight(int query_num) const {\n        // Progressive exploration decay\n        if (query_num < 100 && count < 3) {\n            return weight * 0.82;  // 18% optimism\n        } else if (query_num < 180 && count < 5) {\n            return weight * 0.88;  // 12% optimism\n        } else if (query_num < 280 && count < 7) {\n            return weight * 0.94;  // 6% optimism\n        }\n        return weight;\n    }\n    \n    double get_confidence() const {\n        if (count < 2) return 0;\n        double avg = sum / count;\n        double var = (sum_sq / count) - avg * avg;\n        return 1.0 / (1.0 + sqrt(var) / (avg + 1));\n    }\n};\n\nEdge h_edges[N][N-1];\nEdge v_edges[N-1][N];\n\n// Enhanced statistics tracking\nstruct LineStats {\n    double sum = 0;\n    double sum_sq = 0;\n    int count = 0;\n    \n    double get_avg() const { \n        return count > 0 ? sum / count : 5000.0; \n    }\n    \n    double get_std() const {\n        if (count < 2) return 1000;\n        double avg = sum / count;\n        return sqrt((sum_sq / count) - avg * avg);\n    }\n    \n    void add(double val) { \n        sum += val; \n        sum_sq += val * val;\n        count++; \n    }\n};\n\nLineStats row_stats[N];\nLineStats col_stats[N];\n\nstruct State {\n    double f, g;\n    int i, j;\n    bool operator>(const State& o) const { return f > o.f; }\n};\n\npair<string, vector<Edge*>> find_path(int si, int sj, int ti, int tj, int query_num) {\n    vector<vector<double>> dist(N, vector<double>(N, INF));\n    vector<vector<pair<int,int>>> prev(N, vector<pair<int,int>>(N, {-1,-1}));\n    \n    // Phase-dependent heuristic\n    double h_weight;\n    if (query_num < 100) h_weight = 800.0;   // Strong exploration\n    else if (query_num < 300) h_weight = 1400.0;\n    else h_weight = 1700.0;  // Exploitation\n    \n    auto heuristic = [&](int i, int j) {\n        return (abs(ti - i) + abs(tj - j)) * h_weight;\n    };\n    \n    priority_queue<State, vector<State>, greater<State>> pq;\n    dist[si][sj] = 0;\n    pq.push({heuristic(si, sj), 0, si, sj});\n    \n    while (!pq.empty()) {\n        auto [f, g, i, j] = pq.top();\n        pq.pop();\n        \n        if (g > dist[i][j]) continue;\n        if (i == ti && j == tj) break;\n        \n        vector<tuple<int,int,Edge*>> moves;\n        if (i > 0) moves.push_back({i-1, j, &v_edges[i-1][j]});\n        if (i < N-1) moves.push_back({i+1, j, &v_edges[i][j]});\n        if (j > 0) moves.push_back({i, j-1, &h_edges[i][j-1]});\n        if (j < N-1) moves.push_back({i, j+1, &h_edges[i][j]});\n        \n        for (auto [ni, nj, edge] : moves) {\n            double w = edge->get_weight(query_num);\n            double new_g = dist[i][j] + w;\n            \n            if (new_g < dist[ni][nj]) {\n                dist[ni][nj] = new_g;\n                prev[ni][nj] = {i, j};\n                pq.push({new_g + heuristic(ni, nj), new_g, ni, nj});\n            }\n        }\n    }\n    \n    string path;\n    vector<Edge*> edges;\n    \n    int ci = ti, cj = tj;\n    while (ci != si || cj != sj) {\n        auto [pi, pj] = prev[ci][cj];\n        \n        if (pi < ci) {\n            path += 'D';\n            edges.push_back(&v_edges[pi][pj]);\n        } else if (pi > ci) {\n            path += 'U';\n            edges.push_back(&v_edges[ci][cj]);\n        } else if (pj < cj) {\n            path += 'R';\n            edges.push_back(&h_edges[pi][pj]);\n        } else {\n            path += 'L';\n            edges.push_back(&h_edges[ci][cj]);\n        }\n        \n        ci = pi; cj = pj;\n    }\n    \n    reverse(path.begin(), path.end());\n    reverse(edges.begin(), edges.end());\n    return {path, edges};\n}\n\nvoid update_weights(const vector<Edge*>& edges, const string& path,\n                   int si, int sj, int measured, int query_num) {\n    if (edges.empty()) return;\n    \n    double total = 0;\n    for (Edge* e : edges) total += e->weight;\n    if (total <= 0) return;\n    \n    double ratio = measured / total;\n    \n    int ci = si, cj = sj;\n    for (int idx = 0; idx < edges.size(); idx++) {\n        double obs = edges[idx]->weight * ratio;\n        edges[idx]->update(obs, query_num);\n        \n        if (path[idx] == 'L' || path[idx] == 'R') {\n            row_stats[ci].add(obs);\n        } else {\n            col_stats[cj].add(obs);\n        }\n        \n        if (path[idx] == 'U') ci--;\n        else if (path[idx] == 'D') ci++;\n        else if (path[idx] == 'L') cj--;\n        else if (path[idx] == 'R') cj++;\n    }\n}\n\nvoid initialize_unvisited(int query_num) {\n    // Smart initialization using statistics\n    for (int i = 0; i < N; i++) {\n        if (row_stats[i].count < 3) continue;\n        double avg = row_stats[i].get_avg();\n        double std = row_stats[i].get_std();\n        \n        for (int j = 0; j < N-1; j++) {\n            if (h_edges[i][j].count == 0) {\n                // Use average with slight randomness for diversity\n                h_edges[i][j].weight = avg;\n            } else if (h_edges[i][j].count < 3 && query_num > 200) {\n                // Gently pull rarely-visited edges toward row average\n                h_edges[i][j].weight = h_edges[i][j].weight * 0.7 + avg * 0.3;\n            }\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        if (col_stats[j].count < 3) continue;\n        double avg = col_stats[j].get_avg();\n        \n        for (int i = 0; i < N-1; i++) {\n            if (v_edges[i][j].count == 0) {\n                v_edges[i][j].weight = avg;\n            } else if (v_edges[i][j].count < 3 && query_num > 200) {\n                v_edges[i][j].weight = v_edges[i][j].weight * 0.7 + avg * 0.3;\n            }\n        }\n    }\n}\n\nvoid stabilize(int query_num) {\n    if (query_num < 400) return;\n    \n    double factor;\n    if (query_num > 900) factor = 0.03;\n    else if (query_num > 750) factor = 0.05;\n    else factor = 0.08;\n    \n    // Only smooth high-confidence edges\n    for (int i = 0; i < N; i++) {\n        for (int j = 1; j < N-2; j++) {\n            auto& e = h_edges[i][j];\n            if (e.count < 20 || e.get_confidence() < 0.6) continue;\n            \n            double sum = e.weight * 4;\n            int cnt = 4;\n            \n            if (h_edges[i][j-1].count > 10 && h_edges[i][j-1].get_confidence() > 0.5) {\n                sum += h_edges[i][j-1].weight;\n                cnt++;\n            }\n            if (h_edges[i][j+1].count > 10 && h_edges[i][j+1].get_confidence() > 0.5) {\n                sum += h_edges[i][j+1].weight;\n                cnt++;\n            }\n            \n            e.weight = e.weight * (1 - factor) + (sum / cnt) * factor;\n        }\n    }\n    \n    for (int j = 0; j < N; j++) {\n        for (int i = 1; i < N-2; i++) {\n            auto& e = v_edges[i][j];\n            if (e.count < 20 || e.get_confidence() < 0.6) continue;\n            \n            double sum = e.weight * 4;\n            int cnt = 4;\n            \n            if (v_edges[i-1][j].count > 10 && v_edges[i-1][j].get_confidence() > 0.5) {\n                sum += v_edges[i-1][j].weight;\n                cnt++;\n            }\n            if (v_edges[i+1][j].count > 10 && v_edges[i+1][j].get_confidence() > 0.5) {\n                sum += v_edges[i+1][j].weight;\n                cnt++;\n            }\n            \n            e.weight = e.weight * (1 - factor) + (sum / cnt) * factor;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int query = 0; query < QUERIES; query++) {\n        int si, sj, ti, tj;\n        cin >> si >> sj >> ti >> tj;\n        \n        auto [path, edges] = find_path(si, sj, ti, tj, query);\n        \n        cout << path << endl;\n        cout.flush();\n        \n        int measured;\n        cin >> measured;\n        \n        update_weights(edges, path, si, sj, measured, query);\n        \n        if (query > 30 && query % 40 == 39) {\n            initialize_unvisited(query);\n            if (query >= 400) {\n                stabilize(query);\n            }\n        }\n    }\n    \n    return 0;\n}","ahc004":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\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<string> strings(m);\n    for (int i = 0; i < m; i++) {\n        cin >> strings[i];\n    }\n    \n    // Best solution tracking\n    vector<vector<char>> bestGrid(n, vector<char>(n, '.'));\n    int bestMatched = 0;\n    int bestDots = n * n;\n    \n    // Random number generator\n    mt19937 rng(42);\n    \n    // Try multiple random configurations\n    for (int attempt = 0; attempt < 50; attempt++) {\n        vector<vector<char>> grid(n, vector<char>(n, '.'));\n        \n        // Shuffle string order for this attempt\n        vector<int> order(m);\n        iota(order.begin(), order.end(), 0);\n        shuffle(order.begin(), order.end(), rng);\n        \n        // Sort by length for first half of attempts, random for second half\n        if (attempt < 25) {\n            sort(order.begin(), order.end(), [&](int a, int b) {\n                return strings[a].length() > strings[b].length();\n            });\n        }\n        \n        // Helper functions\n        auto canPlaceH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int col = (c + i) % n;\n                if (grid[r][col] != '.' && grid[r][col] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto canPlaceV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                int row = (r + i) % n;\n                if (grid[row][c] != '.' && grid[row][c] != s[i]) {\n                    return false;\n                }\n            }\n            return true;\n        };\n        \n        auto placeH = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[r][(c + i) % n] = s[i];\n            }\n        };\n        \n        auto placeV = [&](int r, int c, const string& s) {\n            for (int i = 0; i < s.length(); i++) {\n                grid[(r + i) % n][c] = s[i];\n            }\n        };\n        \n        // Place strings\n        vector<bool> placed(m, false);\n        \n        for (int idx : order) {\n            const string& s = strings[idx];\n            vector<tuple<int, int, int, int>> positions; // r, c, dir, overlap\n            \n            for (int r = 0; r < n; r++) {\n                for (int c = 0; c < n; c++) {\n                    if (canPlaceH(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[r][(c + i) % n] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 0, overlap});\n                    }\n                    if (canPlaceV(r, c, s)) {\n                        int overlap = 0;\n                        for (int i = 0; i < s.length(); i++) {\n                            if (grid[(r + i) % n][c] == s[i]) overlap++;\n                        }\n                        positions.push_back({r, c, 1, overlap});\n                    }\n                }\n            }\n            \n            if (!positions.empty()) {\n                // Choose position based on strategy\n                int choice;\n                if (attempt < 10) {\n                    // Max overlap\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = 0;\n                } else if (attempt < 20) {\n                    // Random from top positions\n                    sort(positions.begin(), positions.end(), [](const auto& a, const auto& b) {\n                        return get<3>(a) > get<3>(b);\n                    });\n                    choice = uniform_int_distribution<int>(0, min(3, (int)positions.size()-1))(rng);\n                } else {\n                    // Pure random\n                    choice = uniform_int_distribution<int>(0, positions.size()-1)(rng);\n                }\n                \n                auto [r, c, dir, overlap] = positions[choice];\n                if (dir == 0) {\n                    placeH(r, c, s);\n                } else {\n                    placeV(r, c, s);\n                }\n                placed[idx] = true;\n            }\n        }\n        \n        // Check all strings against final grid\n        int matched = 0;\n        for (const string& s : strings) {\n            bool found = false;\n            for (int r = 0; r < n && !found; r++) {\n                for (int c = 0; c < n && !found; c++) {\n                    // Check horizontal\n                    bool matchH = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[r][(c + i) % n] != s[i]) {\n                            matchH = false;\n                            break;\n                        }\n                    }\n                    if (matchH) {\n                        found = true;\n                        break;\n                    }\n                    \n                    // Check vertical\n                    bool matchV = true;\n                    for (int i = 0; i < s.length(); i++) {\n                        if (grid[(r + i) % n][c] != s[i]) {\n                            matchV = false;\n                            break;\n                        }\n                    }\n                    if (matchV) {\n                        found = true;\n                        break;\n                    }\n                }\n            }\n            if (found) matched++;\n        }\n        \n        // Count dots\n        int dots = 0;\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (grid[i][j] == '.') dots++;\n            }\n        }\n        \n        // Update best if better\n        if (matched > bestMatched || (matched == bestMatched && dots < bestDots)) {\n            bestGrid = grid;\n            bestMatched = matched;\n            bestDots = dots;\n        }\n    }\n    \n    // Fill remaining dots intelligently\n    map<char, int> freq;\n    for (const auto& s : strings) {\n        for (char c : s) {\n            freq[c]++;\n        }\n    }\n    \n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (bestGrid[i][j] == '.') {\n                // Look at neighbors\n                map<char, int> neighborFreq;\n                for (int di = -1; di <= 1; di++) {\n                    for (int dj = -1; dj <= 1; dj++) {\n                        if (di == 0 && dj == 0) continue;\n                        int ni = (i + di + n) % n;\n                        int nj = (j + dj + n) % n;\n                        if (bestGrid[ni][nj] != '.') {\n                            neighborFreq[bestGrid[ni][nj]]++;\n                        }\n                    }\n                }\n                \n                if (!neighborFreq.empty()) {\n                    char best = 'A';\n                    int bestScore = -1;\n                    for (auto [c, cnt] : neighborFreq) {\n                        int score = cnt * 1000 + freq[c];\n                        if (score > bestScore) {\n                            bestScore = score;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                } else {\n                    // Use most frequent character\n                    char best = 'A';\n                    int maxF = 0;\n                    for (auto [c, f] : freq) {\n                        if (f > maxF) {\n                            maxF = f;\n                            best = c;\n                        }\n                    }\n                    bestGrid[i][j] = best;\n                }\n            }\n        }\n    }\n    \n    // Output the best grid\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            cout << bestGrid[i][j];\n        }\n        cout << '\\n';\n    }\n    \n    return 0;\n}","ahc005":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, si, sj;\nvector<string> grid;\nint di[] = {-1, 1, 0, 0};\nint dj[] = {0, 0, -1, 1};\nchar dir[] = {'U', 'D', 'L', 'R'};\n\nbool is_road(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N && grid[i][j] != '#';\n}\n\npair<int, string> dijkstra(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return {0, \"\"};\n    \n    priority_queue<tuple<int, int, int>, vector<tuple<int, int, int>>, greater<>> pq;\n    vector<vector<int>> dist(N, vector<int>(N, 1e9));\n    vector<vector<pair<int,int>>> parent(N, vector<pair<int,int>>(N, {-1, -1}));\n    vector<vector<int>> parent_dir(N, vector<int>(N, -1));\n    \n    pq.push({0, si, sj});\n    dist[si][sj] = 0;\n    \n    while (!pq.empty()) {\n        auto [d, i, j] = pq.top();\n        pq.pop();\n        \n        if (d > dist[i][j]) continue;\n        if (i == ei && j == ej) {\n            string path = \"\";\n            int ci = ei, cj = ej;\n            while (!(ci == si && cj == sj)) {\n                path = dir[parent_dir[ci][cj]] + path;\n                auto [pi, pj] = parent[ci][cj];\n                ci = pi; cj = pj;\n            }\n            return {d, path};\n        }\n        \n        for (int k = 0; k < 4; k++) {\n            int ni = i + di[k], nj = j + dj[k];\n            if (is_road(ni, nj)) {\n                int nd = d + (grid[ni][nj] - '0');\n                if (nd < dist[ni][nj]) {\n                    dist[ni][nj] = nd;\n                    parent[ni][nj] = {i, j};\n                    parent_dir[ni][nj] = k;\n                    pq.push({nd, ni, nj});\n                }\n            }\n        }\n    }\n    return {1e9, \"\"};\n}\n\nvector<pair<int,int>> get_visible(int i, int j) {\n    vector<pair<int,int>> vis;\n    if (!is_road(i, j)) return vis;\n    vis.push_back({i, j});\n    for (int jj = j-1; jj >= 0 && is_road(i, jj); jj--) vis.push_back({i, jj});\n    for (int jj = j+1; jj < N && is_road(i, jj); jj++) vis.push_back({i, jj});\n    for (int ii = i-1; ii >= 0 && is_road(ii, j); ii--) vis.push_back({ii, j});\n    for (int ii = i+1; ii < N && is_road(ii, j); ii++) vis.push_back({ii, j});\n    return vis;\n}\n\nint main() {\n    cin >> N >> si >> sj;\n    grid.resize(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    \n    // Find all roads and compute visibility\n    vector<pair<int,int>> all_roads;\n    map<pair<int,int>, vector<pair<int,int>>> visibility;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (is_road(i, j)) {\n                all_roads.push_back({i, j});\n                visibility[{i, j}] = get_visible(i, j);\n            }\n        }\n    }\n    \n    // Smart waypoint selection\n    set<pair<int,int>> covered;\n    vector<pair<int,int>> waypoints;\n    waypoints.push_back({si, sj});\n    \n    for (auto p : visibility[{si, sj}]) {\n        covered.insert(p);\n    }\n    \n    // Identify high-value positions\n    vector<pair<double, pair<int,int>>> candidates;\n    for (auto [i, j] : all_roads) {\n        int vis_count = visibility[{i, j}].size();\n        // Score based on visibility and centrality\n        double score = vis_count;\n        // Bonus for crossroads (good horizontal and vertical visibility)\n        int h_vis = 1, v_vis = 1;\n        for (int jj = j-1; jj >= 0 && is_road(i, jj); jj--) h_vis++;\n        for (int jj = j+1; jj < N && is_road(i, jj); jj++) h_vis++;\n        for (int ii = i-1; ii >= 0 && is_road(ii, j); ii--) v_vis++;\n        for (int ii = i+1; ii < N && is_road(ii, j); ii++) v_vis++;\n        if (h_vis > 5 && v_vis > 5) score *= 1.5;\n        \n        candidates.push_back({score, {i, j}});\n    }\n    sort(candidates.rbegin(), candidates.rend());\n    \n    // Phase 1: Add high-value positions\n    for (auto [score, pos] : candidates) {\n        if (covered.size() >= all_roads.size()) break;\n        if (score < 8) break;\n        \n        int new_cov = 0;\n        for (auto p : visibility[pos]) {\n            if (!covered.count(p)) new_cov++;\n        }\n        \n        if (new_cov >= 3) {\n            waypoints.push_back(pos);\n            for (auto p : visibility[pos]) {\n                covered.insert(p);\n            }\n        }\n    }\n    \n    // Phase 2: Cover remaining areas efficiently\n    while (covered.size() < all_roads.size()) {\n        int best_i = -1, best_j = -1;\n        double best_score = -1;\n        \n        for (auto [i, j] : all_roads) {\n            if (covered.count({i, j})) continue;\n            \n            int new_cov = 0;\n            for (auto p : visibility[{i, j}]) {\n                if (!covered.count(p)) new_cov++;\n            }\n            \n            if (new_cov > 0) {\n                // Find minimum distance to existing waypoints\n                int min_dist = 1e9;\n                for (auto [wi, wj] : waypoints) {\n                    auto [d, _] = dijkstra(wi, wj, i, j);\n                    min_dist = min(min_dist, d);\n                }\n                \n                double score = (double)new_cov * 1000 / (min_dist + 10);\n                if (score > best_score) {\n                    best_score = score;\n                    best_i = i;\n                    best_j = j;\n                }\n            }\n        }\n        \n        if (best_i == -1) break;\n        \n        waypoints.push_back({best_i, best_j});\n        for (auto p : visibility[{best_i, best_j}]) {\n            covered.insert(p);\n        }\n    }\n    \n    // Advanced tour optimization\n    int n = waypoints.size();\n    if (n > 2) {\n        // Precompute distance matrix\n        vector<vector<int>> dist(n, vector<int>(n, 0));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (i != j) {\n                    auto [d, _] = dijkstra(waypoints[i].first, waypoints[i].second,\n                                          waypoints[j].first, waypoints[j].second);\n                    dist[i][j] = d;\n                }\n            }\n        }\n        \n        // Insertion heuristic for initial tour\n        vector<int> tour = {0};\n        vector<bool> used(n, false);\n        used[0] = true;\n        \n        while (tour.size() < n) {\n            int best_city = -1;\n            int best_pos = -1;\n            int best_cost = 1e9;\n            \n            // Find best city and position to insert\n            for (int c = 0; c < n; c++) {\n                if (used[c]) continue;\n                \n                // Try inserting at each position\n                for (int pos = 1; pos <= tour.size(); pos++) {\n                    int prev = tour[pos-1];\n                    int next = (pos == tour.size()) ? tour[0] : tour[pos];\n                    \n                    int insertion_cost = dist[prev][c] + dist[c][next] - dist[prev][next];\n                    \n                    if (insertion_cost < best_cost) {\n                        best_cost = insertion_cost;\n                        best_city = c;\n                        best_pos = pos;\n                    }\n                }\n            }\n            \n            if (best_city != -1) {\n                tour.insert(tour.begin() + best_pos, best_city);\n                used[best_city] = true;\n            } else break;\n        }\n        \n        // 2-opt improvement\n        bool improved = true;\n        int iterations = 0;\n        while (improved && iterations++ < 200) {\n            improved = false;\n            \n            for (int i = 0; i < n - 2; i++) {\n                for (int j = i + 2; j < n; j++) {\n                    int a = tour[i];\n                    int b = tour[(i + 1) % n];\n                    int c = tour[j];\n                    int d = tour[(j + 1) % n];\n                    \n                    int cur_cost = dist[a][b] + dist[c][d];\n                    int new_cost = dist[a][c] + dist[b][d];\n                    \n                    if (new_cost < cur_cost) {\n                        // Perform 2-opt swap\n                        int start = i + 1;\n                        int end = j;\n                        while (start < end) {\n                            swap(tour[start], tour[end]);\n                            start++;\n                            end--;\n                        }\n                        improved = true;\n                        break;\n                    }\n                }\n                if (improved) break;\n            }\n        }\n        \n        // Or-opt improvement (move segments)\n        if (n <= 30) {\n            improved = true;\n            iterations = 0;\n            while (improved && iterations++ < 50) {\n                improved = false;\n                \n                for (int len = 1; len <= min(3, n/2); len++) {\n                    for (int i = 0; i < n; i++) {\n                        int a = tour[i];\n                        int b = tour[(i + len) % n];\n                        int c = tour[(i + len + 1) % n];\n                        \n                        for (int j = 0; j < n; j++) {\n                            if (abs(i - j) <= len + 1) continue;\n                            \n                            int d = tour[j];\n                            int e = tour[(j + 1) % n];\n                            \n                            int cur_cost = dist[tour[(i + n - 1) % n]][a] + \n                                          dist[b][c] + dist[d][e];\n                            int new_cost = dist[tour[(i + n - 1) % n]][c] + \n                                          dist[d][a] + dist[b][e];\n                            \n                            if (new_cost < cur_cost) {\n                                // Move segment [a...b] after d\n                                vector<int> new_tour;\n                                for (int k = 0; k < n; k++) {\n                                    if (k == (j + 1) % n) {\n                                        for (int l = 0; l <= len; l++) {\n                                            new_tour.push_back(tour[(i + l) % n]);\n                                        }\n                                    }\n                                    if (k < i || k > i + len) {\n                                        new_tour.push_back(tour[k]);\n                                    }\n                                }\n                                tour = new_tour;\n                                improved = true;\n                                break;\n                            }\n                        }\n                        if (improved) break;\n                    }\n                    if (improved) break;\n                }\n            }\n        }\n        \n        // Reorder waypoints\n        vector<pair<int,int>> optimized;\n        for (int idx : tour) {\n            optimized.push_back(waypoints[idx]);\n        }\n        waypoints = optimized;\n    }\n    \n    // Build final route\n    string route = \"\";\n    for (int i = 1; i < waypoints.size(); i++) {\n        auto [d, path] = dijkstra(waypoints[i-1].first, waypoints[i-1].second,\n                                  waypoints[i].first, waypoints[i].second);\n        route += path;\n    }\n    \n    // Return to start\n    if (!waypoints.empty() && waypoints.back() != make_pair(si, sj)) {\n        auto [d, path] = dijkstra(waypoints.back().first, waypoints.back().second, si, sj);\n        route += path;\n    }\n    \n    cout << route << endl;\n    return 0;\n}","future-contest-2022-qual":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K, R;\n    cin >> N >> M >> K >> R;\n    \n    vector<vector<int>> d(N, vector<int>(K));\n    vector<int> task_sum(N, 0);\n    vector<double> skill_freq(K, 0);\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < K; j++) {\n            cin >> d[i][j];\n            task_sum[i] += d[i][j];\n            skill_freq[j] += d[i][j];\n        }\n    }\n    \n    vector<vector<int>> succ(N);\n    vector<int> in_deg(N, 0);\n    \n    for (int i = 0; i < R; i++) {\n        int u, v;\n        cin >> u >> v;\n        u--; v--;\n        succ[u].push_back(v);\n        in_deg[v]++;\n    }\n    \n    // Enhanced criticality calculation\n    vector<int> chain_len(N, 1);\n    vector<int> descendants(N, 0);\n    vector<int> critical_descendants(N, 0);\n    \n    queue<int> q;\n    vector<int> topo;\n    vector<int> tmp_deg = in_deg;\n    \n    for (int i = 0; i < N; i++) {\n        if (tmp_deg[i] == 0) q.push(i);\n    }\n    \n    while (!q.empty()) {\n        int u = q.front();\n        q.pop();\n        topo.push_back(u);\n        for (int v : succ[u]) {\n            tmp_deg[v]--;\n            if (tmp_deg[v] == 0) q.push(v);\n        }\n    }\n    \n    // Calculate metrics with critical path emphasis\n    for (int idx = N - 1; idx >= 0; idx--) {\n        int t = topo[idx];\n        int max_child_chain = 0;\n        for (int s : succ[t]) {\n            chain_len[t] = max(chain_len[t], chain_len[s] + 1);\n            descendants[t] += descendants[s] + 1;\n            max_child_chain = max(max_child_chain, chain_len[s]);\n        }\n        // Count critical descendants (on longest path)\n        for (int s : succ[t]) {\n            if (chain_len[s] == max_child_chain) {\n                critical_descendants[t] += critical_descendants[s] + 1;\n            }\n        }\n    }\n    \n    // Analyze skill distribution\n    vector<double> skill_mean(K), skill_var(K);\n    for (int k = 0; k < K; k++) {\n        double sum = 0, sum2 = 0;\n        for (int i = 0; i < N; i++) {\n            sum += d[i][k];\n            sum2 += d[i][k] * d[i][k];\n        }\n        skill_mean[k] = sum / N;\n        skill_var[k] = max(1.0, sum2 / N - skill_mean[k] * skill_mean[k]);\n    }\n    \n    // Smart skill initialization\n    vector<vector<double>> skills(M, vector<double>(K));\n    vector<vector<double>> confidence(M, vector<double>(K, 0.15));\n    mt19937 rng(42);\n    \n    // Create diverse skill profiles based on task analysis\n    vector<pair<double, int>> skill_priority;\n    for (int k = 0; k < K; k++) {\n        skill_priority.push_back({skill_freq[k], k});\n    }\n    sort(skill_priority.rbegin(), skill_priority.rend());\n    \n    for (int m = 0; m < M; m++) {\n        if (m < min(K/2, M/3)) {\n            // Specialists for high-priority skills\n            int spec = skill_priority[m % skill_priority.size()].second;\n            for (int k = 0; k < K; k++) {\n                if (k == spec) {\n                    skills[m][k] = skill_mean[k] + sqrt(skill_var[k]) * 1.5;\n                } else {\n                    skills[m][k] = skill_mean[k] * 0.4 + normal_distribution<>(0, 5)(rng);\n                }\n            }\n        } else if (m < 2*M/3) {\n            // Multi-specialists\n            set<int> specs;\n            specs.insert(skill_priority[(m*2) % K].second);\n            specs.insert(skill_priority[(m*2+1) % K].second);\n            for (int k = 0; k < K; k++) {\n                if (specs.count(k)) {\n                    skills[m][k] = skill_mean[k] + sqrt(skill_var[k]) * 0.8;\n                } else {\n                    skills[m][k] = skill_mean[k] * 0.6 + normal_distribution<>(0, 5)(rng);\n                }\n            }\n        } else {\n            // Adaptive generalists\n            for (int k = 0; k < K; k++) {\n                skills[m][k] = skill_mean[k] + normal_distribution<>(0, sqrt(skill_var[k]) * 0.5)(rng);\n            }\n        }\n        \n        for (int k = 0; k < K; k++) {\n            skills[m][k] = max(0.0, min(80.0, skills[m][k]));\n        }\n    }\n    \n    // Advanced tracking\n    struct TaskResult {\n        int task, days;\n        double pred_w;\n        vector<int> reqs;\n    };\n    vector<deque<TaskResult>> history(M);\n    vector<int> tasks_done(M, 0);\n    vector<double> error_bias(M, 0);\n    vector<double> performance_factor(M, 1.0);\n    \n    // State\n    vector<int> state(N, 0);\n    vector<int> working(M, -1);\n    vector<int> start_day(N);\n    vector<int> deps_cnt(N);\n    for (int i = 0; i < N; i++) deps_cnt[i] = in_deg[i];\n    \n    int day = 0;\n    int completed = 0;\n    \n    while (completed < N && day < 1980) {\n        day++;\n        \n        double progress = (double)completed / N;\n        double time_factor = min(1.0, day / 1300.0);\n        bool explore_phase = (completed < M * 3) || (progress < 0.1);\n        \n        // Find ready tasks\n        vector<int> ready;\n        for (int i = 0; i < N; i++) {\n            if (state[i] == 0 && deps_cnt[i] == 0) {\n                ready.push_back(i);\n            }\n        }\n        \n        // Calculate dynamic priorities\n        vector<pair<double, int>> priorities;\n        for (int t : ready) {\n            double priority = 0;\n            \n            // Critical path weight with time pressure\n            priority += chain_len[t] * (1800 + time_factor * 1200);\n            \n            // Critical descendants bonus\n            priority += critical_descendants[t] * 100;\n            \n            // Regular descendants\n            priority += descendants[t] * 40;\n            \n            // Immediate unlock bonus (very important)\n            int immediate_unlocks = 0;\n            int critical_unlocks = 0;\n            for (int s : succ[t]) {\n                if (deps_cnt[s] == 1) {\n                    immediate_unlocks++;\n                    if (chain_len[s] > 15) critical_unlocks++;\n                }\n            }\n            priority += immediate_unlocks * 400 + critical_unlocks * 200;\n            \n            // Adjust for task difficulty under time pressure\n            if (time_factor > 0.6) {\n                priority -= task_sum[t] * time_factor * 4;\n            }\n            \n            priorities.push_back({priority, t});\n        }\n        sort(priorities.rbegin(), priorities.rend());\n        \n        // Optimal assignment\n        vector<pair<int, int>> assignments;\n        set<int> assigned;\n        \n        for (auto [_, task] : priorities) {\n            int best_member = -1;\n            double best_score = -1e9;\n            \n            for (int m = 0; m < M; m++) {\n                if (working[m] != -1 || assigned.count(m)) continue;\n                \n                // Calculate expected time with confidence\n                double w_est = 0;\n                double conf_sum = 0;\n                int perfect_skills = 0;\n                double skill_match = 0;\n                \n                for (int k = 0; k < K; k++) {\n                    double gap = max(0.0, d[task][k] - skills[m][k]);\n                    w_est += gap;\n                    conf_sum += confidence[m][k];\n                    \n                    if (d[task][k] > 0) {\n                        if (gap < 0.1) perfect_skills++;\n                        skill_match += min(1.0, skills[m][k] / max(1.0, (double)d[task][k]));\n                    }\n                }\n                \n                double avg_conf = conf_sum / K;\n                double expected_time = (w_est < 0.01) ? 1 : max(1.0, w_est + error_bias[m]);\n                expected_time *= performance_factor[m];\n                \n                // Calculate assignment score\n                double score = -expected_time * 100;\n                \n                // Skill matching bonus\n                score += perfect_skills * 30;\n                score += skill_match * 10;\n                \n                // Exploration vs exploitation\n                if (explore_phase && tasks_done[m] < 6) {\n                    score += (6 - tasks_done[m]) * 40;\n                    if (tasks_done[m] == 0) score += 120;\n                } else if (chain_len[task] > 30) {\n                    // Very critical tasks need confident members\n                    score += avg_conf * 80;\n                    if (tasks_done[m] > 15) score += 30;\n                }\n                \n                // Task similarity bonus from recent history\n                double max_similarity = 0;\n                int similar_count = 0;\n                for (auto& h : history[m]) {\n                    double sim = 0;\n                    for (int k = 0; k < K; k++) {\n                        sim += min(d[task][k], h.reqs[k]);\n                    }\n                    sim /= max(task_sum[task], 1);\n                    if (sim > 0.7) similar_count++;\n                    max_similarity = max(max_similarity, sim);\n                }\n                score += max_similarity * 50;\n                if (similar_count > 2) score += 30;\n                \n                // Workload balancing\n                double avg_work = (double)completed / max(1, M - (int)assigned.size());\n                if (tasks_done[m] < avg_work - 2) {\n                    score += (avg_work - tasks_done[m]) * 12;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_member = m;\n                }\n            }\n            \n            if (best_member != -1) {\n                assignments.push_back({best_member, task});\n                assigned.insert(best_member);\n                working[best_member] = task;\n                state[task] = 1;\n                start_day[task] = day;\n            }\n        }\n        \n        // Output\n        cout << assignments.size();\n        for (auto [m, t] : assignments) {\n            cout << \" \" << (m + 1) << \" \" << (t + 1);\n        }\n        cout << endl;\n        \n        // Read completions\n        int n;\n        cin >> n;\n        if (n == -1) break;\n        \n        if (n > 0) {\n            for (int i = 0; i < n; i++) {\n                int m;\n                cin >> m;\n                m--;\n                \n                if (m >= 0 && m < M && working[m] >= 0) {\n                    int task = working[m];\n                    state[task] = 2;\n                    completed++;\n                    \n                    for (int s : succ[task]) deps_cnt[s]--;\n                    \n                    int actual = day - start_day[task] + 1;\n                    \n                    double pred_w = 0;\n                    for (int k = 0; k < K; k++) {\n                        pred_w += max(0.0, d[task][k] - skills[m][k]);\n                    }\n                    \n                    TaskResult res;\n                    res.task = task;\n                    res.days = actual;\n                    res.pred_w = pred_w;\n                    res.reqs = d[task];\n                    history[m].push_back(res);\n                    if (history[m].size() > 10) history[m].pop_front();\n                    \n                    // Adaptive skill update\n                    double lr = 0.45 / (1 + tasks_done[m] * 0.012);\n                    \n                    if (actual == 1) {\n                        for (int k = 0; k < K; k++) {\n                            if (d[task][k] > skills[m][k]) {\n                                skills[m][k] = d[task][k] + 1;\n                            }\n                            confidence[m][k] = min(0.98, confidence[m][k] + 0.15);\n                        }\n                    } else if (pred_w > 0.01) {\n                        // Robust update with bias correction\n                        if (history[m].size() >= 3) {\n                            vector<double> errors;\n                            for (auto& h : history[m]) {\n                                if (h.pred_w > 0.01) {\n                                    errors.push_back(h.days - h.pred_w);\n                                }\n                            }\n                            if (!errors.empty()) {\n                                sort(errors.begin(), errors.end());\n                                error_bias[m] = errors[errors.size()/2] * 0.4;\n                                error_bias[m] = max(-2.5, min(2.5, error_bias[m]));\n                                \n                                // Update performance factor\n                                double avg_error = 0;\n                                for (double e : errors) avg_error += abs(e);\n                                avg_error /= errors.size();\n                                performance_factor[m] = 0.9 * performance_factor[m] + 0.1 * (1 + avg_error / 10);\n                                performance_factor[m] = max(0.7, min(1.3, performance_factor[m]));\n                            }\n                        }\n                        \n                        double ratio = actual / pred_w;\n                        \n                        for (int k = 0; k < K; k++) {\n                            double gap = max(0.0, d[task][k] - skills[m][k]);\n                            if (gap > 0) {\n                                skills[m][k] += gap * (1 - ratio) * lr;\n                                skills[m][k] = max(0.0, min(100.0, skills[m][k]));\n                                confidence[m][k] = min(0.95, confidence[m][k] + 0.1);\n                            }\n                        }\n                    }\n                    \n                    tasks_done[m]++;\n                    working[m] = -1;\n                }\n            }\n        }\n    }\n    \n    return 0;\n}","ahc006":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Order {\n    int id;\n    int ax, ay, cx, cy;\n    double score;\n};\n\nint manhattan(int x1, int y1, int x2, int y2) {\n    return abs(x1 - x2) + abs(y1 - y2);\n}\n\nint main() {\n    vector<Order> orders(1000);\n    \n    // Read all orders\n    for (int i = 0; i < 1000; i++) {\n        cin >> orders[i].ax >> orders[i].ay >> orders[i].cx >> orders[i].cy;\n        orders[i].id = i + 1;\n        \n        // Score based on proximity to center and delivery distance\n        int dist_from_center_pickup = manhattan(400, 400, orders[i].ax, orders[i].ay);\n        int dist_from_center_delivery = manhattan(400, 400, orders[i].cx, orders[i].cy);\n        int delivery_dist = manhattan(orders[i].ax, orders[i].ay, orders[i].cx, orders[i].cy);\n        \n        // Prefer orders close to center with reasonable delivery distances\n        orders[i].score = dist_from_center_pickup + dist_from_center_delivery + delivery_dist * 0.3;\n    }\n    \n    // Sort orders by score (lower is better)\n    sort(orders.begin(), orders.end(), [](const Order& a, const Order& b) {\n        return a.score < b.score;\n    });\n    \n    // Select the best 50 orders\n    vector<int> selected_ids;\n    vector<pair<int, int>> pickups, deliveries;\n    \n    for (int i = 0; i < 50; i++) {\n        selected_ids.push_back(orders[i].id);\n        pickups.push_back({orders[i].ax, orders[i].ay});\n        deliveries.push_back({orders[i].cx, orders[i].cy});\n    }\n    \n    // Build route using greedy approach with preference for clearing deliveries\n    vector<pair<int, int>> route;\n    route.push_back({400, 400});\n    \n    vector<bool> picked(50, false);\n    vector<bool> delivered(50, false);\n    int num_delivered = 0;\n    \n    while (num_delivered < 50) {\n        int cur_x = route.back().first;\n        int cur_y = route.back().second;\n        \n        int best_dist = INT_MAX;\n        int best_idx = -1;\n        bool best_is_pickup = false;\n        \n        // Count how many items we're currently carrying\n        int carrying = 0;\n        for (int i = 0; i < 50; i++) {\n            if (picked[i] && !delivered[i]) carrying++;\n        }\n        \n        // If carrying many items, prioritize deliveries\n        double delivery_weight = (carrying > 10) ? 0.7 : 1.0;\n        \n        // Consider pickups\n        for (int i = 0; i < 50; i++) {\n            if (picked[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, pickups[i].first, pickups[i].second);\n            if (dist < best_dist) {\n                best_dist = dist;\n                best_idx = i;\n                best_is_pickup = true;\n            }\n        }\n        \n        // Consider deliveries for items we're carrying\n        for (int i = 0; i < 50; i++) {\n            if (!picked[i] || delivered[i]) continue;\n            \n            int dist = manhattan(cur_x, cur_y, deliveries[i].first, deliveries[i].second);\n            int weighted_dist = dist * delivery_weight;\n            \n            if (weighted_dist < best_dist) {\n                best_dist = weighted_dist;\n                best_idx = i;\n                best_is_pickup = false;\n            }\n        }\n        \n        if (best_is_pickup) {\n            route.push_back(pickups[best_idx]);\n            picked[best_idx] = true;\n        } else {\n            route.push_back(deliveries[best_idx]);\n            delivered[best_idx] = true;\n            num_delivered++;\n        }\n    }\n    \n    // Return to office\n    route.push_back({400, 400});\n    \n    // Output\n    cout << \"50\";\n    for (int id : selected_ids) {\n        cout << \" \" << id;\n    }\n    cout << \"\\n\";\n    \n    cout << route.size();\n    for (const auto& p : route) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc007":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    int components;\n    \n    UnionFind(int n) : parent(n), size(n, 1), components(n) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) {\n            parent[x] = find(parent[x]);\n        }\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        x = find(x);\n        y = find(y);\n        if (x == y) return false;\n        \n        if (size[x] < size[y]) swap(x, y);\n        parent[y] = x;\n        size[x] += size[y];\n        components--;\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n    \n    int getComponents() {\n        return components;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    const int N = 400;\n    const 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<pair<int, int>> edges(M);\n    vector<int> distances(M);\n    \n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].first >> edges[i].second;\n        int dx = coords[edges[i].first].first - coords[edges[i].second].first;\n        int dy = coords[edges[i].first].second - coords[edges[i].second].second;\n        distances[i] = round(sqrt(dx * dx + dy * dy));\n    }\n    \n    UnionFind uf(N);\n    int edges_accepted = 0;\n    int connecting_edges_seen = 0;\n    \n    for (int i = 0; i < M; i++) {\n        int l_i;\n        cin >> l_i;\n        \n        int u = edges[i].first;\n        int v = edges[i].second;\n        int d_i = distances[i];\n        double ratio = (double)l_i / d_i;\n        \n        int decision = 0;\n        \n        if (!uf.connected(u, v)) {\n            // Edge connects different components\n            connecting_edges_seen++;\n            int edges_needed = uf.getComponents() - 1;\n            int remaining_edges = M - i - 1;\n            double progress = (double)i / M;\n            \n            // Calculate dynamic threshold based on multiple factors\n            double threshold = 3.0;  // Default: accept everything\n            \n            if (edges_needed > 0) {\n                // Estimate how many more connecting edges we'll see\n                // Based on ratio of connecting edges seen so far\n                double connecting_ratio = (double)connecting_edges_seen / (i + 1);\n                double expected_connecting = remaining_edges * connecting_ratio;\n                \n                // Real safety factor based on expected connecting edges\n                double real_safety = expected_connecting / edges_needed;\n                \n                // Dynamic threshold based on safety and progress\n                if (real_safety > 8.0 && progress < 0.5) {\n                    threshold = 2.5;  // Be selective early with high safety\n                } else if (real_safety > 5.0 && progress < 0.6) {\n                    threshold = 2.6;\n                } else if (real_safety > 3.0 && progress < 0.7) {\n                    threshold = 2.7;\n                } else if (real_safety > 2.0 && progress < 0.8) {\n                    threshold = 2.8;\n                } else if (real_safety > 1.5) {\n                    threshold = 2.9;\n                }\n                \n                // Extra selectivity for very early edges with lots of components\n                if (i < 50 && edges_needed > 300 && ratio > 2.3) {\n                    threshold = min(threshold, 2.3);\n                }\n            }\n            \n            // Always accept very good edges\n            if (ratio <= 1.2) {\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            } else if (ratio < threshold) {\n                decision = 1;\n                uf.unite(u, v);\n                edges_accepted++;\n            }\n            \n            // Safety override: accept if critically needed\n            if (edges_needed > 0 && remaining_edges <= edges_needed * 1.2) {\n                if (decision == 0) {\n                    decision = 1;\n                    uf.unite(u, v);\n                    edges_accepted++;\n                }\n            }\n        }\n        \n        cout << decision << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc008":"#include <iostream>\n#include <vector>\n#include <string>\n#include <queue>\n#include <set>\n#include <map>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nconst int GRID_SIZE = 30;\nconst int MAX_TURNS = 300;\n\nstruct Position {\n    int x, y;\n    bool operator==(const Position& other) const {\n        return x == other.x && y == other.y;\n    }\n    bool operator<(const Position& other) const {\n        return x < other.x || (x == other.x && y < other.y);\n    }\n};\n\nclass Solver {\nprivate:\n    int N, M;\n    vector<Position> petPos;\n    vector<int> petType;\n    vector<Position> humanPos;\n    vector<vector<bool>> walls;\n    \n    const int dx[4] = {-1, 1, 0, 0};\n    const int dy[4] = {0, 0, -1, 1};\n    const char dirChar[4] = {'U', 'D', 'L', 'R'};\n    const char blockChar[4] = {'u', 'd', 'l', 'r'};\n    \n    Position targetCenter;\n    int targetSize;\n    bool enclosureComplete = false;\n    int completionTurn = -1;\n    \n    bool isValid(int x, int y) const {\n        return x >= 1 && x <= GRID_SIZE && y >= 1 && y <= GRID_SIZE;\n    }\n    \n    bool canMakeWall(int x, int y) const {\n        if (!isValid(x, y) || walls[x][y]) return false;\n        \n        for (const auto& p : petPos) {\n            if (p.x == x && p.y == y) return false;\n        }\n        for (const auto& h : humanPos) {\n            if (h.x == x && h.y == y) return false;\n        }\n        \n        for (int d = 0; d < 4; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            if (isValid(nx, ny)) {\n                for (const auto& p : petPos) {\n                    if (p.x == nx && p.y == ny) return false;\n                }\n            }\n        }\n        \n        return true;\n    }\n    \n    int manhattanDist(int x1, int y1, int x2, int y2) const {\n        return abs(x1 - x2) + abs(y1 - y2);\n    }\n    \n    bool isInsideTarget(int x, int y) const {\n        return abs(x - targetCenter.x) < targetSize && \n               abs(y - targetCenter.y) < targetSize;\n    }\n    \n    bool checkEnclosureComplete() const {\n        // Check if the target area is fully enclosed\n        vector<vector<bool>> visited(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        queue<Position> q;\n        \n        // Start from outside the enclosure\n        q.push({1, 1});\n        visited[1][1] = true;\n        \n        while (!q.empty()) {\n            Position curr = q.front();\n            q.pop();\n            \n            for (int d = 0; d < 4; d++) {\n                int nx = curr.x + dx[d];\n                int ny = curr.y + dy[d];\n                \n                if (!isValid(nx, ny)) continue;\n                if (visited[nx][ny]) continue;\n                if (walls[nx][ny]) continue;\n                \n                // If we can reach inside the target area from outside, not enclosed\n                if (isInsideTarget(nx, ny)) {\n                    return false;\n                }\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return true;\n    }\n    \n    int countPetsInArea(int cx, int cy, int radius) const {\n        int count = 0;\n        for (const auto& p : petPos) {\n            if (abs(p.x - cx) <= radius && abs(p.y - cy) <= radius) {\n                count++;\n            }\n        }\n        return count;\n    }\n    \n    void selectTargetArea() {\n        // Try different areas and sizes\n        vector<tuple<Position, int, double>> candidates;\n        \n        // Corners with different sizes\n        for (int size = 3; size <= 6; size++) {\n            candidates.push_back({{size + 1, size + 1}, size, 0});\n            candidates.push_back({{size + 1, GRID_SIZE - size}, size, 0});\n            candidates.push_back({{GRID_SIZE - size, size + 1}, size, 0});\n            candidates.push_back({{GRID_SIZE - size, GRID_SIZE - size}, size, 0});\n        }\n        \n        // Edges\n        candidates.push_back({{4, 15}, 3, 0});\n        candidates.push_back({{27, 15}, 3, 0});\n        candidates.push_back({{15, 4}, 3, 0});\n        candidates.push_back({{15, 27}, 3, 0});\n        \n        Position bestCenter = {15, 15};\n        int bestSize = 4;\n        double bestScore = -1e9;\n        \n        for (auto& [center, size, _] : candidates) {\n            double score = 0;\n            \n            // Count pets in this area\n            int petsInside = countPetsInArea(center.x, center.y, size);\n            score -= petsInside * 500;\n            \n            // Count dogs specifically\n            for (int i = 0; i < N; i++) {\n                if (petType[i] == 4) {  // Dog\n                    if (abs(petPos[i].x - center.x) <= size && \n                        abs(petPos[i].y - center.y) <= size) {\n                        score -= 300;  // Extra penalty for dogs\n                    }\n                }\n            }\n            \n            // Larger areas are better if no pets inside\n            if (petsInside == 0) {\n                score += size * size * 30;\n            }\n            \n            // Distance from all pets\n            for (const auto& p : petPos) {\n                score += manhattanDist(center.x, center.y, p.x, p.y);\n            }\n            \n            // Distance from humans (prefer closer)\n            for (const auto& h : humanPos) {\n                score -= manhattanDist(center.x, center.y, h.x, h.y) * 0.3;\n            }\n            \n            // Prefer actual corners\n            if ((center.x <= 5 || center.x >= 26) && (center.y <= 5 || center.y >= 26)) {\n                score += 100;\n            }\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestCenter = center;\n                bestSize = size;\n            }\n        }\n        \n        targetCenter = bestCenter;\n        targetSize = bestSize;\n    }\n    \n    vector<Position> getEnclosureWalls() const {\n        vector<Position> result;\n        \n        // Create rectangle perimeter\n        for (int x = targetCenter.x - targetSize; x <= targetCenter.x + targetSize; x++) {\n            for (int y = targetCenter.y - targetSize; y <= targetCenter.y + targetSize; y++) {\n                if (!isValid(x, y)) continue;\n                \n                // Check if it's on the perimeter\n                if (x == targetCenter.x - targetSize || x == targetCenter.x + targetSize ||\n                    y == targetCenter.y - targetSize || y == targetCenter.y + targetSize) {\n                    result.push_back({x, y});\n                }\n            }\n        }\n        \n        return result;\n    }\n    \n    Position findBestWallToBuild(const set<Position>& wallsBeingBuilt) const {\n        auto targetWalls = getEnclosureWalls();\n        \n        Position best = {-1, -1};\n        int bestScore = -1000;\n        \n        // Group walls by priority\n        vector<Position> corners, edges;\n        \n        for (const auto& w : targetWalls) {\n            if (walls[w.x][w.y] || wallsBeingBuilt.count(w)) continue;\n            if (!canMakeWall(w.x, w.y)) continue;\n            \n            bool isCorner = \n                (w.x == targetCenter.x - targetSize || w.x == targetCenter.x + targetSize) &&\n                (w.y == targetCenter.y - targetSize || w.y == targetCenter.y + targetSize);\n            \n            if (isCorner) {\n                corners.push_back(w);\n            } else {\n                edges.push_back(w);\n            }\n        }\n        \n        // Build corners first\n        for (const auto& w : corners) {\n            int score = 1000;\n            \n            // Prefer walls close to humans\n            for (const auto& h : humanPos) {\n                if (manhattanDist(w.x, w.y, h.x, h.y) == 1) {\n                    score += 100;\n                }\n            }\n            \n            // Connect to existing walls\n            int connected = 0;\n            for (int d = 0; d < 4; d++) {\n                int nx = w.x + dx[d];\n                int ny = w.y + dy[d];\n                if (isValid(nx, ny) && walls[nx][ny]) {\n                    connected++;\n                }\n            }\n            score += connected * 50;\n            \n            if (score > bestScore) {\n                bestScore = score;\n                best = w;\n            }\n        }\n        \n        // Then edges, prioritizing gaps\n        if (best.x == -1) {\n            for (const auto& w : edges) {\n                int score = 500;\n                \n                // Prefer walls close to humans\n                for (const auto& h : humanPos) {\n                    if (manhattanDist(w.x, w.y, h.x, h.y) == 1) {\n                        score += 100;\n                    }\n                }\n                \n                // Strongly prefer connecting walls (to close gaps)\n                int connected = 0;\n                for (int d = 0; d < 4; d++) {\n                    int nx = w.x + dx[d];\n                    int ny = w.y + dy[d];\n                    if (isValid(nx, ny) && walls[nx][ny]) {\n                        connected++;\n                    }\n                }\n                score += connected * 200;  // High weight for closing gaps\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    best = w;\n                }\n            }\n        }\n        \n        return best;\n    }\n    \npublic:\n    void solve() {\n        cin >> N;\n        petPos.resize(N);\n        petType.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> petPos[i].x >> petPos[i].y >> petType[i];\n        }\n        \n        cin >> M;\n        humanPos.resize(M);\n        for (int i = 0; i < M; i++) {\n            cin >> humanPos[i].x >> humanPos[i].y;\n        }\n        \n        walls.assign(GRID_SIZE + 1, vector<bool>(GRID_SIZE + 1, false));\n        \n        selectTargetArea();\n        \n        for (int turn = 0; turn < MAX_TURNS; turn++) {\n            string actions(M, '.');\n            set<Position> wallsBeingBuilt;\n            \n            // Check for enclosure completion\n            if (!enclosureComplete && turn >= 50) {\n                if (checkEnclosureComplete()) {\n                    enclosureComplete = true;\n                    completionTurn = turn;\n                }\n            }\n            \n            // Reconsider target if pets get inside (early game only)\n            if (turn == 30 && !enclosureComplete) {\n                int petsInside = 0;\n                for (const auto& p : petPos) {\n                    if (isInsideTarget(p.x, p.y)) {\n                        petsInside++;\n                    }\n                }\n                if (petsInside > 0) {\n                    selectTargetArea();\n                    enclosureComplete = false;\n                }\n            }\n            \n            // Phase 1: Build walls (if not complete)\n            if (!enclosureComplete && turn >= 15) {\n                Position nextWall = findBestWallToBuild(wallsBeingBuilt);\n                \n                while (nextWall.x != -1) {\n                    bool assigned = false;\n                    \n                    // Find closest human who can build this wall\n                    int bestHuman = -1;\n                    int minDist = 1000;\n                    \n                    for (int i = 0; i < M; i++) {\n                        if (actions[i] != '.') continue;\n                        \n                        const Position& human = humanPos[i];\n                        \n                        // Check if adjacent to the wall position\n                        for (int d = 0; d < 4; d++) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            \n                            if (wx == nextWall.x && wy == nextWall.y) {\n                                actions[i] = blockChar[d];\n                                wallsBeingBuilt.insert(nextWall);\n                                assigned = true;\n                                break;\n                            }\n                        }\n                        \n                        if (assigned) break;\n                    }\n                    \n                    if (!assigned) {\n                        break;  // No human can build this wall\n                    }\n                    \n                    nextWall = findBestWallToBuild(wallsBeingBuilt);\n                }\n            }\n            \n            // Phase 2: Movement for non-building humans\n            for (int i = 0; i < M; i++) {\n                if (actions[i] != '.') continue;\n                \n                const Position& human = humanPos[i];\n                \n                // Check for danger\n                bool inDanger = false;\n                for (int j = 0; j < N; j++) {\n                    int dist = manhattanDist(human.x, human.y, petPos[j].x, petPos[j].y);\n                    if ((petType[j] == 4 && dist <= 2) || dist <= 1) {\n                        inDanger = true;\n                        break;\n                    }\n                }\n                \n                if (inDanger) {\n                    // Emergency escape\n                    int bestDir = -1;\n                    double maxSafety = -1;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = human.x + dx[d];\n                        int ny = human.y + dy[d];\n                        \n                        if (isValid(nx, ny) && !walls[nx][ny] && !wallsBeingBuilt.count({nx, ny})) {\n                            double minPetDist = 1000;\n                            for (const auto& p : petPos) {\n                                minPetDist = min(minPetDist, (double)manhattanDist(nx, ny, p.x, p.y));\n                            }\n                            \n                            if (minPetDist > maxSafety) {\n                                maxSafety = minPetDist;\n                                bestDir = d;\n                            }\n                        }\n                    }\n                    \n                    if (bestDir != -1) {\n                        actions[i] = dirChar[bestDir];\n                    }\n                } else if (!enclosureComplete) {\n                    // Move to help build enclosure\n                    Position nextWall = findBestWallToBuild(wallsBeingBuilt);\n                    \n                    if (nextWall.x != -1) {\n                        // Move towards the next wall to build\n                        int bestDir = -1;\n                        int minDist = manhattanDist(human.x, human.y, nextWall.x, nextWall.y);\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            \n                            if (isValid(nx, ny) && !walls[nx][ny] && !wallsBeingBuilt.count({nx, ny})) {\n                                int newDist = manhattanDist(nx, ny, nextWall.x, nextWall.y);\n                                if (newDist < minDist) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                        }\n                    } else if (!isInsideTarget(human.x, human.y)) {\n                        // Move inside target area\n                        int bestDir = -1;\n                        int minDist = manhattanDist(human.x, human.y, targetCenter.x, targetCenter.y);\n                        \n                        for (int d = 0; d < 4; d++) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            \n                            if (isValid(nx, ny) && !walls[nx][ny] && !wallsBeingBuilt.count({nx, ny})) {\n                                int newDist = manhattanDist(nx, ny, targetCenter.x, targetCenter.y);\n                                if (newDist < minDist) {\n                                    minDist = newDist;\n                                    bestDir = d;\n                                }\n                            }\n                        }\n                        \n                        if (bestDir != -1) {\n                            actions[i] = dirChar[bestDir];\n                        }\n                    }\n                }\n            }\n            \n            cout << actions << endl;\n            cout.flush();\n            \n            // Apply actions\n            for (int i = 0; i < M; i++) {\n                char action = actions[i];\n                Position& human = humanPos[i];\n                \n                if (action == 'U' || action == 'D' || action == 'L' || action == 'R') {\n                    for (int d = 0; d < 4; d++) {\n                        if (dirChar[d] == action) {\n                            int nx = human.x + dx[d];\n                            int ny = human.y + dy[d];\n                            \n                            if (isValid(nx, ny) && !walls[nx][ny]) {\n                                bool blocked = false;\n                                for (int j = 0; j < M; j++) {\n                                    if (i != j && (actions[j] == 'u' || actions[j] == 'd' || \n                                                   actions[j] == 'l' || actions[j] == 'r')) {\n                                        for (int dd = 0; dd < 4; dd++) {\n                                            if (blockChar[dd] == actions[j]) {\n                                                int wx = humanPos[j].x + dx[dd];\n                                                int wy = humanPos[j].y + dy[dd];\n                                                if (wx == nx && wy == ny) {\n                                                    blocked = true;\n                                                    break;\n                                                }\n                                            }\n                                        }\n                                    }\n                                    if (blocked) break;\n                                }\n                                \n                                if (!blocked) {\n                                    human.x = nx;\n                                    human.y = ny;\n                                }\n                            }\n                            break;\n                        }\n                    }\n                } else if (action == 'u' || action == 'd' || action == 'l' || action == 'r') {\n                    for (int d = 0; d < 4; d++) {\n                        if (blockChar[d] == action) {\n                            int wx = human.x + dx[d];\n                            int wy = human.y + dy[d];\n                            if (isValid(wx, wy)) {\n                                walls[wx][wy] = true;\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            // Read pet movements\n            for (int i = 0; i < N; i++) {\n                string petMove;\n                cin >> petMove;\n                \n                for (char c : petMove) {\n                    if (c != '.') {\n                        for (int d = 0; d < 4; d++) {\n                            if (dirChar[d] == c) {\n                                petPos[i].x += dx[d];\n                                petPos[i].y += dy[d];\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solver solver;\n    solver.solve();\n    \n    return 0;\n}","ahc009":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <string>\n#include <algorithm>\n#include <cmath>\n\nusing namespace std;\n\nint main() {\n    int si, sj, ti, tj;\n    double p;\n    cin >> si >> sj >> ti >> tj >> p;\n    \n    vector<string> h(20), v(19);\n    for (int i = 0; i < 20; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < 19; i++) {\n        cin >> v[i];\n    }\n    \n    // Build wall information\n    vector<vector<bool>> canGoRight(20, vector<bool>(20, false));\n    vector<vector<bool>> canGoDown(20, vector<bool>(20, false));\n    \n    for (int i = 0; i < 20; i++) {\n        for (int j = 0; j < 19; j++) {\n            if (h[i][j] == '0') {\n                canGoRight[i][j] = true;\n            }\n        }\n    }\n    \n    for (int i = 0; i < 19; i++) {\n        for (int j = 0; j < 20; j++) {\n            if (v[i][j] == '0') {\n                canGoDown[i][j] = true;\n            }\n        }\n    }\n    \n    // BFS to find shortest path\n    queue<pair<int,int>> q;\n    vector<vector<int>> dist(20, vector<int>(20, -1));\n    vector<vector<pair<int,int>>> parent(20, vector<pair<int,int>>(20, {-1, -1}));\n    \n    q.push({si, sj});\n    dist[si][sj] = 0;\n    \n    while (!q.empty()) {\n        auto [i, j] = q.front();\n        q.pop();\n        \n        if (j < 19 && canGoRight[i][j] && dist[i][j+1] == -1) {\n            dist[i][j+1] = dist[i][j] + 1;\n            parent[i][j+1] = {i, j};\n            q.push({i, j+1});\n        }\n        if (j > 0 && canGoRight[i][j-1] && dist[i][j-1] == -1) {\n            dist[i][j-1] = dist[i][j] + 1;\n            parent[i][j-1] = {i, j};\n            q.push({i, j-1});\n        }\n        if (i < 19 && canGoDown[i][j] && dist[i+1][j] == -1) {\n            dist[i+1][j] = dist[i][j] + 1;\n            parent[i+1][j] = {i, j};\n            q.push({i+1, j});\n        }\n        if (i > 0 && canGoDown[i-1][j] && dist[i-1][j] == -1) {\n            dist[i-1][j] = dist[i][j] + 1;\n            parent[i-1][j] = {i, j};\n            q.push({i-1, j});\n        }\n    }\n    \n    // Reconstruct shortest path\n    string shortestPath;\n    int ci = ti, cj = tj;\n    \n    while (ci != si || cj != sj) {\n        auto [pi, pj] = parent[ci][cj];\n        \n        if (ci - pi == 1) shortestPath = \"D\" + shortestPath;\n        else if (ci - pi == -1) shortestPath = \"U\" + shortestPath;\n        else if (cj - pj == 1) shortestPath = \"R\" + shortestPath;\n        else shortestPath = \"L\" + shortestPath;\n        \n        ci = pi;\n        cj = pj;\n    }\n    \n    int pathLen = shortestPath.length();\n    string result;\n    \n    // Very slightly adjusted thresholds\n    int baseRepeat = 1;\n    \n    if (p >= 0.485) {\n        baseRepeat = 4;  // Very high forget rate (slightly raised threshold)\n    } else if (p >= 0.425) {\n        baseRepeat = 3;  // High forget rate (slightly lowered)\n    } else if (p >= 0.325) {\n        baseRepeat = 2;  // Medium-high forget rate (slightly lowered)\n    } else if (p >= 0.225) {\n        baseRepeat = 2;  // Medium forget rate (slightly lowered)\n    } else if (p >= 0.15) {\n        baseRepeat = 1;  // Low-medium forget rate\n    } else {\n        baseRepeat = 1;  // Low forget rate\n    }\n    \n    // Build result\n    int expandedLen = pathLen * baseRepeat;\n    \n    if (expandedLen <= 200) {\n        // Add path with move repetitions\n        for (char move : shortestPath) {\n            for (int r = 0; r < baseRepeat; r++) {\n                result += move;\n            }\n        }\n        \n        // Repeat entire expanded sequence\n        while (result.length() + expandedLen <= 200) {\n            for (char move : shortestPath) {\n                for (int r = 0; r < baseRepeat; r++) {\n                    result += move;\n                }\n            }\n        }\n        \n        // Fill remainder by cycling through original path\n        int idx = 0;\n        while (result.length() < 200) {\n            result += shortestPath[idx % pathLen];\n            idx++;\n        }\n    } else {\n        // Path too long for full repetition\n        int maxRepeat = 200 / pathLen;\n        \n        if (maxRepeat >= 2) {\n            int useRepeat = min(baseRepeat, maxRepeat);\n            \n            for (char move : shortestPath) {\n                for (int r = 0; r < useRepeat && result.length() < 200; r++) {\n                    result += move;\n                }\n            }\n        } else {\n            result = shortestPath;\n        }\n        \n        // Fill remainder\n        int idx = 0;\n        while (result.length() < 200) {\n            result += shortestPath[idx % pathLen];\n            idx++;\n        }\n    }\n    \n    // Ensure max 200 chars\n    if (result.length() > 200) {\n        result = result.substr(0, 200);\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc010":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\nint tiles[N][N];\nint rotations[N][N];\n\nconst int di[] = {0, -1, 0, 1};\nconst int dj[] = {-1, 0, 1, 0};\n\nconst int to[8][4] = {\n    {1, 0, -1, -1},\n    {3, -1, -1, 0},\n    {-1, -1, 3, 2},\n    {-1, 2, 1, -1},\n    {1, 0, 3, 2},\n    {3, 2, 1, 0},\n    {2, -1, 0, -1},\n    {-1, 3, -1, 1}\n};\n\nint rotate_tile(int tile) {\n    if (tile <= 3) return (tile + 1) % 4;\n    if (tile == 4) return 5;\n    if (tile == 5) return 4;\n    if (tile == 6) return 7;\n    return 6;\n}\n\nint get_tile_state(int i, int j) {\n    int t = tiles[i][j];\n    for (int r = 0; r < rotations[i][j]; r++) {\n        t = rotate_tile(t);\n    }\n    return t;\n}\n\nint trace_path(int si, int sj, int sd, vector<vector<vector<bool>>>& visited) {\n    int i = si, j = sj, d = sd;\n    int length = 0;\n    \n    do {\n        if (visited[i][j][d]) return 0;\n        \n        int tile_state = get_tile_state(i, j);\n        int d2 = to[tile_state][d];\n        if (d2 == -1) return 0;\n        \n        int ni = i + di[d2];\n        int nj = j + dj[d2];\n        if (ni < 0 || ni >= N || nj < 0 || nj >= N) return 0;\n        \n        i = ni;\n        j = nj;\n        d = (d2 + 2) % 4;\n        length++;\n        \n        if (length > N * N * 4) return 0;\n    } while (!(i == si && j == sj && d == sd));\n    \n    return length;\n}\n\nint calculate_score() {\n    vector<vector<vector<bool>>> visited(N, vector<vector<bool>>(N, vector<bool>(4, false)));\n    vector<int> loops;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            for (int d = 0; d < 4; d++) {\n                if (visited[i][j][d]) continue;\n                \n                int len = trace_path(i, j, d, visited);\n                if (len > 0) {\n                    loops.push_back(len);\n                    \n                    int ci = i, cj = j, cd = d;\n                    for (int step = 0; step < len; step++) {\n                        visited[ci][cj][cd] = true;\n                        int tile_state = get_tile_state(ci, cj);\n                        int d2 = to[tile_state][cd];\n                        ci += di[d2];\n                        cj += dj[d2];\n                        cd = (d2 + 2) % 4;\n                    }\n                }\n            }\n        }\n    }\n    \n    if (loops.size() < 2) return 0;\n    sort(loops.rbegin(), loops.rend());\n    return loops[0] * loops[1];\n}\n\nvoid greedy_init() {\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            int best_rot = 0;\n            int best_score = -1000;\n            \n            for (int r = 0; r < 4; r++) {\n                rotations[i][j] = r;\n                int score = 0;\n                int tile_state = get_tile_state(i, j);\n                \n                for (int d = 0; d < 4; d++) {\n                    int d2 = to[tile_state][d];\n                    if (d2 == -1) continue;\n                    \n                    int ni = i + di[d2];\n                    int nj = j + dj[d2];\n                    if (ni < 0 || ni >= N || nj < 0 || nj >= N) continue;\n                    \n                    score += 5;\n                    \n                    int neighbor_state = get_tile_state(ni, nj);\n                    int return_dir = (d2 + 2) % 4;\n                    if (to[neighbor_state][return_dir] != -1) {\n                        score += 15;\n                    }\n                }\n                \n                // Prefer tiles that can create multiple loops\n                if (tiles[i][j] == 4 || tiles[i][j] == 5) {\n                    score += 3;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_rot = r;\n                }\n            }\n            \n            rotations[i][j] = best_rot;\n        }\n    }\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    for (int i = 0; i < N; i++) {\n        string s;\n        cin >> s;\n        for (int j = 0; j < N; j++) {\n            tiles[i][j] = s[j] - '0';\n        }\n    }\n    \n    random_device rd;\n    mt19937 rng(rd());\n    uniform_int_distribution<int> rot_dist(0, 3);\n    uniform_int_distribution<int> pos_dist(0, N-1);\n    uniform_real_distribution<double> prob_dist(0.0, 1.0);\n    \n    // Initialize\n    greedy_init();\n    \n    int best_score = calculate_score();\n    int best_rotations[N][N];\n    memcpy(best_rotations, rotations, sizeof(rotations));\n    \n    auto start_time = chrono::steady_clock::now();\n    int iteration = 0;\n    int no_improve = 0;\n    int restart_count = 0;\n    \n    // Main optimization loop\n    while (chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - start_time).count() < 1800) {\n        iteration++;\n        \n        // Smart restart strategy\n        if (no_improve > 8000) {\n            restart_count++;\n            \n            if (restart_count % 4 == 0) {\n                // Complete random restart\n                for (int i = 0; i < N; i++) {\n                    for (int j = 0; j < N; j++) {\n                        rotations[i][j] = rot_dist(rng);\n                    }\n                }\n            } else if (restart_count % 4 == 1) {\n                // Fresh greedy initialization\n                greedy_init();\n            } else if (restart_count % 4 == 2) {\n                // Start from best with heavy perturbation\n                memcpy(rotations, best_rotations, sizeof(rotations));\n                for (int k = 0; k < N * N / 3; k++) {\n                    rotations[pos_dist(rng)][pos_dist(rng)] = rot_dist(rng);\n                }\n            } else {\n                // Start from best with light perturbation\n                memcpy(rotations, best_rotations, sizeof(rotations));\n                for (int k = 0; k < N * N / 10; k++) {\n                    rotations[pos_dist(rng)][pos_dist(rng)] = rot_dist(rng);\n                }\n            }\n            no_improve = 0;\n        }\n        \n        // Adaptive move selection based on progress\n        vector<pair<pair<int,int>, int>> changes;\n        int move_type;\n        \n        if (iteration < 5000) {\n            // Early phase: more aggressive moves\n            move_type = rng() % 100;\n            if (move_type < 40) move_type = 0;      // 40% single\n            else if (move_type < 70) move_type = 1;  // 30% 2x2\n            else if (move_type < 85) move_type = 2;  // 15% 3x3\n            else move_type = 3;                      // 15% line\n        } else {\n            // Later phase: more conservative\n            move_type = rng() % 100;\n            if (move_type < 60) move_type = 0;      // 60% single\n            else if (move_type < 85) move_type = 1;  // 25% 2x2\n            else if (move_type < 95) move_type = 2;  // 10% 3x3\n            else move_type = 3;                      // 5% line\n        }\n        \n        if (move_type == 0) {\n            // Single tile\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            int old_rot = rotations[i][j];\n            int new_rot = rot_dist(rng);\n            if (new_rot == old_rot) continue;\n            changes.push_back({{i, j}, old_rot});\n            rotations[i][j] = new_rot;\n        } else if (move_type == 1) {\n            // 2x2 block\n            int i = rng() % (N-1);\n            int j = rng() % (N-1);\n            for (int di = 0; di < 2; di++) {\n                for (int dj = 0; dj < 2; dj++) {\n                    changes.push_back({{i+di, j+dj}, rotations[i+di][j+dj]});\n                    rotations[i+di][j+dj] = rot_dist(rng);\n                }\n            }\n        } else if (move_type == 2) {\n            // 3x3 block\n            int i = rng() % max(1, N-2);\n            int j = rng() % max(1, N-2);\n            for (int di = 0; di < min(3, N-i); di++) {\n                for (int dj = 0; dj < min(3, N-j); dj++) {\n                    changes.push_back({{i+di, j+dj}, rotations[i+di][j+dj]});\n                    rotations[i+di][j+dj] = rot_dist(rng);\n                }\n            }\n        } else {\n            // Line (row or column)\n            if (rng() % 2 == 0) {\n                int i = pos_dist(rng);\n                for (int j = 0; j < N; j++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            } else {\n                int j = pos_dist(rng);\n                for (int i = 0; i < N; i++) {\n                    changes.push_back({{i, j}, rotations[i][j]});\n                    rotations[i][j] = rot_dist(rng);\n                }\n            }\n        }\n        \n        int new_score = calculate_score();\n        \n        if (new_score > best_score) {\n            best_score = new_score;\n            memcpy(best_rotations, rotations, sizeof(rotations));\n            no_improve = 0;\n        } else {\n            no_improve++;\n            \n            // Dynamic temperature based on actual iteration count\n            double temp = 50.0 * exp(-iteration / 10000.0);\n            temp = max(temp, 0.1);\n            \n            if (prob_dist(rng) >= exp((new_score - best_score) / temp)) {\n                // Reject\n                for (auto& [pos, old_val] : changes) {\n                    rotations[pos.first][pos.second] = old_val;\n                }\n            }\n        }\n    }\n    \n    // Final optimization phase - use remaining time efficiently\n    memcpy(rotations, best_rotations, sizeof(rotations));\n    auto opt_start = chrono::steady_clock::now();\n    bool improved = true;\n    \n    // Systematic check if we have time\n    while (improved && chrono::duration_cast<chrono::milliseconds>(chrono::steady_clock::now() - opt_start).count() < 100) {\n        improved = false;\n        \n        // Random sample of positions to check\n        for (int attempt = 0; attempt < 100 && !improved; attempt++) {\n            int i = pos_dist(rng);\n            int j = pos_dist(rng);\n            int original = rotations[i][j];\n            \n            for (int r = 0; r < 4; r++) {\n                if (r == original) continue;\n                rotations[i][j] = r;\n                int score = calculate_score();\n                \n                if (score > best_score) {\n                    best_score = score;\n                    memcpy(best_rotations, rotations, sizeof(rotations));\n                    improved = true;\n                    break;\n                }\n            }\n            \n            if (!improved) {\n                rotations[i][j] = original;\n            }\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cout << best_rotations[i][j];\n        }\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc011":"#include <bits/stdc++.h>\nusing namespace std;\nusing namespace chrono;\n\nint N, T;\nvector<vector<int>> board;\npair<int, int> empty_pos;\nvector<char> answer;\nmt19937 rng(42);\nauto start_time = steady_clock::now();\n\nconst int LEFT = 1, UP = 2, RIGHT = 4, DOWN = 8;\nconst int dx[] = {-1, 1, 0, 0};\nconst int dy[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\nconst int opposite_dir[] = {1, 0, 3, 2};\n\nbool in_bounds(int x, int y) {\n    return x >= 0 && x < N && y >= 0 && y < N;\n}\n\ndouble elapsed_time() {\n    return duration_cast<milliseconds>(steady_clock::now() - start_time).count() / 1000.0;\n}\n\nvoid make_move(int dir) {\n    int nx = empty_pos.first + dx[dir];\n    int ny = empty_pos.second + dy[dir];\n    if (in_bounds(nx, ny)) {\n        swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n        empty_pos = {nx, ny};\n        answer.push_back(dir_char[dir]);\n    }\n}\n\nstruct CompInfo {\n    int max_tree;\n    int total_edges;\n    int num_components;\n    vector<int> comp_sizes;\n    vector<vector<pair<int,int>>> comp_cells;\n};\n\nCompInfo analyze_board_detailed(const vector<vector<int>>& b) {\n    CompInfo info = {0, 0, 0};\n    vector<int> parent(N * N);\n    vector<int> size(N * N, 0);\n    vector<int> edges(N * N, 0);\n    iota(parent.begin(), parent.end(), 0);\n    \n    function<int(int)> find = [&](int x) {\n        return parent[x] == x ? x : parent[x] = find(parent[x]);\n    };\n    \n    // Build components\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] == 0) continue;\n            int id = i * N + j;\n            size[id] = 1;\n            \n            if (i < N-1 && b[i+1][j] != 0 && \n                (b[i][j] & DOWN) && (b[i+1][j] & UP)) {\n                int id2 = (i+1) * N + j;\n                int r1 = find(id), r2 = find(id2);\n                if (r1 != r2) {\n                    parent[r2] = r1;\n                    size[r1] += size[r2];\n                    edges[r1] += edges[r2] + 1;\n                    size[r2] = 0;\n                } else {\n                    edges[r1]++;\n                }\n                info.total_edges++;\n            }\n            \n            if (j < N-1 && b[i][j+1] != 0 && \n                (b[i][j] & RIGHT) && (b[i][j+1] & LEFT)) {\n                int id2 = i * N + (j+1);\n                int r1 = find(id), r2 = find(id2);\n                if (r1 != r2) {\n                    parent[r2] = r1;\n                    size[r1] += size[r2];\n                    edges[r1] += edges[r2] + 1;\n                    size[r2] = 0;\n                } else {\n                    edges[r1]++;\n                }\n                info.total_edges++;\n            }\n        }\n    }\n    \n    // Collect component info\n    map<int, vector<pair<int,int>>> comp_map;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] != 0) {\n                int root = find(i * N + j);\n                comp_map[root].push_back({i, j});\n            }\n        }\n    }\n    \n    for (auto& [root, cells] : comp_map) {\n        info.num_components++;\n        info.comp_sizes.push_back(cells.size());\n        info.comp_cells.push_back(cells);\n        \n        if (edges[root] == (int)cells.size() - 1) {\n            info.max_tree = max(info.max_tree, (int)cells.size());\n        }\n    }\n    \n    return info;\n}\n\ndouble evaluate_advanced(const vector<vector<int>>& b, const pair<int,int>& e) {\n    auto info = analyze_board_detailed(b);\n    \n    double score = info.max_tree * 1000000.0;\n    \n    // Heavy penalty for multiple components\n    if (info.num_components > 1) {\n        score -= (info.num_components - 1) * 5000.0;\n    }\n    \n    // Reward total edges\n    score += info.total_edges * 500.0;\n    \n    // Reward largest component even if not tree\n    if (!info.comp_sizes.empty()) {\n        int largest = *max_element(info.comp_sizes.begin(), info.comp_sizes.end());\n        score += largest * 2000.0;\n    }\n    \n    // Count merge opportunities\n    int merge_ops = 0;\n    set<pair<pair<int,int>, pair<int,int>>> checked;\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (b[i][j] == 0) continue;\n            \n            // Check adjacent cells\n            for (int d = 0; d < 4; d++) {\n                int ni = i + dx[d];\n                int nj = j + dy[d];\n                if (!in_bounds(ni, nj) || b[ni][nj] == 0) continue;\n                \n                pair<int,int> p1 = {i, j}, p2 = {ni, nj};\n                if (p1 > p2) swap(p1, p2);\n                if (checked.count({p1, p2})) continue;\n                checked.insert({p1, p2});\n                \n                bool connected = false;\n                bool could_connect = false;\n                \n                if (d == 0) { // UP\n                    connected = (b[i][j] & UP) && (b[ni][nj] & DOWN);\n                    could_connect = (b[i][j] & UP) || (b[ni][nj] & DOWN);\n                } else if (d == 1) { // DOWN\n                    connected = (b[i][j] & DOWN) && (b[ni][nj] & UP);\n                    could_connect = (b[i][j] & DOWN) || (b[ni][nj] & UP);\n                } else if (d == 2) { // LEFT\n                    connected = (b[i][j] & LEFT) && (b[ni][nj] & RIGHT);\n                    could_connect = (b[i][j] & LEFT) || (b[ni][nj] & RIGHT);\n                } else { // RIGHT\n                    connected = (b[i][j] & RIGHT) && (b[ni][nj] & LEFT);\n                    could_connect = (b[i][j] & RIGHT) || (b[ni][nj] & LEFT);\n                }\n                \n                if (!connected && could_connect) {\n                    merge_ops++;\n                }\n            }\n        }\n    }\n    score += merge_ops * 50.0;\n    \n    // Empty position quality\n    int empty_neighbors = 0;\n    for (int d = 0; d < 4; d++) {\n        if (in_bounds(e.first + dx[d], e.second + dy[d])) {\n            empty_neighbors++;\n        }\n    }\n    score += empty_neighbors * 5.0;\n    \n    return score;\n}\n\nstruct State {\n    vector<vector<int>> board;\n    pair<int,int> empty;\n    vector<int> moves;\n    double score;\n    int tree_size;\n    \n    uint64_t hash() const {\n        uint64_t h = 0;\n        for (int i = 0; i < board.size(); i++) {\n            for (int j = 0; j < board[i].size(); j++) {\n                h = h * 31 + board[i][j];\n            }\n        }\n        h = h * 31 + empty.first;\n        h = h * 31 + empty.second;\n        return h;\n    }\n};\n\nvector<int> enhanced_beam_search(double time_limit) {\n    unordered_set<uint64_t> visited;\n    State best_found;\n    best_found.board = board;\n    best_found.empty = empty_pos;\n    best_found.score = evaluate_advanced(board, empty_pos);\n    auto initial_info = analyze_board_detailed(board);\n    best_found.tree_size = initial_info.max_tree;\n    \n    // Dynamic beam configurations based on problem state\n    vector<pair<int,int>> configs;\n    if (initial_info.num_components > 3) {\n        configs = {{60, 5}, {30, 7}, {15, 9}}; // Need aggressive search\n    } else if (initial_info.max_tree > N * N * 0.7) {\n        configs = {{20, 10}, {10, 12}}; // Close to solution, search deeper\n    } else {\n        configs = {{40, 6}, {20, 8}, {10, 10}}; // Standard search\n    }\n    \n    for (auto [width, max_depth] : configs) {\n        if (elapsed_time() > time_limit) break;\n        \n        for (int target_depth = 3; target_depth <= max_depth; target_depth += 2) {\n            if (elapsed_time() > time_limit) break;\n            \n            vector<State> beam;\n            State init;\n            init.board = board;\n            init.empty = empty_pos;\n            init.score = best_found.score;\n            init.tree_size = best_found.tree_size;\n            beam.push_back(init);\n            visited.clear();\n            visited.insert(init.hash());\n            \n            for (int d = 0; d < target_depth && elapsed_time() < time_limit; d++) {\n                vector<State> next_beam;\n                \n                for (const auto& state : beam) {\n                    for (int dir = 0; dir < 4; dir++) {\n                        if (!state.moves.empty() && dir == opposite_dir[state.moves.back()]) \n                            continue;\n                        \n                        int nx = state.empty.first + dx[dir];\n                        int ny = state.empty.second + dy[dir];\n                        if (!in_bounds(nx, ny)) continue;\n                        \n                        State ns;\n                        ns.board = state.board;\n                        ns.empty = {nx, ny};\n                        swap(ns.board[state.empty.first][state.empty.second], \n                             ns.board[nx][ny]);\n                        ns.moves = state.moves;\n                        ns.moves.push_back(dir);\n                        \n                        // Skip if visited\n                        uint64_t h = ns.hash();\n                        if (visited.count(h)) continue;\n                        visited.insert(h);\n                        \n                        // Evaluate\n                        if (d == target_depth - 1 || width <= 10) {\n                            ns.score = evaluate_advanced(ns.board, ns.empty);\n                            auto comp_info = analyze_board_detailed(ns.board);\n                            ns.tree_size = comp_info.max_tree;\n                        } else {\n                            // Quick evaluation\n                            int edges = 0;\n                            for (int i = 0; i < N; i++) {\n                                for (int j = 0; j < N; j++) {\n                                    if (ns.board[i][j] == 0) continue;\n                                    if (i < N-1 && ns.board[i+1][j] != 0 && \n                                        (ns.board[i][j] & DOWN) && (ns.board[i+1][j] & UP)) edges++;\n                                    if (j < N-1 && ns.board[i][j+1] != 0 && \n                                        (ns.board[i][j] & RIGHT) && (ns.board[i][j+1] & LEFT)) edges++;\n                                }\n                            }\n                            ns.score = edges * 1000.0;\n                            ns.tree_size = state.tree_size;\n                        }\n                        \n                        next_beam.push_back(ns);\n                    }\n                }\n                \n                if (next_beam.empty()) break;\n                \n                // Advanced pruning\n                sort(next_beam.begin(), next_beam.end(), \n                     [](const State& a, const State& b) {\n                         if (abs(a.tree_size - b.tree_size) > 5) \n                             return a.tree_size > b.tree_size;\n                         return a.score > b.score;\n                     });\n                \n                beam.clear();\n                int keep = min(width, (int)next_beam.size());\n                \n                // Diversity preservation\n                set<int> tree_sizes_kept;\n                for (int i = 0; i < next_beam.size() && beam.size() < keep; i++) {\n                    if (tree_sizes_kept.size() < 3 || \n                        tree_sizes_kept.count(next_beam[i].tree_size) ||\n                        next_beam[i].tree_size > best_found.tree_size) {\n                        beam.push_back(next_beam[i]);\n                        tree_sizes_kept.insert(next_beam[i].tree_size);\n                        \n                        if (next_beam[i].tree_size > best_found.tree_size ||\n                            (next_beam[i].tree_size == best_found.tree_size && \n                             next_beam[i].score > best_found.score)) {\n                            best_found = next_beam[i];\n                        }\n                        \n                        if (next_beam[i].tree_size == N * N - 1) {\n                            return next_beam[i].moves;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    return best_found.moves;\n}\n\nvoid solve() {\n    auto initial = analyze_board_detailed(board);\n    int best_tree = initial.max_tree;\n    int stagnation = 0;\n    int phase = 0; // 0: exploration, 1: exploitation\n    \n    while (answer.size() < T && elapsed_time() < 2.95) {\n        // Progress check\n        if (answer.size() % 20 == 0) {\n            auto info = analyze_board_detailed(board);\n            if (info.max_tree > best_tree) {\n                best_tree = info.max_tree;\n                stagnation = 0;\n                \n                // Switch to exploitation when close\n                if (best_tree > N * N * 0.85) phase = 1;\n            }\n            \n            if (best_tree == N * N - 1) break;\n        }\n        \n        double time_left = 2.95 - elapsed_time();\n        int moves_left = T - answer.size();\n        \n        // Time allocation\n        double search_time = min(0.3, time_left * 0.25);\n        if (phase == 1) search_time = min(0.15, time_left * 0.15);\n        if (moves_left < 50) search_time = min(0.05, time_left * 0.1);\n        \n        // Search\n        auto save_board = board;\n        auto save_empty = empty_pos;\n        \n        vector<int> moves = enhanced_beam_search(elapsed_time() + search_time);\n        \n        board = save_board;\n        empty_pos = save_empty;\n        \n        if (!moves.empty()) {\n            int apply = min((int)moves.size(), max(1, min(5, moves_left / 100 + 1)));\n            if (phase == 1) apply = min(apply, 2); // More careful in exploitation\n            \n            for (int i = 0; i < apply && answer.size() < T; i++) {\n                make_move(moves[i]);\n            }\n            stagnation = 0;\n        } else {\n            stagnation++;\n        }\n        \n        // Advanced restart strategies\n        if (stagnation > 40 || (stagnation > 20 && rng() % 100 < 40)) {\n            auto current_info = analyze_board_detailed(board);\n            \n            if (current_info.num_components > 2) {\n                // Try to merge components\n                for (int attempt = 0; attempt < 8 && answer.size() < T; attempt++) {\n                    double best_score = -1e9;\n                    int best_dir = -1;\n                    \n                    for (int d = 0; d < 4; d++) {\n                        int nx = empty_pos.first + dx[d];\n                        int ny = empty_pos.second + dy[d];\n                        if (in_bounds(nx, ny)) {\n                            swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                            auto old_e = empty_pos;\n                            empty_pos = {nx, ny};\n                            \n                            auto new_info = analyze_board_detailed(board);\n                            double score = new_info.num_components * -1000 + new_info.total_edges * 10;\n                            \n                            empty_pos = old_e;\n                            swap(board[empty_pos.first][empty_pos.second], board[nx][ny]);\n                            \n                            if (score > best_score) {\n                                best_score = score;\n                                best_dir = d;\n                            }\n                        }\n                    }\n                    \n                    if (best_dir != -1) make_move(best_dir);\n                }\n            } else {\n                // Random perturbation\n                for (int i = 0; i < 6 && answer.size() < T; i++) {\n                    vector<int> dirs;\n                    for (int d = 0; d < 4; d++) {\n                        if (in_bounds(empty_pos.first + dx[d], empty_pos.second + dy[d])) {\n                            dirs.push_back(d);\n                        }\n                    }\n                    if (!dirs.empty()) {\n                        make_move(dirs[rng() % dirs.size()]);\n                    }\n                }\n            }\n            stagnation = 0;\n        }\n    }\n}\n\nint main() {\n    start_time = steady_clock::now();\n    \n    cin >> N >> T;\n    board.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N; i++) {\n        string line;\n        cin >> line;\n        for (int j = 0; j < N; j++) {\n            if (line[j] >= '0' && line[j] <= '9') {\n                board[i][j] = line[j] - '0';\n            } else {\n                board[i][j] = line[j] - 'a' + 10;\n            }\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (board[i][j] == 0) {\n                empty_pos = {i, j};\n                break;\n            }\n        }\n    }\n    \n    solve();\n    \n    for (char c : answer) cout << c;\n    cout << endl;\n    \n    return 0;\n}","ahc012":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst double RADIUS = 10000.0;\nconst double EPS = 1e-9;\nconst double TIME_LIMIT = 2.8;\n\nstruct Point {\n    double x, y;\n    Point(double x = 0, double y = 0) : x(x), y(y) {}\n    Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }\n    Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }\n    Point operator*(double t) const { return Point(x * t, y * t); }\n    double norm2() const { return x * x + y * y; }\n    double norm() const { return sqrt(norm2()); }\n};\n\nstruct Line {\n    int px, py, qx, qy;\n    Line(int px = 0, int py = 0, int qx = 0, int qy = 0) : px(px), py(py), qx(qx), qy(qy) {}\n    \n    int side(const Point& p) const {\n        double dx1 = qx - px;\n        double dy1 = qy - py;\n        double dx2 = p.x - px;\n        double dy2 = p.y - py;\n        double v = dx1 * dy2 - dy1 * dx2;\n        if (v > EPS) return 1;\n        if (v < -EPS) return -1;\n        return 0;\n    }\n};\n\nint N, K;\nvector<int> a(11);\nvector<Point> strawberries;\nvector<Line> lines;\nvector<Line> bestLines;\nint bestScore = 0;\nvector<int> deficit(11);\nvector<int> priority(11);\n\nmt19937 rng(chrono::steady_clock::now().time_since_epoch().count());\n\nbool insideCircle(const Point& p) {\n    return p.norm2() < RADIUS * RADIUS - EPS;\n}\n\npair<int, vector<int>> calculateScoreWithDetails() {\n    map<vector<int>, int> regionCount;\n    \n    for (int i = 0; i < N; i++) {\n        if (!insideCircle(strawberries[i])) continue;\n        \n        vector<int> sideVector;\n        bool onLine = false;\n        \n        for (const Line& line : lines) {\n            int s = line.side(strawberries[i]);\n            if (s == 0) {\n                onLine = true;\n                break;\n            }\n            sideVector.push_back(s);\n        }\n        \n        if (!onLine) {\n            regionCount[sideVector]++;\n        }\n    }\n    \n    vector<int> b(11, 0);\n    for (auto& [region, cnt] : regionCount) {\n        if (cnt <= 10) b[cnt]++;\n    }\n    \n    int score = 0;\n    for (int d = 1; d <= 10; d++) {\n        score += min(a[d], b[d]);\n        deficit[d] = max(0, a[d] - b[d]);\n    }\n    \n    // Update priorities based on deficit and value\n    for (int d = 1; d <= 10; d++) {\n        priority[d] = deficit[d] * d;  // Weight by both deficit and count value\n    }\n    \n    return {score, b};\n}\n\nint calculateScore() {\n    return calculateScoreWithDetails().first;\n}\n\n// Get top priority targets\nvector<int> getPriorityTargets() {\n    vector<pair<int, int>> targets;\n    for (int d = 1; d <= 10; d++) {\n        if (deficit[d] > 0) {\n            targets.push_back({priority[d], d});\n        }\n    }\n    sort(targets.rbegin(), targets.rend());\n    \n    vector<int> result;\n    for (int i = 0; i < min(3, (int)targets.size()); i++) {\n        result.push_back(targets[i].second);\n    }\n    return result;\n}\n\nLine randomLine() {\n    uniform_int_distribution<int> coord_dist(-20000, 20000);\n    int px = coord_dist(rng);\n    int py = coord_dist(rng);\n    int qx = coord_dist(rng);\n    int qy = coord_dist(rng);\n    while (px == qx && py == qy) {\n        qx = coord_dist(rng);\n        qy = coord_dist(rng);\n    }\n    return Line(px, py, qx, qy);\n}\n\nLine targetedLine() {\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    int i = idx_dist(rng);\n    int j = idx_dist(rng);\n    while (i == j) j = idx_dist(rng);\n    \n    Point mid = (strawberries[i] + strawberries[j]) * 0.5;\n    Point dir = strawberries[j] - strawberries[i];\n    \n    if (dir.norm() < EPS) return randomLine();\n    \n    uniform_real_distribution<double> angle_dist(-0.6, 0.6);\n    double angle = atan2(dir.y, dir.x) + angle_dist(rng);\n    \n    uniform_real_distribution<double> offset_dist(-2500, 2500);\n    mid.x += offset_dist(rng);\n    mid.y += offset_dist(rng);\n    \n    int px = (int)mid.x;\n    int py = (int)mid.y;\n    int qx = px + (int)(15000 * cos(angle + M_PI/2));\n    int qy = py + (int)(15000 * sin(angle + M_PI/2));\n    \n    return Line(px, py, qx, qy);\n}\n\nLine precisionLine(int targetCount) {\n    // Try 3 different seeds to find good grouping\n    Line bestLine = randomLine();\n    int bestMatch = 1000;\n    \n    for (int trial = 0; trial < 3; trial++) {\n        int seed = rng() % N;\n        \n        vector<pair<double, int>> dists;\n        for (int i = 0; i < N; i++) {\n            if (i != seed && insideCircle(strawberries[i])) {\n                dists.push_back({(strawberries[i] - strawberries[seed]).norm2(), i});\n            }\n        }\n        \n        if ((int)dists.size() >= targetCount - 1) {\n            sort(dists.begin(), dists.end());\n            \n            // Try cutting at target position\n            int cutIdx = max(0, min(targetCount - 2, (int)dists.size() - 1));\n            \n            if (cutIdx >= 0 && cutIdx < dists.size()) {\n                Point p1 = strawberries[seed];\n                Point p2 = strawberries[dists[cutIdx].second];\n                \n                Point mid = (p1 + p2) * 0.5;\n                Point dir = p2 - p1;\n                \n                if (dir.norm() > EPS) {\n                    dir = dir * (1.0 / dir.norm());\n                    \n                    uniform_real_distribution<double> offset_dist(-300, 300);\n                    mid = mid + dir * offset_dist(rng);\n                    \n                    int px = (int)mid.x;\n                    int py = (int)mid.y;\n                    int qx = px - (int)(dir.y * 15000);\n                    int qy = py + (int)(dir.x * 15000);\n                    \n                    Line candidate(px, py, qx, qy);\n                    \n                    // Quick validation\n                    int count = 1;  // seed\n                    for (int i = 0; i <= min(cutIdx, (int)dists.size() - 1); i++) {\n                        if (candidate.side(strawberries[seed]) == \n                            candidate.side(strawberries[dists[i].second])) {\n                            count++;\n                        }\n                    }\n                    \n                    int diff = abs(count - targetCount);\n                    if (diff < bestMatch) {\n                        bestMatch = diff;\n                        bestLine = candidate;\n                        if (diff == 0) break;  // Perfect match\n                    }\n                }\n            }\n        }\n    }\n    \n    return bestLine;\n}\n\nLine smartLine() {\n    vector<int> targets = getPriorityTargets();\n    if (!targets.empty() && rng() % 3 < 2) {\n        return precisionLine(targets[0]);\n    }\n    \n    // Cluster-based line\n    uniform_int_distribution<int> idx_dist(0, N - 1);\n    int center = idx_dist(rng);\n    \n    vector<pair<double, int>> dists;\n    for (int i = 0; i < N; i++) {\n        if (i != center && insideCircle(strawberries[i])) {\n            double d = (strawberries[i] - strawberries[center]).norm2();\n            dists.push_back({d, i});\n        }\n    }\n    \n    if (dists.empty()) return randomLine();\n    sort(dists.begin(), dists.end());\n    \n    // Find largest gap\n    int bestGap = -1;\n    double maxGapRatio = 0;\n    for (int i = 0; i < min(20, (int)dists.size() - 1); i++) {\n        if (dists[i].first > EPS) {\n            double ratio = dists[i+1].first / dists[i].first;\n            if (ratio > maxGapRatio) {\n                maxGapRatio = ratio;\n                bestGap = i;\n            }\n        }\n    }\n    \n    if (bestGap >= 0 && bestGap < (int)dists.size() - 1) {\n        Point p1 = strawberries[dists[bestGap].second];\n        Point p2 = strawberries[dists[bestGap + 1].second];\n        Point mid = (p1 + p2) * 0.5;\n        Point dir = p2 - p1;\n        \n        if (dir.norm() > EPS) {\n            double angle = atan2(dir.y, dir.x) + M_PI/2;\n            int px = (int)mid.x;\n            int py = (int)mid.y;\n            int qx = px + (int)(15000 * cos(angle));\n            int qy = py + (int)(15000 * sin(angle));\n            return Line(px, py, qx, qy);\n        }\n    }\n    \n    return targetedLine();\n}\n\nLine densityLine() {\n    vector<int> targets = getPriorityTargets();\n    int targetCount = targets.empty() ? 1 : targets[0];\n    \n    Point bestCenter;\n    double bestScore = -1;\n    \n    // Quick sampling\n    for (int trial = 0; trial < 5; trial++) {\n        int idx = rng() % N;\n        Point center = strawberries[idx];\n        \n        // Count strawberries within target radius\n        double targetRadius = targetCount * 500;  // Rough estimate\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            if ((strawberries[i] - center).norm() < targetRadius) {\n                count++;\n            }\n        }\n        \n        double score = 1.0 / (1 + abs(count - targetCount));\n        if (score > bestScore) {\n            bestScore = score;\n            bestCenter = center;\n        }\n    }\n    \n    uniform_real_distribution<double> angle_dist(0, 2 * M_PI);\n    double angle = angle_dist(rng);\n    \n    int px = (int)bestCenter.x;\n    int py = (int)bestCenter.y;\n    int qx = px + (int)(15000 * cos(angle));\n    int qy = py + (int)(15000 * sin(angle));\n    \n    return Line(px, py, qx, qy);\n}\n\n// Fast local search\nvoid localSearch(double timeLimit) {\n    double startTime = clock();\n    int currentScore = calculateScore();\n    int noImprove = 0;\n    \n    while ((clock() - startTime) / CLOCKS_PER_SEC < timeLimit && noImprove < 5) {\n        if (lines.empty()) break;\n        \n        bool improved = false;\n        \n        // Try small perturbations on random lines\n        for (int attempt = 0; attempt < min(10, (int)lines.size()); attempt++) {\n            int idx = rng() % lines.size();\n            Line old = lines[idx];\n            \n            // Small perturbation\n            uniform_int_distribution<int> perturb_dist(-400, 400);\n            lines[idx].px += perturb_dist(rng);\n            lines[idx].py += perturb_dist(rng);\n            lines[idx].qx += perturb_dist(rng);\n            lines[idx].qy += perturb_dist(rng);\n            \n            int newScore = calculateScore();\n            if (newScore > currentScore) {\n                currentScore = newScore;\n                improved = true;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                }\n                break;\n            } else {\n                lines[idx] = old;\n            }\n        }\n        \n        noImprove = improved ? 0 : noImprove + 1;\n    }\n}\n\nvoid solve() {\n    double startTime = clock();\n    lines.clear();\n    bestLines.clear();\n    bestScore = 0;\n    deficit = a;\n    priority = vector<int>(11, 0);\n    \n    // Phase 1: Smart greedy initialization (15% time)\n    for (int iter = 0; iter < min(25, K); iter++) {\n        if ((clock() - startTime) / CLOCKS_PER_SEC > TIME_LIMIT * 0.15) break;\n        \n        Line bestLine = randomLine();\n        int bestImprovement = -1;\n        int currentScore = calculateScore();\n        \n        // More trials for early important lines\n        int numTrials = iter < 10 ? 45 : 30;\n        \n        for (int trial = 0; trial < numTrials; trial++) {\n            Line candidate;\n            \n            // Priority-based strategy selection\n            double r = uniform_real_distribution<double>(0, 1)(rng);\n            if (r < 0.25 && !getPriorityTargets().empty()) {\n                vector<int> targets = getPriorityTargets();\n                candidate = precisionLine(targets[0]);\n            } else if (r < 0.45) {\n                candidate = smartLine();\n            } else if (r < 0.6) {\n                candidate = densityLine();\n            } else if (r < 0.75) {\n                candidate = targetedLine();\n            } else if (r < 0.85 && !lines.empty()) {\n                Line& ref = lines[rng() % lines.size()];\n                double dx = ref.qx - ref.px;\n                double dy = ref.qy - ref.py;\n                uniform_int_distribution<int> offset_dist(-4000, 4000);\n                int cx = offset_dist(rng);\n                int cy = offset_dist(rng);\n                candidate = Line(cx - (int)dy, cy + (int)dx, cx + (int)dy, cy - (int)dx);\n            } else {\n                candidate = randomLine();\n            }\n            \n            lines.push_back(candidate);\n            int newScore = calculateScore();\n            lines.pop_back();\n            \n            if (newScore - currentScore > bestImprovement) {\n                bestImprovement = newScore - currentScore;\n                bestLine = candidate;\n            }\n        }\n        \n        if (bestImprovement >= 0) {\n            lines.push_back(bestLine);\n        }\n    }\n    \n    // Phase 2: Simulated annealing (75% time)\n    int currentScore = calculateScore();\n    bestLines = lines;\n    bestScore = currentScore;\n    \n    double temp = 18.0;\n    int iter = 0;\n    int lastBestUpdate = 0;\n    int plateauCount = 0;\n    \n    vector<int> strategySuccess(6, 0);\n    \n    while ((clock() - startTime) / CLOCKS_PER_SEC < TIME_LIMIT * 0.9) {\n        iter++;\n        \n        if (iter % 400 == 0) {\n            double elapsed = (clock() - startTime) / CLOCKS_PER_SEC;\n            double progress = elapsed / (TIME_LIMIT * 0.9);\n            \n            if (iter - lastBestUpdate > 1800) {\n                temp = min(25.0, temp * 2);\n                plateauCount++;\n                lastBestUpdate = iter;\n                \n                if (plateauCount > 3 && lines.size() > 8) {\n                    // Shake up\n                    int removeCount = min((int)lines.size() / 4, 6);\n                    for (int i = 0; i < removeCount && lines.size() > 5; i++) {\n                        lines.erase(lines.begin() + (rng() % lines.size()));\n                    }\n                    currentScore = calculateScore();\n                    plateauCount = 0;\n                }\n            } else {\n                temp = 18.0 * exp(-2.2 * progress);\n            }\n        }\n        \n        uniform_real_distribution<double> op_dist(0, 1);\n        double op = op_dist(rng);\n        \n        if (op < 0.37 && lines.size() < (size_t)K) {\n            // Add with smart strategy selection\n            Line newLine;\n            \n            // Use weighted selection based on success\n            int totalWeight = 6;\n            for (int s : strategySuccess) totalWeight += s;\n            \n            uniform_int_distribution<int> weight_dist(0, totalWeight - 1);\n            int w = weight_dist(rng);\n            int strategy = 0;\n            int cumSum = 0;\n            for (int s = 0; s < 6; s++) {\n                cumSum += 1 + strategySuccess[s];\n                if (w < cumSum) {\n                    strategy = s;\n                    break;\n                }\n            }\n            \n            switch(strategy) {\n                case 0: newLine = randomLine(); break;\n                case 1: newLine = targetedLine(); break;\n                case 2: newLine = smartLine(); break;\n                case 3: {\n                    vector<int> targets = getPriorityTargets();\n                    newLine = targets.empty() ? smartLine() : precisionLine(targets[0]);\n                    break;\n                }\n                case 4: newLine = densityLine(); break;\n                case 5: {\n                    if (!lines.empty()) {\n                        Line& ref = lines[rng() % min(5, (int)lines.size())];\n                        double dx = ref.qx - ref.px;\n                        double dy = ref.qy - ref.py;\n                        uniform_int_distribution<int> offset_dist(-3500, 3500);\n                        int cx = offset_dist(rng);\n                        int cy = offset_dist(rng);\n                        newLine = Line(cx - (int)dy, cy + (int)dx, cx + (int)dy, cy - (int)dx);\n                    } else {\n                        newLine = smartLine();\n                    }\n                    break;\n                }\n            }\n            \n            lines.push_back(newLine);\n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.001)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                if (delta > 0) {\n                    strategySuccess[strategy]++;\n                    if (newScore > bestScore) {\n                        bestScore = newScore;\n                        bestLines = lines;\n                        lastBestUpdate = iter;\n                    }\n                }\n            } else {\n                lines.pop_back();\n            }\n        } else if (op < 0.55 && lines.size() > 5) {\n            // Remove\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line removed = lines[idx];\n            lines.erase(lines.begin() + idx);\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.001)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                    lastBestUpdate = iter;\n                }\n            } else {\n                lines.insert(lines.begin() + idx, removed);\n            }\n        } else if (lines.size() > 0) {\n            // Modify\n            uniform_int_distribution<int> idx_dist(0, lines.size() - 1);\n            int idx = idx_dist(rng);\n            Line old = lines[idx];\n            \n            if (rng() % 5 == 0) {\n                // Small perturbation\n                double scale = exp(-iter / 8000.0);\n                uniform_int_distribution<int> perturb_dist(-(int)(2000 * scale), (int)(2000 * scale));\n                lines[idx].px += perturb_dist(rng);\n                lines[idx].py += perturb_dist(rng);\n                lines[idx].qx += perturb_dist(rng);\n                lines[idx].qy += perturb_dist(rng);\n            } else {\n                // Replace with smart line\n                vector<int> targets = getPriorityTargets();\n                if (!targets.empty() && rng() % 3 == 0) {\n                    lines[idx] = precisionLine(targets[0]);\n                } else {\n                    int strategy = rng() % 4;\n                    switch(strategy) {\n                        case 0: lines[idx] = randomLine(); break;\n                        case 1: lines[idx] = targetedLine(); break;\n                        case 2: lines[idx] = smartLine(); break;\n                        case 3: lines[idx] = densityLine(); break;\n                    }\n                }\n            }\n            \n            int newScore = calculateScore();\n            \n            double delta = newScore - currentScore;\n            if (delta > 0 || exp(delta / max(temp, 0.001)) > uniform_real_distribution<double>(0, 1)(rng)) {\n                currentScore = newScore;\n                if (newScore > bestScore) {\n                    bestScore = newScore;\n                    bestLines = lines;\n                    lastBestUpdate = iter;\n                }\n            } else {\n                lines[idx] = old;\n            }\n        }\n    }\n    \n    // Phase 3: Final local search (10% time)\n    lines = bestLines;\n    double remainingTime = TIME_LIMIT - (clock() - startTime) / CLOCKS_PER_SEC;\n    if (remainingTime > 0.05) {\n        localSearch(remainingTime);\n    }\n    \n    lines = bestLines;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> K;\n    \n    for (int i = 1; i <= 10; i++) {\n        cin >> a[i];\n    }\n    \n    strawberries.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> strawberries[i].x >> strawberries[i].y;\n    }\n    \n    solve();\n    \n    cout << lines.size() << \"\\n\";\n    for (const Line& line : lines) {\n        cout << line.px << \" \" << line.py << \" \" << line.qx << \" \" << line.qy << \"\\n\";\n    }\n    \n    return 0;\n}","ahc014":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n    bool operator<(const Point& p) const {\n        return tie(x, y) < tie(p.x, p.y);\n    }\n    bool operator==(const Point& p) const {\n        return x == p.x && y == p.y;\n    }\n    Point operator-(const Point& p) const {\n        return Point(x - p.x, y - p.y);\n    }\n};\n\nint N, M;\nset<Point> dots;\nset<pair<Point, Point>> usedEdges;\nclock_t startTime;\n\nint weight(int x, int y) {\n    int c = (N - 1) / 2;\n    return (x - c) * (x - c) + (y - c) * (y - c) + 1;\n}\n\ndouble getElapsedTime() {\n    return (double)(clock() - startTime) / CLOCKS_PER_SEC;\n}\n\nint dot(Point a, Point b) {\n    return a.x * b.x + a.y * b.y;\n}\n\nbool isRectangle(Point p1, Point p2, Point p3, Point p4) {\n    // Check if p1-p2-p3-p4 forms a rectangle\n    Point v12 = p2 - p1;\n    Point v23 = p3 - p2;\n    Point v34 = p4 - p3;\n    Point v41 = p1 - p4;\n    \n    // For a rectangle, opposite sides must be equal and adjacent sides perpendicular\n    if (v12.x == v34.x && v12.y == v34.y && \n        v23.x == v41.x && v23.y == v41.y &&\n        dot(v12, v23) == 0) {\n        return true;\n    }\n    \n    return false;\n}\n\nvector<Point> getAllPointsOnSegment(Point a, Point b) {\n    vector<Point> points;\n    int dx = (b.x > a.x) ? 1 : (b.x < a.x) ? -1 : 0;\n    int dy = (b.y > a.y) ? 1 : (b.y < a.y) ? -1 : 0;\n    \n    Point curr = a;\n    while (!(curr == b)) {\n        points.push_back(curr);\n        curr.x += dx;\n        curr.y += dy;\n    }\n    points.push_back(b);\n    return points;\n}\n\nbool tryRectangle(Point newDot, vector<Point>& existingDots, vector<int>& output) {\n    if (dots.count(newDot)) return false;\n    if (newDot.x < 0 || newDot.x >= N || newDot.y < 0 || newDot.y >= N) return false;\n    \n    // Try all permutations of 3 existing dots\n    sort(existingDots.begin(), existingDots.end());\n    do {\n        Point p2 = existingDots[0];\n        Point p3 = existingDots[1]; \n        Point p4 = existingDots[2];\n        \n        if (!isRectangle(newDot, p2, p3, p4)) continue;\n        \n        // Check perimeter has no other dots\n        vector<pair<Point, Point>> edges = {\n            {newDot, p2}, {p2, p3}, {p3, p4}, {p4, newDot}\n        };\n        \n        bool valid = true;\n        set<Point> corners = {newDot, p2, p3, p4};\n        \n        for (auto& edge : edges) {\n            auto points = getAllPointsOnSegment(edge.first, edge.second);\n            for (auto& pt : points) {\n                if (!corners.count(pt) && dots.count(pt)) {\n                    valid = false;\n                    break;\n                }\n            }\n            if (!valid) break;\n        }\n        \n        if (!valid) continue;\n        \n        // Check edges not already used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            if (usedEdges.count({a, b})) {\n                valid = false;\n                break;\n            }\n        }\n        \n        if (!valid) continue;\n        \n        // Found valid rectangle\n        output = {newDot.x, newDot.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y};\n        \n        // Mark edges as used\n        for (auto& edge : edges) {\n            Point a = edge.first, b = edge.second;\n            if (a.x > b.x || (a.x == b.x && a.y > b.y)) swap(a, b);\n            usedEdges.insert({a, b});\n        }\n        \n        return true;\n        \n    } while (next_permutation(existingDots.begin(), existingDots.end()));\n    \n    return false;\n}\n\nint main() {\n    startTime = clock();\n    cin >> N >> M;\n    \n    for (int i = 0; i < M; i++) {\n        int x, y;\n        cin >> x >> y;\n        dots.insert(Point(x, y));\n    }\n    \n    vector<vector<int>> result;\n    int center = (N - 1) / 2;\n    \n    while (getElapsedTime() < 4.0) {\n        bool found = false;\n        \n        // Try positions from center outward\n        for (int dist = 0; dist <= N && !found; dist++) {\n            for (int x = max(0, center - dist); x <= min(N - 1, center + dist) && !found; x++) {\n                for (int y = max(0, center - dist); y <= min(N - 1, center + dist) && !found; y++) {\n                    if (abs(x - center) != dist && abs(y - center) != dist) continue;\n                    \n                    Point newDot(x, y);\n                    if (dots.count(newDot)) continue;\n                    \n                    // Try to form rectangle with 3 existing dots\n                    vector<Point> dotVec(dots.begin(), dots.end());\n                    int n = dotVec.size();\n                    \n                    // Try combinations of 3 dots\n                    for (int i = 0; i < n && !found; i++) {\n                        for (int j = i + 1; j < n && !found; j++) {\n                            for (int k = j + 1; k < n && !found; k++) {\n                                vector<Point> threeDots = {dotVec[i], dotVec[j], dotVec[k]};\n                                vector<int> output;\n                                \n                                if (tryRectangle(newDot, threeDots, output)) {\n                                    dots.insert(newDot);\n                                    result.push_back(output);\n                                    found = true;\n                                }\n                                \n                                if (getElapsedTime() > 4.0) break;\n                            }\n                            if (getElapsedTime() > 4.0) break;\n                        }\n                        if (getElapsedTime() > 4.0) break;\n                    }\n                }\n            }\n        }\n        \n        if (!found) break;\n    }\n    \n    cout << result.size() << endl;\n    for (auto& r : result) {\n        for (int i = 0; i < 8; i++) {\n            if (i) cout << \" \";\n            cout << r[i];\n        }\n        cout << endl;\n    }\n    \n    return 0;\n}","ahc015":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 10;\nconst int TOTAL = 100;\n\nstruct Board {\n    int grid[N][N];\n    \n    Board() {\n        memset(grid, 0, sizeof(grid));\n    }\n    \n    void place(int pos, int flavor) {\n        int cnt = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] == 0) {\n                    cnt++;\n                    if (cnt == pos) {\n                        grid[i][j] = flavor;\n                        return;\n                    }\n                }\n            }\n        }\n    }\n    \n    void tiltForward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = 0;\n            for (int i = 0; i < N; i++) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltBackward() {\n        for (int j = 0; j < N; j++) {\n            int writePos = N-1;\n            for (int i = N-1; i >= 0; i--) {\n                if (grid[i][j] != 0) {\n                    if (i != writePos) {\n                        grid[writePos][j] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tiltLeft() {\n        for (int i = 0; i < N; i++) {\n            int writePos = 0;\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos++;\n                }\n            }\n        }\n    }\n    \n    void tiltRight() {\n        for (int i = 0; i < N; i++) {\n            int writePos = N-1;\n            for (int j = N-1; j >= 0; j--) {\n                if (grid[i][j] != 0) {\n                    if (j != writePos) {\n                        grid[i][writePos] = grid[i][j];\n                        grid[i][j] = 0;\n                    }\n                    writePos--;\n                }\n            }\n        }\n    }\n    \n    void tilt(char dir) {\n        if (dir == 'F') tiltForward();\n        else if (dir == 'B') tiltBackward();\n        else if (dir == 'L') tiltLeft();\n        else if (dir == 'R') tiltRight();\n    }\n    \n    // Get component information\n    struct Info {\n        double score;\n        int numComponents;\n        map<int, int> largestByFlavor;\n        vector<int> allSizes;\n    };\n    \n    Info getInfo() {\n        Info result;\n        result.score = 0;\n        result.numComponents = 0;\n        \n        bool visited[N][N];\n        memset(visited, false, sizeof(visited));\n        \n        int dx[] = {0, 0, 1, -1};\n        int dy[] = {1, -1, 0, 0};\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0 && !visited[i][j]) {\n                    int flavor = grid[i][j];\n                    int size = 0;\n                    queue<pair<int, int>> q;\n                    q.push({i, j});\n                    visited[i][j] = true;\n                    \n                    while (!q.empty()) {\n                        auto [x, y] = q.front();\n                        q.pop();\n                        size++;\n                        \n                        for (int k = 0; k < 4; k++) {\n                            int nx = x + dx[k];\n                            int ny = y + dy[k];\n                            if (nx >= 0 && nx < N && ny >= 0 && ny < N &&\n                                !visited[nx][ny] && grid[nx][ny] == flavor) {\n                                visited[nx][ny] = true;\n                                q.push({nx, ny});\n                            }\n                        }\n                    }\n                    \n                    result.score += (double)size * size;\n                    result.numComponents++;\n                    result.largestByFlavor[flavor] = max(result.largestByFlavor[flavor], size);\n                    result.allSizes.push_back(size);\n                }\n            }\n        }\n        return result;\n    }\n    \n    // Count adjacent pairs\n    int countAdjacent() {\n        int count = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] != 0) {\n                    if (i + 1 < N && grid[i+1][j] == grid[i][j]) count++;\n                    if (j + 1 < N && grid[i][j+1] == grid[i][j]) count++;\n                }\n            }\n        }\n        return count;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    vector<int> flavors(TOTAL);\n    vector<int> flavorFreq(4, 0);\n    \n    for (int i = 0; i < TOTAL; i++) {\n        cin >> flavors[i];\n        flavorFreq[flavors[i]]++;\n    }\n    \n    Board board;\n    \n    for (int t = 0; t < TOTAL; t++) {\n        int pos;\n        cin >> pos;\n        \n        board.place(pos, flavors[t]);\n        \n        if (t == TOTAL - 1) break;\n        \n        char dirs[] = {'F', 'B', 'L', 'R'};\n        char bestDir = 'F';\n        double bestScore = -1e9;\n        \n        // Try each direction\n        for (char dir : dirs) {\n            Board tempBoard = board;\n            tempBoard.tilt(dir);\n            \n            auto info = tempBoard.getInfo();\n            \n            // Always start with the core metric\n            double score = info.score;\n            \n            if (t < 12) {\n                // Very early game: build initial clusters\n                score *= 50;\n                \n                // Strong emphasis on adjacency\n                int adj = tempBoard.countAdjacent();\n                score += adj * 100;\n                \n                // Light penalty for fragments\n                score -= info.numComponents * 5;\n                \n            } else if (t < 40) {\n                // Early-mid game: grow clusters\n                score *= 150;\n                \n                // Moderate penalty for fragmentation\n                score -= info.numComponents * 10;\n                \n                // Bonus for having large clusters\n                for (auto& [flavor, size] : info.largestByFlavor) {\n                    if (size >= 10) score += size * 20;\n                    if (size >= 15) score += size * 30;\n                }\n                \n                // Look ahead for upcoming candies\n                for (int i = t + 1; i < min(t + 8, TOTAL); i++) {\n                    int nextFlavor = flavors[i];\n                    if (info.largestByFlavor.count(nextFlavor)) {\n                        score += info.largestByFlavor[nextFlavor] * 4;\n                    }\n                }\n                \n            } else if (t < 75) {\n                // Mid-late game: consolidate\n                score *= 300;\n                \n                // Progressive fragmentation penalty\n                score -= info.numComponents * (5 + (t - 40) * 0.2);\n                \n                // Strong bonus for large components\n                for (int size : info.allSizes) {\n                    if (size >= 30) score += size * 80;\n                    else if (size >= 20) score += size * 40;\n                    else if (size >= 10) score += size * 10;\n                }\n                \n                // Consider upcoming candies\n                for (int i = t + 1; i < min(t + 6, TOTAL); i++) {\n                    int nextFlavor = flavors[i];\n                    if (info.largestByFlavor.count(nextFlavor)) {\n                        score += info.largestByFlavor[nextFlavor] * 2;\n                    }\n                }\n                \n            } else {\n                // End game: pure score optimization\n                score *= 1000;\n                \n                // Very light penalty for extreme fragmentation\n                if (info.numComponents > 15) {\n                    score -= (info.numComponents - 15) * 10;\n                }\n                \n                // Huge bonus for preserving large components\n                for (int size : info.allSizes) {\n                    if (size >= 35) score += size * 200;\n                    else if (size >= 25) score += size * 50;\n                }\n            }\n            \n            // Add small random perturbation to break ties\n            score += (rand() % 100) * 0.001;\n            \n            if (score > bestScore) {\n                bestScore = score;\n                bestDir = dir;\n            }\n        }\n        \n        board.tilt(bestDir);\n        cout << bestDir << endl;\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc016":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass Graph {\n    int N;\n    vector<vector<int>> adj;\n    \npublic:\n    Graph(int n) : N(n), adj(n, vector<int>(n, 0)) {}\n    \n    void setEdge(int i, int j, int val) {\n        adj[i][j] = adj[j][i] = val;\n    }\n    \n    string toString() const {\n        string s;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                s += (adj[i][j] ? '1' : '0');\n            }\n        }\n        return s;\n    }\n    \n    void fromString(const string& s) {\n        int idx = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                adj[i][j] = adj[j][i] = (s[idx++] == '1' ? 1 : 0);\n            }\n        }\n    }\n    \n    vector<double> getInvariants() const {\n        vector<double> inv;\n        \n        // 1. Edge count - most robust invariant\n        int edges = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                edges += adj[i][j];\n            }\n        }\n        inv.push_back(edges);\n        \n        // 2. Full degree sequence (sorted)\n        vector<int> degrees(N, 0);\n        for(int i = 0; i < N; i++) {\n            for(int j = 0; j < N; j++) {\n                degrees[i] += adj[i][j];\n            }\n        }\n        sort(degrees.begin(), degrees.end());\n        for(int d : degrees) {\n            inv.push_back(d);\n        }\n        \n        // 3. Triangle count\n        int triangles = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                if(adj[i][j]) {\n                    for(int k = j + 1; k < N; k++) {\n                        if(adj[j][k] && adj[k][i]) triangles++;\n                    }\n                }\n            }\n        }\n        inv.push_back(triangles);\n        \n        // 4. Sum of squared degrees\n        double deg2 = 0;\n        for(int d : degrees) deg2 += d * d;\n        inv.push_back(deg2);\n        \n        // 5. 4-cycles\n        int cycles4 = 0;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                int common = 0;\n                for(int k = 0; k < N; k++) {\n                    if(k != i && k != j && adj[i][k] && adj[j][k]) {\n                        common++;\n                    }\n                }\n                cycles4 += common * (common - 1) / 2;\n            }\n        }\n        inv.push_back(cycles4);\n        \n        // 6. Wedge count\n        int wedges = 0;\n        for(int d : degrees) {\n            wedges += d * (d - 1) / 2;\n        }\n        inv.push_back(wedges);\n        \n        // 7. Common neighbor histogram (first few values)\n        map<int, int> cn_hist;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                int cn = 0;\n                for(int k = 0; k < N; k++) {\n                    if(k != i && k != j) cn += adj[i][k] * adj[j][k];\n                }\n                cn_hist[cn]++;\n            }\n        }\n        for(int i = 0; i <= min(5, N-2); i++) {\n            inv.push_back(cn_hist[i]);\n        }\n        \n        return inv;\n    }\n};\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int M;\n    double eps;\n    cin >> M >> eps;\n    \n    // Conservative N selection for robustness\n    int N;\n    \n    // Base selection on M\n    if(M <= 10) {\n        N = 5;\n    } else if(M <= 20) {\n        N = 6;\n    } else if(M <= 35) {\n        N = 7;\n    } else if(M <= 56) {\n        N = 8;  \n    } else if(M <= 84) {\n        N = 9;\n    } else if(M <= 120) {\n        N = 10;\n    } else {\n        N = min(20, 10 + (M - 120) / 15);\n    }\n    \n    // Adjust for error rate - need more redundancy with higher noise\n    if(eps > 0.35) {\n        N = min(25, N + 4);\n    } else if(eps > 0.25) {\n        N = min(20, N + 3);\n    } else if(eps > 0.15) {\n        N = min(15, N + 2);\n    } else if(eps > 0.05) {\n        N = min(12, N + 1);\n    }\n    \n    // Ensure minimum N\n    N = max(4, N);\n    \n    vector<Graph> graphs;\n    int total_edges = N * (N - 1) / 2;\n    \n    // Generate M graphs with maximum separation\n    for(int idx = 0; idx < M; idx++) {\n        Graph g(N);\n        \n        // Primary distinction: edge count\n        // Spread edge counts evenly across the range\n        int target_edges = (idx * total_edges) / max(1, M - 1);\n        \n        // Secondary distinction: structure\n        // Use different generation patterns for different indices\n        set<pair<int,int>> edges;\n        \n        // Pattern selection based on index\n        int pattern = idx % 5;\n        mt19937 rng(idx * 999983);  // Prime number seed\n        \n        if(pattern == 0) {\n            // Random uniform distribution\n            vector<pair<int,int>> all_edges;\n            for(int i = 0; i < N; i++) {\n                for(int j = i + 1; j < N; j++) {\n                    all_edges.push_back({i, j});\n                }\n            }\n            shuffle(all_edges.begin(), all_edges.end(), rng);\n            for(int i = 0; i < target_edges && i < all_edges.size(); i++) {\n                edges.insert(all_edges[i]);\n            }\n        } else if(pattern == 1) {\n            // Preferential attachment-like\n            vector<int> node_weight(N, 1);\n            while(edges.size() < target_edges) {\n                // Sample two nodes with probability proportional to weight\n                discrete_distribution<int> dist(node_weight.begin(), node_weight.end());\n                int u = dist(rng);\n                int v = dist(rng);\n                if(u > v) swap(u, v);\n                if(u != v && edges.find({u, v}) == edges.end()) {\n                    edges.insert({u, v});\n                    node_weight[u]++;\n                    node_weight[v]++;\n                }\n                if(edges.size() > target_edges * 2) break; // Avoid infinite loop\n            }\n        } else if(pattern == 2) {\n            // Regular-like structure\n            if(target_edges > 0) {\n                int degree = (target_edges * 2) / N;\n                for(int i = 0; i < N; i++) {\n                    for(int j = 1; j <= degree/2 + 1 && edges.size() < target_edges; j++) {\n                        int next = (i + j) % N;\n                        if(i < next) edges.insert({i, next});\n                        else edges.insert({next, i});\n                    }\n                }\n            }\n        } else if(pattern == 3) {\n            // Bipartite-inspired\n            int part1 = N / 2;\n            vector<pair<int,int>> bipartite_edges;\n            for(int i = 0; i < part1; i++) {\n                for(int j = part1; j < N; j++) {\n                    bipartite_edges.push_back({i, j});\n                }\n            }\n            shuffle(bipartite_edges.begin(), bipartite_edges.end(), rng);\n            for(int i = 0; i < target_edges && i < bipartite_edges.size(); i++) {\n                edges.insert(bipartite_edges[i]);\n            }\n        } else {\n            // Clique + random\n            int clique_size = min(N, (int)(sqrt(target_edges * 2) + 1));\n            for(int i = 0; i < clique_size; i++) {\n                for(int j = i + 1; j < clique_size && edges.size() < target_edges; j++) {\n                    edges.insert({i, j});\n                }\n            }\n            // Fill remaining with random edges\n            vector<pair<int,int>> remaining;\n            for(int i = 0; i < N; i++) {\n                for(int j = i + 1; j < N; j++) {\n                    if(edges.find({i, j}) == edges.end()) {\n                        remaining.push_back({i, j});\n                    }\n                }\n            }\n            shuffle(remaining.begin(), remaining.end(), rng);\n            for(auto e : remaining) {\n                if(edges.size() >= target_edges) break;\n                edges.insert(e);\n            }\n        }\n        \n        // Ensure we have exactly target_edges\n        vector<pair<int,int>> all_possible;\n        for(int i = 0; i < N; i++) {\n            for(int j = i + 1; j < N; j++) {\n                all_possible.push_back({i, j});\n            }\n        }\n        shuffle(all_possible.begin(), all_possible.end(), rng);\n        \n        // Add missing edges\n        for(auto e : all_possible) {\n            if(edges.size() >= target_edges) break;\n            edges.insert(e);\n        }\n        \n        // Remove excess edges\n        while(edges.size() > target_edges && edges.size() > 0) {\n            auto it = edges.begin();\n            advance(it, rng() % edges.size());\n            edges.erase(it);\n        }\n        \n        // Build graph\n        for(auto [u, v] : edges) {\n            g.setEdge(u, v, 1);\n        }\n        \n        graphs.push_back(g);\n    }\n    \n    // Output\n    cout << N << \"\\n\";\n    for(const auto& g : graphs) {\n        cout << g.toString() << \"\\n\";\n    }\n    cout.flush();\n    \n    // Precompute invariants\n    vector<vector<double>> invariants;\n    for(const auto& g : graphs) {\n        invariants.push_back(g.getInvariants());\n    }\n    \n    // Process queries\n    for(int q = 0; q < 100; q++) {\n        string h_str;\n        cin >> h_str;\n        \n        Graph h(N);\n        h.fromString(h_str);\n        auto h_inv = h.getInvariants();\n        \n        // Find best match\n        int best = 0;\n        double best_score = -1e18;\n        \n        for(int i = 0; i < M; i++) {\n            double score = 0;\n            \n            // Edge count is by far the most important\n            double edge_diff = abs(h_inv[0] - invariants[i][0]);\n            score -= edge_diff * 100;\n            \n            // Degree sequence\n            for(int j = 1; j <= N && j < h_inv.size() && j < invariants[i].size(); j++) {\n                score -= abs(h_inv[j] - invariants[i][j]) * 10;\n            }\n            \n            // Triangles\n            if(N + 1 < h_inv.size() && N + 1 < invariants[i].size()) {\n                score -= abs(h_inv[N + 1] - invariants[i][N + 1]) * 20;\n            }\n            \n            // Other invariants\n            for(int j = N + 2; j < min(h_inv.size(), invariants[i].size()); j++) {\n                double weight = 5.0;\n                if(j == N + 2) weight = 15;  // deg^2 sum\n                if(j == N + 3) weight = 15;  // 4-cycles\n                if(j == N + 4) weight = 10;  // wedges\n                \n                double norm = max(1.0, abs(invariants[i][j]) + 1.0);\n                score -= weight * abs(h_inv[j] - invariants[i][j]) / norm;\n            }\n            \n            if(score > best_score) {\n                best_score = score;\n                best = i;\n            }\n        }\n        \n        cout << best << \"\\n\";\n        cout.flush();\n    }\n    \n    return 0;\n}","ahc017":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, w;\n    int id;\n};\n\nint N, M, D, K;\nvector<Edge> edges;\nvector<pair<int, int>> coords;\nvector<int> assignment;\nvector<int> best_global;\ndouble best_global_score = 1e18;\nmt19937 rng(42);\n\nconst int INF = 1000000000;\n\n// Fast Dijkstra\nvector<int> dijkstra(int s, const vector<bool>& usable, const vector<vector<pair<int, int>>>& graph) {\n    vector<int> dist(N, INF);\n    priority_queue<pair<int, int>, vector<pair<int, int>>, greater<>> pq;\n    \n    dist[s] = 0;\n    pq.push({0, s});\n    \n    while (!pq.empty()) {\n        auto [d, u] = pq.top();\n        pq.pop();\n        \n        if (d > dist[u]) continue;\n        \n        for (auto [v, eid] : graph[u]) {\n            if (!usable[eid]) continue;\n            int w = edges[eid].w;\n            \n            if (dist[u] + w < dist[v]) {\n                dist[v] = dist[u] + w;\n                pq.push({dist[v], v});\n            }\n        }\n    }\n    \n    return dist;\n}\n\n// Evaluate with caching\ndouble evaluateFrustration(const vector<int>& assign, \n                          const vector<vector<int>>& base_dist,\n                          const vector<int>& samples,\n                          const vector<vector<pair<int, int>>>& graph,\n                          bool quick = true) {\n    // Check constraints\n    vector<int> counts(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        counts[assign[i]]++;\n        if (counts[assign[i]] > K) return 1e18;\n    }\n    \n    vector<vector<int>> day_edges(D + 1);\n    for (int i = 0; i < M; i++) {\n        day_edges[assign[i]].push_back(i);\n    }\n    \n    double total = 0;\n    int pair_count = 0;\n    \n    for (int day = 1; day <= D; day++) {\n        vector<bool> usable(M, true);\n        for (int e : day_edges[day]) {\n            usable[e] = false;\n        }\n        \n        for (int idx = 0; idx < samples.size(); idx++) {\n            int s = samples[idx];\n            auto dist = dijkstra(s, usable, graph);\n            \n            // Sample targets\n            int step = quick ? max(5, N/20) : max(2, N/50);\n            for (int t = 0; t < N; t += step) {\n                if (s != t) {\n                    total += (double)(dist[t] - base_dist[idx][t]);\n                    pair_count++;\n                }\n            }\n        }\n    }\n    \n    return total / (pair_count * D);\n}\n\n// BFS-based clustering\nvector<int> bfsCluster(const vector<vector<pair<int, int>>>& graph) {\n    vector<int> result(M);\n    vector<bool> edge_used(M, false);\n    vector<int> day_counts(D + 1, 0);\n    \n    // Start from random vertices and assign edges in BFS order\n    vector<int> start_vertices;\n    for (int i = 0; i < D && i < N; i++) {\n        start_vertices.push_back((i * N) / D);\n    }\n    \n    int current_day = 1;\n    for (int start : start_vertices) {\n        queue<int> q;\n        q.push(start);\n        vector<bool> visited(N, false);\n        visited[start] = true;\n        \n        while (!q.empty() && day_counts[current_day] < K) {\n            int u = q.front();\n            q.pop();\n            \n            for (auto [v, eid] : graph[u]) {\n                if (!edge_used[eid] && day_counts[current_day] < K) {\n                    result[eid] = current_day;\n                    edge_used[eid] = true;\n                    day_counts[current_day]++;\n                }\n                \n                if (!visited[v]) {\n                    visited[v] = true;\n                    q.push(v);\n                }\n            }\n        }\n        current_day = (current_day % D) + 1;\n    }\n    \n    // Assign remaining edges\n    for (int i = 0; i < M; i++) {\n        if (!edge_used[i]) {\n            for (int d = 1; d <= D; d++) {\n                if (day_counts[d] < K) {\n                    result[i] = d;\n                    day_counts[d]++;\n                    break;\n                }\n            }\n        }\n    }\n    \n    return result;\n}\n\n// Local search with multiple move types\nvoid localSearch(vector<int>& assign, \n                const vector<vector<int>>& base_dist,\n                const vector<int>& samples,\n                const vector<vector<pair<int, int>>>& graph,\n                int time_limit) {\n    auto start = chrono::high_resolution_clock::now();\n    \n    double current_score = evaluateFrustration(assign, base_dist, samples, graph, true);\n    double best_score = current_score;\n    vector<int> best_assign = assign;\n    \n    vector<int> day_counts(D + 1, 0);\n    for (int i = 0; i < M; i++) {\n        day_counts[assign[i]]++;\n    }\n    \n    double T = current_score * 0.01;\n    uniform_real_distribution<double> prob(0, 1);\n    uniform_int_distribution<int> edge_dist(0, M - 1);\n    uniform_int_distribution<int> day_dist(1, D);\n    \n    int no_improve = 0;\n    \n    while (true) {\n        auto now = chrono::high_resolution_clock::now();\n        if (chrono::duration_cast<chrono::milliseconds>(now - start).count() > time_limit) break;\n        \n        int move_type = rng() % 100;\n        vector<int> old_assign = assign;\n        vector<int> old_counts = day_counts;\n        bool valid = true;\n        \n        if (move_type < 40) {\n            // Swap two edges\n            int e1 = edge_dist(rng);\n            int e2 = edge_dist(rng);\n            if (e1 != e2 && assign[e1] != assign[e2]) {\n                swap(assign[e1], assign[e2]);\n            } else {\n                continue;\n            }\n        } else if (move_type < 70) {\n            // Move edge to different day\n            int e = edge_dist(rng);\n            int old_day = assign[e];\n            int new_day = day_dist(rng);\n            \n            if (old_day != new_day && day_counts[new_day] < K) {\n                assign[e] = new_day;\n                day_counts[old_day]--;\n                day_counts[new_day]++;\n            } else {\n                continue;\n            }\n        } else if (move_type < 90) {\n            // Move multiple connected edges\n            int e = edge_dist(rng);\n            int v = edges[e].u;\n            int old_day = assign[e];\n            int new_day = day_dist(rng);\n            \n            if (old_day == new_day) continue;\n            \n            vector<int> to_move;\n            for (auto [u, eid] : graph[v]) {\n                if (assign[eid] == old_day) {\n                    to_move.push_back(eid);\n                }\n            }\n            \n            if (day_counts[new_day] + to_move.size() <= K && \n                day_counts[old_day] >= to_move.size()) {\n                for (int eid : to_move) {\n                    assign[eid] = new_day;\n                }\n                day_counts[old_day] -= to_move.size();\n                day_counts[new_day] += to_move.size();\n            } else {\n                continue;\n            }\n        } else {\n            // Balance days - move from max to min\n            int max_day = 1, min_day = 1;\n            for (int d = 1; d <= D; d++) {\n                if (day_counts[d] > day_counts[max_day]) max_day = d;\n                if (day_counts[d] < day_counts[min_day]) min_day = d;\n            }\n            \n            if (max_day != min_day && day_counts[min_day] < K) {\n                for (int i = 0; i < M; i++) {\n                    if (assign[i] == max_day) {\n                        assign[i] = min_day;\n                        day_counts[max_day]--;\n                        day_counts[min_day]++;\n                        break;\n                    }\n                }\n            } else {\n                continue;\n            }\n        }\n        \n        // Verify constraints\n        for (int d = 1; d <= D; d++) {\n            if (day_counts[d] > K) {\n                valid = false;\n                break;\n            }\n        }\n        \n        if (!valid) {\n            assign = old_assign;\n            day_counts = old_counts;\n            continue;\n        }\n        \n        double new_score = evaluateFrustration(assign, base_dist, samples, graph, true);\n        double delta = new_score - current_score;\n        \n        if (delta < 0 || prob(rng) < exp(-delta / T)) {\n            current_score = new_score;\n            no_improve = 0;\n            \n            if (current_score < best_score) {\n                best_score = current_score;\n                best_assign = assign;\n                \n                if (best_score < best_global_score) {\n                    best_global_score = best_score;\n                    best_global = best_assign;\n                }\n            }\n        } else {\n            assign = old_assign;\n            day_counts = old_counts;\n            no_improve++;\n        }\n        \n        // Adaptive temperature\n        T *= 0.995;\n        \n        // Restart if stuck\n        if (no_improve > 500) {\n            T = best_score * 0.005;\n            no_improve = 0;\n        }\n    }\n    \n    assign = best_assign;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    auto start_time = chrono::high_resolution_clock::now();\n    \n    cin >> N >> M >> D >> K;\n    \n    edges.resize(M);\n    for (int i = 0; i < M; i++) {\n        cin >> edges[i].u >> edges[i].v >> edges[i].w;\n        edges[i].u--;\n        edges[i].v--;\n        edges[i].id = i;\n    }\n    \n    coords.resize(N);\n    for (int i = 0; i < N; i++) {\n        cin >> coords[i].first >> coords[i].second;\n    }\n    \n    // Build graph\n    vector<vector<pair<int, int>>> graph(N);\n    for (int i = 0; i < M; i++) {\n        graph[edges[i].u].push_back({edges[i].v, i});\n        graph[edges[i].v].push_back({edges[i].u, i});\n    }\n    \n    // Sample vertices - use more samples\n    int sample_size = min(35, N);\n    vector<int> samples;\n    for (int i = 0; i < sample_size; i++) {\n        samples.push_back((i * N) / sample_size);\n    }\n    \n    // Compute base distances\n    vector<bool> all_usable(M, true);\n    vector<vector<int>> base_dist(sample_size);\n    for (int i = 0; i < sample_size; i++) {\n        base_dist[i] = dijkstra(samples[i], all_usable, graph);\n    }\n    \n    // Multi-start with different strategies\n    int strategies = 3;\n    int time_per_strategy = 4800 / strategies;\n    \n    for (int strategy = 0; strategy < strategies; strategy++) {\n        auto now = chrono::high_resolution_clock::now();\n        auto elapsed = chrono::duration_cast<chrono::milliseconds>(now - start_time).count();\n        if (elapsed > 4800) break;\n        \n        // Different initial assignments\n        if (strategy == 0) {\n            // BFS clustering\n            assignment = bfsCluster(graph);\n        } else if (strategy == 1) {\n            // Random assignment\n            assignment.resize(M);\n            vector<int> counts(D + 1, 0);\n            for (int i = 0; i < M; i++) {\n                int d = (rng() % D) + 1;\n                while (counts[d] >= K) {\n                    d = (rng() % D) + 1;\n                }\n                assignment[i] = d;\n                counts[d]++;\n            }\n        } else {\n            // Weight-based clustering\n            assignment.resize(M);\n            vector<pair<int, int>> weight_order;\n            for (int i = 0; i < M; i++) {\n                weight_order.push_back({edges[i].w, i});\n            }\n            sort(weight_order.begin(), weight_order.end());\n            \n            vector<int> counts(D + 1, 0);\n            for (auto [w, eid] : weight_order) {\n                int best_day = 1;\n                for (int d = 1; d <= D; d++) {\n                    if (counts[d] < counts[best_day]) best_day = d;\n                }\n                assignment[eid] = best_day;\n                counts[best_day]++;\n            }\n        }\n        \n        localSearch(assignment, base_dist, samples, graph, \n                   min(time_per_strategy, 4800 - (int)elapsed));\n    }\n    \n    // Use best found solution\n    assignment = best_global;\n    \n    // Output\n    for (int i = 0; i < M; i++) {\n        if (i > 0) cout << \" \";\n        cout << assignment[i];\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc019":"#include <bits/stdc++.h>\nusing namespace std;\n\nint D;\nvector<string> f1, r1, f2, r2;\n\nvoid read_input() {\n    cin >> D;\n    f1.resize(D); r1.resize(D);\n    f2.resize(D); r2.resize(D);\n    \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\nvector<vector<vector<int>>> construct_object(vector<string>& f, vector<string>& r) {\n    vector<vector<vector<int>>> obj(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(f[z][x] == '1' && r[z][y] == '1') {\n                    obj[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    return obj;\n}\n\nstruct Block {\n    set<tuple<int,int,int>> cells;\n    \n    Block normalized() const {\n        if(cells.empty()) return *this;\n        \n        int min_x = INT_MAX, min_y = INT_MAX, min_z = INT_MAX;\n        for(auto [x,y,z] : cells) {\n            min_x = min(min_x, x);\n            min_y = min(min_y, y);\n            min_z = min(min_z, z);\n        }\n        \n        Block result;\n        for(auto [x,y,z] : cells) {\n            result.cells.insert({x - min_x, y - min_y, z - min_z});\n        }\n        return result;\n    }\n    \n    bool operator<(const Block& other) const {\n        return cells < other.cells;\n    }\n};\n\nset<Block> get_24_rotations(const Block& block) {\n    set<Block> result;\n    \n    vector<function<tuple<int,int,int>(int,int,int)>> transforms;\n    \n    // All 24 orientations of a cube\n    transforms.push_back([](int x, int y, int z) { return make_tuple(x, y, z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-y, x, z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-x, -y, z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(y, -x, z); });\n    \n    transforms.push_back([](int x, int y, int z) { return make_tuple(z, y, -x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(z, x, y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(z, -y, x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(z, -x, -y); });\n    \n    transforms.push_back([](int x, int y, int z) { return make_tuple(-z, y, x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-z, -x, y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-z, -y, -x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-z, x, -y); });\n    \n    transforms.push_back([](int x, int y, int z) { return make_tuple(x, z, -y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-y, z, -x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-x, z, y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(y, z, x); });\n    \n    transforms.push_back([](int x, int y, int z) { return make_tuple(x, -z, y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(y, -z, -x); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-x, -z, -y); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-y, -z, x); });\n    \n    transforms.push_back([](int x, int y, int z) { return make_tuple(x, -y, -z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(y, x, -z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-x, y, -z); });\n    transforms.push_back([](int x, int y, int z) { return make_tuple(-y, -x, -z); });\n    \n    for(auto& transform : transforms) {\n        Block rotated;\n        for(auto [x,y,z] : block.cells) {\n            auto [nx,ny,nz] = transform(x,y,z);\n            rotated.cells.insert({nx, ny, nz});\n        }\n        result.insert(rotated.normalized());\n    }\n    \n    return result;\n}\n\nBlock extract_compact_block(vector<vector<vector<int>>>& obj,\n                           vector<vector<vector<bool>>>& used,\n                           int sx, int sy, int sz, int target_size) {\n    Block block;\n    priority_queue<tuple<double, int, int, int>> pq; // -score, x, y, z\n    set<tuple<int,int,int>> in_queue;\n    \n    block.cells.insert({sx, sy, sz});\n    used[sx][sy][sz] = true;\n    \n    int dx[] = {1,-1,0,0,0,0};\n    int dy[] = {0,0,1,-1,0,0};\n    int dz[] = {0,0,0,0,1,-1};\n    \n    // Add initial neighbors\n    for(int d = 0; d < 6; d++) {\n        int nx = sx + dx[d];\n        int ny = sy + dy[d];\n        int nz = sz + dz[d];\n        if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n           obj[nx][ny][nz] == 1 && !used[nx][ny][nz] && in_queue.find({nx,ny,nz}) == in_queue.end()) {\n            double dist = abs(nx-sx) + abs(ny-sy) + abs(nz-sz);\n            pq.push({-dist, nx, ny, nz});\n            in_queue.insert({nx,ny,nz});\n        }\n    }\n    \n    while(!pq.empty() && (int)block.cells.size() < target_size) {\n        auto [neg_score, x, y, z] = pq.top();\n        pq.pop();\n        \n        if(used[x][y][z]) continue;\n        \n        // Count adjacencies to current block\n        int adj_count = 0;\n        for(int d = 0; d < 6; d++) {\n            int nx = x + dx[d];\n            int ny = y + dy[d];\n            int nz = z + dz[d];\n            if(block.cells.count({nx, ny, nz}) > 0) {\n                adj_count++;\n            }\n        }\n        \n        // Only add if connected\n        if(adj_count > 0) {\n            block.cells.insert({x, y, z});\n            used[x][y][z] = true;\n            \n            // Add new neighbors\n            for(int d = 0; d < 6; d++) {\n                int nx = x + dx[d];\n                int ny = y + dy[d];\n                int nz = z + dz[d];\n                if(nx >= 0 && nx < D && ny >= 0 && ny < D && nz >= 0 && nz < D &&\n                   obj[nx][ny][nz] == 1 && !used[nx][ny][nz] && in_queue.find({nx,ny,nz}) == in_queue.end()) {\n                    // Score based on compactness\n                    double cx = 0, cy = 0, cz = 0;\n                    for(auto [bx,by,bz] : block.cells) {\n                        cx += bx; cy += by; cz += bz;\n                    }\n                    cx /= block.cells.size();\n                    cy /= block.cells.size();\n                    cz /= block.cells.size();\n                    double dist = sqrt((nx-cx)*(nx-cx) + (ny-cy)*(ny-cy) + (nz-cz)*(nz-cz));\n                    pq.push({-dist, nx, ny, nz});\n                    in_queue.insert({nx,ny,nz});\n                }\n            }\n        }\n    }\n    \n    return block;\n}\n\nvoid create_and_output() {\n    auto obj1 = construct_object(f1, r1);\n    auto obj2 = construct_object(f2, r2);\n    \n    vector<int> b1(D * D * D, 0);\n    vector<int> b2(D * D * D, 0);\n    \n    vector<vector<vector<bool>>> used1(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    vector<vector<vector<bool>>> used2(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n    \n    int block_id = 0;\n    \n    // Calculate volumes\n    int vol1 = 0, vol2 = 0, inter_vol = 0;\n    vector<vector<vector<int>>> intersection(D, vector<vector<int>>(D, vector<int>(D, 0)));\n    \n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z]) vol1++;\n                if(obj2[x][y][z]) vol2++;\n                if(obj1[x][y][z] && obj2[x][y][z]) {\n                    inter_vol++;\n                    intersection[x][y][z] = 1;\n                }\n            }\n        }\n    }\n    \n    // Phase 1: Multi-pass intersection exploitation\n    if(inter_vol > 0) {\n        vector<vector<vector<bool>>> inter_used(D, vector<vector<bool>>(D, vector<bool>(D, false)));\n        \n        // Pass 1: Large blocks\n        int large_size = min(30, max(12, inter_vol / 3));\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(intersection[x][y][z] && !inter_used[x][y][z]) {\n                        Block block = extract_compact_block(intersection, inter_used, x, y, z, large_size);\n                        if((int)block.cells.size() >= large_size / 2) {\n                            block_id++;\n                            for(auto [cx,cy,cz] : block.cells) {\n                                b1[cx * D * D + cy * D + cz] = block_id;\n                                b2[cx * D * D + cy * D + cz] = block_id;\n                                used1[cx][cy][cz] = true;\n                                used2[cx][cy][cz] = true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Pass 2: Medium blocks\n        int med_size = max(6, large_size / 2);\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(intersection[x][y][z] && !inter_used[x][y][z]) {\n                        Block block = extract_compact_block(intersection, inter_used, x, y, z, med_size);\n                        if(block.cells.size() >= 3) {\n                            block_id++;\n                            for(auto [cx,cy,cz] : block.cells) {\n                                b1[cx * D * D + cy * D + cz] = block_id;\n                                b2[cx * D * D + cy * D + cz] = block_id;\n                                used1[cx][cy][cz] = true;\n                                used2[cx][cy][cz] = true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Pass 3: Fill remaining intersection cells\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(intersection[x][y][z] && !used1[x][y][z]) {\n                        block_id++;\n                        b1[x * D * D + y * D + z] = block_id;\n                        b2[x * D * D + y * D + z] = block_id;\n                        used1[x][y][z] = true;\n                        used2[x][y][z] = true;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 2: Extract blocks for matching\n    vector<pair<Block, int>> blocks1, blocks2;\n    map<int, vector<int>> size_to_indices1, size_to_indices2;\n    \n    // Use varied block sizes\n    vector<int> block_sizes = {12, 10, 8, 7, 6, 5, 9, 11};\n    \n    for(int target_size : block_sizes) {\n        auto temp_used1 = used1;\n        auto temp_used2 = used2;\n        \n        // Extract from obj1\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(obj1[x][y][z] && !temp_used1[x][y][z]) {\n                        Block block = extract_compact_block(obj1, temp_used1, x, y, z, target_size);\n                        if((int)block.cells.size() >= min(4, target_size / 2)) {\n                            int idx = blocks1.size();\n                            blocks1.push_back({block, x * D * D + y * D + z});\n                            size_to_indices1[block.cells.size()].push_back(idx);\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Extract from obj2\n        for(int x = 0; x < D; x++) {\n            for(int y = 0; y < D; y++) {\n                for(int z = 0; z < D; z++) {\n                    if(obj2[x][y][z] && !temp_used2[x][y][z]) {\n                        Block block = extract_compact_block(obj2, temp_used2, x, y, z, target_size);\n                        if((int)block.cells.size() >= min(4, target_size / 2)) {\n                            int idx = blocks2.size();\n                            blocks2.push_back({block, x * D * D + y * D + z});\n                            size_to_indices2[block.cells.size()].push_back(idx);\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Multi-criteria matching\n    vector<bool> matched1(blocks1.size(), false);\n    vector<bool> matched2(blocks2.size(), false);\n    \n    // First: Match blocks of same size (more likely to match)\n    for(auto& [size, indices1] : size_to_indices1) {\n        if(size_to_indices2.count(size) == 0) continue;\n        auto& indices2 = size_to_indices2[size];\n        \n        for(int i : indices1) {\n            if(matched1[i]) continue;\n            \n            auto rotations = get_24_rotations(blocks1[i].first);\n            \n            for(int j : indices2) {\n                if(matched2[j]) continue;\n                \n                Block norm2 = blocks2[j].first.normalized();\n                \n                if(rotations.count(norm2) > 0) {\n                    // Check placement\n                    bool can_place = true;\n                    for(auto [x,y,z] : blocks1[i].first.cells) {\n                        if(used1[x][y][z]) {\n                            can_place = false;\n                            break;\n                        }\n                    }\n                    for(auto [x,y,z] : blocks2[j].first.cells) {\n                        if(used2[x][y][z]) {\n                            can_place = false;\n                            break;\n                        }\n                    }\n                    \n                    if(can_place) {\n                        block_id++;\n                        for(auto [x,y,z] : blocks1[i].first.cells) {\n                            b1[x * D * D + y * D + z] = block_id;\n                            used1[x][y][z] = true;\n                        }\n                        for(auto [x,y,z] : blocks2[j].first.cells) {\n                            b2[x * D * D + y * D + z] = block_id;\n                            used2[x][y][z] = true;\n                        }\n                        matched1[i] = true;\n                        matched2[j] = true;\n                        break;\n                    }\n                }\n            }\n        }\n    }\n    \n    // Second: Try to match remaining blocks across sizes\n    for(size_t i = 0; i < blocks1.size(); i++) {\n        if(matched1[i]) continue;\n        \n        auto rotations = get_24_rotations(blocks1[i].first);\n        \n        for(size_t j = 0; j < blocks2.size(); j++) {\n            if(matched2[j]) continue;\n            \n            Block norm2 = blocks2[j].first.normalized();\n            \n            if(rotations.count(norm2) > 0) {\n                bool can_place = true;\n                for(auto [x,y,z] : blocks1[i].first.cells) {\n                    if(used1[x][y][z]) {\n                        can_place = false;\n                        break;\n                    }\n                }\n                for(auto [x,y,z] : blocks2[j].first.cells) {\n                    if(used2[x][y][z]) {\n                        can_place = false;\n                        break;\n                    }\n                }\n                \n                if(can_place) {\n                    block_id++;\n                    for(auto [x,y,z] : blocks1[i].first.cells) {\n                        b1[x * D * D + y * D + z] = block_id;\n                        used1[x][y][z] = true;\n                    }\n                    for(auto [x,y,z] : blocks2[j].first.cells) {\n                        b2[x * D * D + y * D + z] = block_id;\n                        used2[x][y][z] = true;\n                    }\n                    matched1[i] = true;\n                    matched2[j] = true;\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Place unmatched blocks\n    for(size_t i = 0; i < blocks1.size(); i++) {\n        if(!matched1[i]) {\n            bool can_place = true;\n            for(auto [x,y,z] : blocks1[i].first.cells) {\n                if(used1[x][y][z]) {\n                    can_place = false;\n                    break;\n                }\n            }\n            if(can_place) {\n                block_id++;\n                for(auto [x,y,z] : blocks1[i].first.cells) {\n                    b1[x * D * D + y * D + z] = block_id;\n                    used1[x][y][z] = true;\n                }\n            }\n        }\n    }\n    \n    for(size_t i = 0; i < blocks2.size(); i++) {\n        if(!matched2[i]) {\n            bool can_place = true;\n            for(auto [x,y,z] : blocks2[i].first.cells) {\n                if(used2[x][y][z]) {\n                    can_place = false;\n                    break;\n                }\n            }\n            if(can_place) {\n                block_id++;\n                for(auto [x,y,z] : blocks2[i].first.cells) {\n                    b2[x * D * D + y * D + z] = block_id;\n                    used2[x][y][z] = true;\n                }\n            }\n        }\n    }\n    \n    // Fill remaining cells\n    for(int x = 0; x < D; x++) {\n        for(int y = 0; y < D; y++) {\n            for(int z = 0; z < D; z++) {\n                if(obj1[x][y][z] && !used1[x][y][z]) {\n                    block_id++;\n                    Block block = extract_compact_block(obj1, used1, x, y, z, 10);\n                    for(auto [cx,cy,cz] : block.cells) {\n                        b1[cx * D * D + cy * D + cz] = block_id;\n                    }\n                }\n                \n                if(obj2[x][y][z] && !used2[x][y][z]) {\n                    block_id++;\n                    Block block = extract_compact_block(obj2, used2, x, y, z, 10);\n                    for(auto [cx,cy,cz] : block.cells) {\n                        b2[cx * D * D + cy * D + cz] = block_id;\n                    }\n                }\n            }\n        }\n    }\n    \n    cout << block_id << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b1[i];\n    }\n    cout << endl;\n    \n    for(int i = 0; i < D * D * D; i++) {\n        if(i > 0) cout << \" \";\n        cout << b2[i];\n    }\n    cout << endl;\n}\n\nint main() {\n    read_input();\n    create_and_output();\n    return 0;\n}","ahc020":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Edge {\n    int u, v, id;\n    long long w;\n};\n\nclass Solution {\n    int N, M, K;\n    vector<pair<int, int>> vertices;\n    vector<Edge> edges;\n    vector<vector<pair<int, pair<int, long long>>>> adj;\n    vector<pair<int, int>> residents;\n    vector<vector<int>> resident_dist;\n    vector<vector<long long>> vertex_dist;\n    vector<vector<vector<int>>> vertex_paths;\n    \n    // Compute all pairs shortest paths with path reconstruction\n    void computeAllPairs() {\n        vertex_dist.assign(N, vector<long long>(N, LLONG_MAX));\n        vertex_paths.assign(N, vector<vector<int>>(N));\n        \n        for (int src = 0; src < N; src++) {\n            vector<int> parent_edge(N, -1);\n            vector<int> parent_vertex(N, -1);\n            priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;\n            \n            vertex_dist[src][src] = 0;\n            pq.push({0, src});\n            \n            while (!pq.empty()) {\n                auto [d, u] = pq.top();\n                pq.pop();\n                \n                if (d > vertex_dist[src][u]) continue;\n                \n                for (auto [v, info] : adj[u]) {\n                    if (vertex_dist[src][u] + info.second < vertex_dist[src][v]) {\n                        vertex_dist[src][v] = vertex_dist[src][u] + info.second;\n                        parent_edge[v] = info.first;\n                        parent_vertex[v] = u;\n                        pq.push({vertex_dist[src][v], v});\n                    }\n                }\n            }\n            \n            // Build paths\n            for (int dst = 0; dst < N; dst++) {\n                if (dst != src && parent_edge[dst] != -1) {\n                    int curr = dst;\n                    while (parent_edge[curr] != -1) {\n                        vertex_paths[src][dst].push_back(parent_edge[curr]);\n                        curr = parent_vertex[curr];\n                    }\n                    reverse(vertex_paths[src][dst].begin(), vertex_paths[src][dst].end());\n                }\n            }\n        }\n    }\n    \n    // Build MST-based Steiner tree\n    vector<int> buildSteinerTree(const set<int>& terminals) {\n        vector<int> edge_used(M, 0);\n        if (terminals.size() <= 1) return edge_used;\n        \n        vector<int> term_vec(terminals.begin(), terminals.end());\n        int t = term_vec.size();\n        \n        // Prim's algorithm on terminal graph\n        vector<bool> in_tree(t, false);\n        vector<long long> key(t, LLONG_MAX);\n        vector<int> parent(t, -1);\n        \n        key[0] = 0;\n        for (int i = 0; i < t-1; i++) {\n            int u = -1;\n            for (int j = 0; j < t; j++) {\n                if (!in_tree[j] && (u == -1 || key[j] < key[u])) {\n                    u = j;\n                }\n            }\n            \n            in_tree[u] = true;\n            \n            for (int v = 0; v < t; v++) {\n                if (!in_tree[v] && term_vec[u] != term_vec[v]) {\n                    long long dist = vertex_dist[term_vec[u]][term_vec[v]];\n                    if (dist < key[v]) {\n                        key[v] = dist;\n                        parent[v] = u;\n                    }\n                }\n            }\n        }\n        \n        // Add edges for MST paths\n        for (int i = 1; i < t; i++) {\n            if (parent[i] != -1) {\n                for (int e : vertex_paths[term_vec[parent[i]]][term_vec[i]]) {\n                    edge_used[e] = 1;\n                }\n            }\n        }\n        \n        return edge_used;\n    }\n    \n    // Get connected vertices\n    set<int> getConnected(const vector<int>& edge_used) {\n        set<int> connected;\n        function<void(int)> dfs = [&](int u) {\n            connected.insert(u);\n            for (auto [v, info] : adj[u]) {\n                if (edge_used[info.first] && !connected.count(v)) {\n                    dfs(v);\n                }\n            }\n        };\n        dfs(0);\n        return connected;\n    }\n    \n    // Compute cost\n    long long computeCost(const vector<int>& powers, const vector<int>& edge_used) {\n        long long cost = 0;\n        for (int p : powers) cost += (long long)p * p;\n        for (int i = 0; i < M; i++) {\n            if (edge_used[i]) cost += edges[i].w;\n        }\n        return cost;\n    }\n    \n    // Get initial solution using clustering\n    pair<vector<int>, vector<int>> getInitialSolution() {\n        // Group nearby residents into clusters\n        vector<int> cluster_id(K, -1);\n        int num_clusters = 0;\n        \n        for (int i = 0; i < K; i++) {\n            if (cluster_id[i] != -1) continue;\n            \n            cluster_id[i] = num_clusters++;\n            queue<int> q;\n            q.push(i);\n            \n            while (!q.empty()) {\n                int r = q.front();\n                q.pop();\n                \n                for (int r2 = 0; r2 < K; r2++) {\n                    if (cluster_id[r2] == -1) {\n                        long long dx = residents[r].first - residents[r2].first;\n                        long long dy = residents[r].second - residents[r2].second;\n                        if (dx * dx + dy * dy <= 500000) { // Within ~700 distance\n                            cluster_id[r2] = cluster_id[r];\n                            q.push(r2);\n                        }\n                    }\n                }\n            }\n        }\n        \n        // For each cluster, find best covering vertices\n        vector<int> powers(N, 0);\n        set<int> active;\n        active.insert(0);\n        \n        for (int c = 0; c < num_clusters; c++) {\n            vector<int> cluster_residents;\n            for (int r = 0; r < K; r++) {\n                if (cluster_id[r] == c) {\n                    cluster_residents.push_back(r);\n                }\n            }\n            \n            if (cluster_residents.empty()) continue;\n            \n            // Find best vertex set to cover this cluster\n            vector<bool> covered(cluster_residents.size(), false);\n            \n            while (count(covered.begin(), covered.end(), false) > 0) {\n                int best_v = -1;\n                double best_score = -1;\n                int best_power = 0;\n                \n                for (int v = 0; v < N; v++) {\n                    if (vertex_dist[0][v] == LLONG_MAX) continue;\n                    \n                    int count = 0;\n                    int max_power = powers[v];\n                    \n                    for (int i = 0; i < cluster_residents.size(); i++) {\n                        if (!covered[i]) {\n                            int r = cluster_residents[i];\n                            if (resident_dist[r][v] <= 2500) { // Prefer lower power\n                                count++;\n                                max_power = max(max_power, resident_dist[r][v]);\n                            }\n                        }\n                    }\n                    \n                    if (count > 0 && max_power <= 5000) {\n                        double edge_cost = active.count(v) ? 0 : vertex_dist[0][v];\n                        double power_cost = max_power * max_power - powers[v] * powers[v];\n                        double score = count / (1.0 + (edge_cost + power_cost) / 1000000.0);\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_v = v;\n                            best_power = max_power;\n                        }\n                    }\n                }\n                \n                // If no low-power vertex found, use any\n                if (best_v == -1) {\n                    for (int v = 0; v < N; v++) {\n                        if (vertex_dist[0][v] == LLONG_MAX) continue;\n                        \n                        int count = 0;\n                        int max_power = powers[v];\n                        \n                        for (int i = 0; i < cluster_residents.size(); i++) {\n                            if (!covered[i]) {\n                                int r = cluster_residents[i];\n                                if (resident_dist[r][v] <= 5000) {\n                                    count++;\n                                    max_power = max(max_power, resident_dist[r][v]);\n                                }\n                            }\n                        }\n                        \n                        if (count > 0 && max_power <= 5000) {\n                            best_v = v;\n                            best_power = max_power;\n                            break;\n                        }\n                    }\n                }\n                \n                if (best_v == -1) break;\n                \n                active.insert(best_v);\n                powers[best_v] = best_power;\n                \n                for (int i = 0; i < cluster_residents.size(); i++) {\n                    int r = cluster_residents[i];\n                    if (resident_dist[r][best_v] <= best_power) {\n                        covered[i] = true;\n                    }\n                }\n            }\n        }\n        \n        return {powers, buildSteinerTree(active)};\n    }\n    \n    // Local search optimization\n    void localSearch(vector<int>& powers, vector<int>& edge_used) {\n        long long current_cost = computeCost(powers, edge_used);\n        bool improved = true;\n        int iterations = 0;\n        \n        while (improved && iterations < 20) {\n            improved = false;\n            iterations++;\n            \n            set<int> active;\n            for (int v = 0; v < N; v++) {\n                if (v == 0 || powers[v] > 0) active.insert(v);\n            }\n            \n            // Try removing vertices\n            for (int v : active) {\n                if (v == 0 || powers[v] == 0) continue;\n                \n                // Try to redistribute coverage\n                vector<int> temp_powers = powers;\n                temp_powers[v] = 0;\n                \n                // Check which residents need reassignment\n                bool can_remove = true;\n                for (int r = 0; r < K; r++) {\n                    if (resident_dist[r][v] <= powers[v]) {\n                        bool covered = false;\n                        for (int u : active) {\n                            if (u != v && temp_powers[u] > 0 && \n                                resident_dist[r][u] <= temp_powers[u]) {\n                                covered = true;\n                                break;\n                            }\n                        }\n                        \n                        if (!covered) {\n                            // Find best alternative\n                            int best_u = -1;\n                            int min_increase = INT_MAX;\n                            \n                            for (int u : active) {\n                                if (u != v && resident_dist[r][u] <= 5000) {\n                                    int needed = resident_dist[r][u];\n                                    int increase = max(0, needed - temp_powers[u]);\n                                    if (increase < min_increase) {\n                                        min_increase = increase;\n                                        best_u = u;\n                                    }\n                                }\n                            }\n                            \n                            if (best_u == -1) {\n                                can_remove = false;\n                                break;\n                            }\n                            \n                            temp_powers[best_u] = max(temp_powers[best_u], resident_dist[r][best_u]);\n                        }\n                    }\n                }\n                \n                if (can_remove) {\n                    set<int> new_active;\n                    for (int u = 0; u < N; u++) {\n                        if (u == 0 || temp_powers[u] > 0) {\n                            new_active.insert(u);\n                        }\n                    }\n                    \n                    vector<int> temp_edges = buildSteinerTree(new_active);\n                    long long new_cost = computeCost(temp_powers, temp_edges);\n                    \n                    if (new_cost < current_cost) {\n                        powers = temp_powers;\n                        edge_used = temp_edges;\n                        current_cost = new_cost;\n                        improved = true;\n                    }\n                }\n            }\n            \n            // Try adding vertices to split high-power ones\n            vector<int> high_power;\n            for (int v : active) {\n                if (powers[v] >= 3500) {\n                    high_power.push_back(v);\n                }\n            }\n            \n            for (int v : high_power) {\n                // Find residents covered by v with high distance\n                vector<int> far_residents;\n                for (int r = 0; r < K; r++) {\n                    if (resident_dist[r][v] >= 2500 && resident_dist[r][v] <= powers[v]) {\n                        far_residents.push_back(r);\n                    }\n                }\n                \n                if (far_residents.size() >= 5) {\n                    // Try to find closer vertex for these residents\n                    int best_u = -1;\n                    int best_power = 0;\n                    long long best_added_cost = LLONG_MAX;\n                    \n                    for (int u = 0; u < N; u++) {\n                        if (active.count(u) || vertex_dist[0][u] == LLONG_MAX) continue;\n                        \n                        int count = 0;\n                        int max_power = 0;\n                        for (int r : far_residents) {\n                            if (resident_dist[r][u] <= 2000) {\n                                count++;\n                                max_power = max(max_power, resident_dist[r][u]);\n                            }\n                        }\n                        \n                        if (count >= far_residents.size() / 2 && max_power <= 2500) {\n                            long long added_cost = vertex_dist[0][u] + \n                                                  (long long)max_power * max_power;\n                            if (added_cost < best_added_cost) {\n                                best_added_cost = added_cost;\n                                best_u = u;\n                                best_power = max_power;\n                            }\n                        }\n                    }\n                    \n                    if (best_u != -1) {\n                        // Check if adding u and reducing v's power helps\n                        vector<int> temp_powers = powers;\n                        temp_powers[best_u] = best_power;\n                        \n                        // Reduce v's power\n                        int new_v_power = 0;\n                        for (int r = 0; r < K; r++) {\n                            if (resident_dist[r][v] <= powers[v]) {\n                                bool covered_elsewhere = false;\n                                if (resident_dist[r][best_u] <= best_power) {\n                                    covered_elsewhere = true;\n                                } else {\n                                    for (int u : active) {\n                                        if (u != v && temp_powers[u] > 0 && \n                                            resident_dist[r][u] <= temp_powers[u]) {\n                                            covered_elsewhere = true;\n                                            break;\n                                        }\n                                    }\n                                }\n                                \n                                if (!covered_elsewhere) {\n                                    new_v_power = max(new_v_power, resident_dist[r][v]);\n                                }\n                            }\n                        }\n                        temp_powers[v] = new_v_power;\n                        \n                        set<int> new_active = active;\n                        new_active.insert(best_u);\n                        \n                        vector<int> temp_edges = buildSteinerTree(new_active);\n                        long long new_cost = computeCost(temp_powers, temp_edges);\n                        \n                        if (new_cost < current_cost) {\n                            powers = temp_powers;\n                            edge_used = temp_edges;\n                            current_cost = new_cost;\n                            improved = true;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \npublic:\n    void run() {\n        cin >> N >> M >> K;\n        \n        vertices.resize(N);\n        for (int i = 0; i < N; i++) {\n            cin >> vertices[i].first >> vertices[i].second;\n        }\n        \n        edges.resize(M);\n        adj.resize(N);\n        \n        for (int i = 0; i < M; i++) {\n            cin >> edges[i].u >> edges[i].v >> edges[i].w;\n            edges[i].u--; edges[i].v--;\n            edges[i].id = i;\n            adj[edges[i].u].push_back({edges[i].v, {i, edges[i].w}});\n            adj[edges[i].v].push_back({edges[i].u, {i, edges[i].w}});\n        }\n        \n        residents.resize(K);\n        for (int i = 0; i < K; i++) {\n            cin >> residents[i].first >> residents[i].second;\n        }\n        \n        // Precompute\n        resident_dist.resize(K, vector<int>(N));\n        for (int r = 0; r < K; r++) {\n            for (int v = 0; v < N; v++) {\n                long long dx = residents[r].first - vertices[v].first;\n                long long dy = residents[r].second - vertices[v].second;\n                resident_dist[r][v] = (int)ceil(sqrt(dx * dx + dy * dy));\n            }\n        }\n        \n        computeAllPairs();\n        \n        // Get initial solution\n        auto [powers, edge_used] = getInitialSolution();\n        \n        // Optimize\n        localSearch(powers, edge_used);\n        \n        // Final cleanup\n        set<int> connected = getConnected(edge_used);\n        for (int v = 0; v < N; v++) {\n            if (!connected.count(v)) {\n                powers[v] = 0;\n            }\n        }\n        \n        // Output\n        for (int i = 0; i < N; i++) {\n            cout << powers[i] << (i == N-1 ? \"\\n\" : \" \");\n        }\n        for (int i = 0; i < M; i++) {\n            cout << edge_used[i] << (i == M-1 ? \"\\n\" : \" \");\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.run();\n    \n    return 0;\n}","ahc021":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 30;\n\nvector<vector<int>> pyramid(N);\nvector<tuple<int,int,int,int>> moves;\n\nvoid swapBalls(int x1, int y1, int x2, int y2) {\n    swap(pyramid[x1][y1], pyramid[x2][y2]);\n    moves.push_back({x1, y1, x2, y2});\n}\n\n// Count violations for a specific position\nint positionViolations(int x, int y) {\n    int violations = 0;\n    if (x < N - 1) {\n        if (pyramid[x][y] > pyramid[x + 1][y]) violations++;\n        if (pyramid[x][y] > pyramid[x + 1][y + 1]) violations++;\n    }\n    return violations;\n}\n\n// Count total violations\nint countViolations() {\n    int violations = 0;\n    for (int x = 0; x < N - 1; x++) {\n        for (int y = 0; y <= x; y++) {\n            violations += positionViolations(x, y);\n        }\n    }\n    return violations;\n}\n\n// Heapify from a position downward\nvoid heapifyDown(int x, int y) {\n    if (x >= N - 1) return;\n    \n    int leftChild = pyramid[x + 1][y];\n    int rightChild = pyramid[x + 1][y + 1];\n    \n    // Find minimum among parent and children\n    if (pyramid[x][y] > leftChild && leftChild <= rightChild) {\n        swapBalls(x, y, x + 1, y);\n        heapifyDown(x + 1, y);\n    } else if (pyramid[x][y] > rightChild) {\n        swapBalls(x, y, x + 1, y + 1);\n        heapifyDown(x + 1, y + 1);\n    }\n}\n\n// Try to bubble up small values\nvoid bubbleUp(int x, int y) {\n    if (x == 0) return;\n    \n    // Check possible parent positions\n    vector<pair<int,int>> parents;\n    if (y > 0) parents.push_back({x - 1, y - 1});\n    if (y < x) parents.push_back({x - 1, y});\n    \n    for (auto [px, py] : parents) {\n        if (px >= 0 && py >= 0 && py <= px) {\n            if (pyramid[x][y] < pyramid[px][py]) {\n                // Check if swap would not create new violations\n                int currentViolations = positionViolations(px, py);\n                swapBalls(x, y, px, py);\n                int newViolations = positionViolations(px, py);\n                \n                if (newViolations <= currentViolations) {\n                    bubbleUp(px, py);\n                    return;\n                } else {\n                    // Revert if it made things worse\n                    swapBalls(x, y, px, py);\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    // Read input\n    for (int x = 0; x < N; x++) {\n        pyramid[x].resize(x + 1);\n        for (int y = 0; y <= x; y++) {\n            cin >> pyramid[x][y];\n        }\n    }\n    \n    // Phase 1: Initial heapify from bottom-up\n    for (int x = N - 2; x >= 0; x--) {\n        for (int y = 0; y <= x; y++) {\n            heapifyDown(x, y);\n        }\n    }\n    \n    // Phase 2: Find small values in lower levels and bubble them up\n    vector<tuple<int, int, int>> valuePositions;\n    for (int x = 0; x < N; x++) {\n        for (int y = 0; y <= x; y++) {\n            valuePositions.push_back({pyramid[x][y], x, y});\n        }\n    }\n    sort(valuePositions.begin(), valuePositions.end());\n    \n    // Try to move smallest values upward\n    for (int i = 0; i < min(100, (int)valuePositions.size()); i++) {\n        auto [val, x, y] = valuePositions[i];\n        // Find current position of this value\n        bool found = false;\n        for (int cx = 0; cx < N && !found; cx++) {\n            for (int cy = 0; cy <= cx && !found; cy++) {\n                if (pyramid[cx][cy] == val) {\n                    bubbleUp(cx, cy);\n                    found = true;\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Final cleanup - fix remaining violations\n    int maxCleanupIter = 1000;\n    for (int iter = 0; iter < maxCleanupIter && moves.size() < 9500; iter++) {\n        if (countViolations() == 0) break;\n        \n        bool improved = false;\n        for (int x = 0; x < N - 1; x++) {\n            for (int y = 0; y <= x; y++) {\n                if (pyramid[x][y] > pyramid[x + 1][y]) {\n                    swapBalls(x, y, x + 1, y);\n                    heapifyDown(x + 1, y);\n                    improved = true;\n                }\n                if (pyramid[x][y] > pyramid[x + 1][y + 1]) {\n                    swapBalls(x, y, x + 1, y + 1);\n                    heapifyDown(x + 1, y + 1);\n                    improved = true;\n                }\n            }\n        }\n        if (!improved) break;\n    }\n    \n    // Output\n    cout << moves.size() << endl;\n    for (auto [x1, y1, x2, y2] : moves) {\n        cout << x1 << \" \" << y1 << \" \" << x2 << \" \" << y2 << endl;\n    }\n    \n    return 0;\n}","toyota2023summer-final":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[] = {-1, 0, 1, 0};\nconst int dy[] = {0, 1, 0, -1};\n\nstruct Container {\n    int number;\n    int x, y;\n};\n\nclass Warehouse {\n    int D, N;\n    int entrance_x, entrance_y;\n    vector<vector<int>> grid; // -1: obstacle, -2: empty, >=0: container number\n    vector<Container> containers;\n    vector<pair<int,int>> obstacles;\n    \npublic:\n    Warehouse() {\n        cin >> D >> N;\n        entrance_x = 0;\n        entrance_y = (D - 1) / 2;\n        \n        grid.resize(D, vector<int>(D, -2));\n        \n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n            grid[x][y] = -1;\n            obstacles.push_back({x, y});\n        }\n    }\n    \n    bool isValid(int x, int y) {\n        return x >= 0 && x < D && y >= 0 && y < D;\n    }\n    \n    bool isReachable(int tx, int ty) {\n        if (!isValid(tx, ty) || grid[tx][ty] == -1) return false;\n        if (tx == entrance_x && ty == entrance_y) return true;\n        \n        queue<pair<int,int>> q;\n        vector<vector<bool>> visited(D, vector<bool>(D, false));\n        q.push({entrance_x, entrance_y});\n        visited[entrance_x][entrance_y] = true;\n        \n        while (!q.empty()) {\n            auto [x, y] = q.front();\n            q.pop();\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = x + dx[dir];\n                int ny = y + dy[dir];\n                \n                if (!isValid(nx, ny) || visited[nx][ny]) continue;\n                if (grid[nx][ny] != -2 && !(nx == tx && ny == ty)) continue;\n                \n                if (nx == tx && ny == ty) return true;\n                \n                visited[nx][ny] = true;\n                q.push({nx, ny});\n            }\n        }\n        \n        return false;\n    }\n    \n    int getDistance(int x, int y) {\n        if (!isReachable(x, y)) return INT_MAX;\n        \n        queue<pair<int,int>> q;\n        vector<vector<int>> dist(D, vector<int>(D, INT_MAX));\n        q.push({entrance_x, entrance_y});\n        dist[entrance_x][entrance_y] = 0;\n        \n        while (!q.empty()) {\n            auto [cx, cy] = q.front();\n            q.pop();\n            \n            if (cx == x && cy == y) return dist[x][y];\n            \n            for (int dir = 0; dir < 4; dir++) {\n                int nx = cx + dx[dir];\n                int ny = cy + dy[dir];\n                \n                if (!isValid(nx, ny) || grid[nx][ny] != -2) continue;\n                if (dist[nx][ny] != INT_MAX) continue;\n                \n                dist[nx][ny] = dist[cx][cy] + 1;\n                q.push({nx, ny});\n            }\n        }\n        \n        return INT_MAX;\n    }\n    \n    pair<int,int> placeContainer(int container_num) {\n        // Find all reachable empty positions\n        vector<pair<int, pair<int,int>>> candidates;\n        \n        for (int i = 0; i < D; i++) {\n            for (int j = 0; j < D; j++) {\n                if (i == entrance_x && j == entrance_y) continue;\n                if (grid[i][j] != -2) continue;\n                \n                int dist = getDistance(i, j);\n                if (dist != INT_MAX) {\n                    candidates.push_back({dist, {i, j}});\n                }\n            }\n        }\n        \n        if (candidates.empty()) {\n            // Should not happen in valid test cases\n            return {0, 0};\n        }\n        \n        // Sort by distance\n        sort(candidates.begin(), candidates.end());\n        \n        // Place based on container number relative to total containers\n        int total_containers = D * D - 1 - N;\n        int idx = (container_num * candidates.size()) / total_containers;\n        idx = min(idx, (int)candidates.size() - 1);\n        \n        // Try to place at the calculated index, but also consider nearby positions\n        // to avoid blocking\n        int best_idx = idx;\n        int range = min(5, (int)candidates.size());\n        \n        for (int offset = 0; offset < range; offset++) {\n            for (int sign : {1, -1}) {\n                int test_idx = idx + sign * offset;\n                if (test_idx >= 0 && test_idx < candidates.size()) {\n                    auto [x, y] = candidates[test_idx].second;\n                    \n                    // Check if this placement would block fewer cells\n                    int blocked_count = 0;\n                    grid[x][y] = container_num; // Temporarily place\n                    \n                    for (int i = 0; i < D; i++) {\n                        for (int j = 0; j < D; j++) {\n                            if (grid[i][j] == -2 && !isReachable(i, j)) {\n                                blocked_count++;\n                            }\n                        }\n                    }\n                    \n                    grid[x][y] = -2; // Remove temporary placement\n                    \n                    if (blocked_count <= 2) { // Acceptable blocking\n                        best_idx = test_idx;\n                        goto found;\n                    }\n                }\n            }\n        }\n        \n        found:\n        auto [px, py] = candidates[best_idx].second;\n        grid[px][py] = container_num;\n        containers.push_back({container_num, px, py});\n        \n        return {px, py};\n    }\n    \n    vector<pair<int,int>> getRetrievalOrder() {\n        vector<pair<int,int>> result;\n        vector<bool> retrieved(containers.size(), false);\n        \n        while (result.size() < containers.size()) {\n            int best_idx = -1;\n            int best_number = INT_MAX;\n            \n            // Find the smallest numbered container that's accessible\n            for (int i = 0; i < containers.size(); i++) {\n                if (retrieved[i]) continue;\n                \n                if (isReachable(containers[i].x, containers[i].y)) {\n                    if (containers[i].number < best_number) {\n                        best_number = containers[i].number;\n                        best_idx = i;\n                    }\n                }\n            }\n            \n            if (best_idx == -1) {\n                // Should not happen, but fallback to any accessible container\n                for (int i = 0; i < containers.size(); i++) {\n                    if (retrieved[i]) continue;\n                    if (isReachable(containers[i].x, containers[i].y)) {\n                        best_idx = i;\n                        break;\n                    }\n                }\n            }\n            \n            retrieved[best_idx] = true;\n            grid[containers[best_idx].x][containers[best_idx].y] = -2;\n            result.push_back({containers[best_idx].x, containers[best_idx].y});\n        }\n        \n        return result;\n    }\n    \n    void run() {\n        int total_containers = D * D - 1 - N;\n        \n        // Place containers as they arrive\n        for (int i = 0; i < total_containers; i++) {\n            int container_num;\n            cin >> container_num;\n            \n            auto [x, y] = placeContainer(container_num);\n            cout << x << \" \" << y << endl;\n            cout.flush();\n        }\n        \n        // Determine retrieval order\n        auto retrieval_order = getRetrievalOrder();\n        for (auto [x, y] : retrieval_order) {\n            cout << x << \" \" << y << endl;\n        }\n        cout.flush();\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Warehouse warehouse;\n    warehouse.run();\n    \n    return 0;\n}","ahc024":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\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    // Extract adjacencies from input\n    set<pair<int, int>> adjacencies;\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j + 1 < n && grid[i][j] != grid[i][j+1]) {\n                adjacencies.insert({min(grid[i][j], grid[i][j+1]), \n                                   max(grid[i][j], grid[i][j+1])});\n            }\n            if (i + 1 < n && grid[i][j] != grid[i+1][j]) {\n                adjacencies.insert({min(grid[i][j], grid[i+1][j]), \n                                   max(grid[i][j], grid[i+1][j])});\n            }\n        }\n    }\n    \n    // Find which wards are on the boundary in the input\n    set<int> boundaryWards;\n    for (int j = 0; j < n; j++) {\n        boundaryWards.insert(grid[0][j]);      // top edge\n        boundaryWards.insert(grid[n-1][j]);    // bottom edge\n    }\n    for (int i = 1; i < n-1; i++) {\n        boundaryWards.insert(grid[i][0]);      // left edge\n        boundaryWards.insert(grid[i][n-1]);    // right edge\n    }\n    \n    // Add boundary adjacencies\n    for (int ward : boundaryWards) {\n        adjacencies.insert({0, ward});\n    }\n    \n    // Create output - use the same grid as input initially\n    vector<vector<int>> result = grid;\n    \n    // Output (for now, just output the same as input to test)\n    for (int i = 0; i < n; i++) {\n        for (int j = 0; j < n; j++) {\n            if (j > 0) cout << \" \";\n            cout << result[i][j];\n        }\n        cout << \"\\n\";\n    }\n    \n    return 0;\n}","ahc025":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N, D, Q;\nvector<double> weight;\nvector<int> comparison_count;\n\nchar query(const vector<int>& left, const vector<int>& right) {\n    cout << left.size() << \" \" << right.size();\n    for (int x : left) cout << \" \" << x;\n    for (int x : right) cout << \" \" << x;\n    cout << endl;\n    cout.flush();\n    \n    char result;\n    cin >> result;\n    return result;\n}\n\nvoid update_weights(const vector<int>& left, const vector<int>& right, char result) {\n    double left_sum = 0, right_sum = 0;\n    int min_comps = 1000000;\n    \n    for (int i : left) {\n        left_sum += weight[i];\n        comparison_count[i]++;\n        min_comps = min(min_comps, comparison_count[i]);\n    }\n    for (int i : right) {\n        right_sum += weight[i];\n        comparison_count[i]++;\n        min_comps = min(min_comps, comparison_count[i]);\n    }\n    \n    // Adaptive learning rate based on confidence\n    double factor = 1.0 + 0.2 / sqrt(1.0 + min_comps);\n    \n    if (result == '<') {\n        double ratio = sqrt(factor);\n        for (int i : left) weight[i] /= ratio;\n        for (int i : right) weight[i] *= ratio;\n    } else if (result == '>') {\n        double ratio = sqrt(factor);\n        for (int i : left) weight[i] *= ratio;\n        for (int i : right) weight[i] /= ratio;\n    } else {\n        double avg = (left_sum + right_sum) / (left.size() + right.size());\n        double mix = 0.2 / sqrt(1.0 + min_comps);\n        for (int i : left) weight[i] = weight[i] * (1 - mix) + avg * mix;\n        for (int i : right) weight[i] = weight[i] * (1 - mix) + avg * mix;\n    }\n    \n    // Normalize\n    double total = accumulate(weight.begin(), weight.end(), 0.0);\n    if (total > 0) {\n        double scale = N * 1000.0 / total;\n        for (int i = 0; i < N; i++) weight[i] *= scale;\n    }\n}\n\ndouble calc_variance(const vector<int>& assignment) {\n    vector<double> sums(D, 0);\n    for (int i = 0; i < N; i++) {\n        sums[assignment[i]] += weight[i];\n    }\n    double mean = accumulate(sums.begin(), sums.end(), 0.0) / D;\n    double var = 0;\n    for (double s : sums) var += (s - mean) * (s - mean);\n    return var;\n}\n\nvoid optimize_partition(vector<int>& assignment) {\n    vector<double> sums(D, 0);\n    for (int i = 0; i < N; i++) {\n        sums[assignment[i]] += weight[i];\n    }\n    \n    double mean = accumulate(sums.begin(), sums.end(), 0.0) / D;\n    \n    // Multiple optimization passes\n    for (int pass = 0; pass < 3; pass++) {\n        bool improved = true;\n        int iterations = 0;\n        \n        while (improved && iterations < 30) {\n            improved = false;\n            iterations++;\n            \n            // Try moving items to better groups\n            vector<int> order(N);\n            iota(order.begin(), order.end(), 0);\n            sort(order.begin(), order.end(), [&](int a, int b) {\n                return weight[a] > weight[b];\n            });\n            \n            for (int i : order) {\n                int old_g = assignment[i];\n                double w = weight[i];\n                \n                // Find best group for this item\n                int best_g = old_g;\n                double best_score = 0;\n                for (int g = 0; g < D; g++) {\n                    best_score += abs(sums[g] - mean);\n                }\n                \n                for (int new_g = 0; new_g < D; new_g++) {\n                    if (new_g != old_g) {\n                        double new_score = 0;\n                        for (int g = 0; g < D; g++) {\n                            double s = sums[g];\n                            if (g == old_g) s -= w;\n                            if (g == new_g) s += w;\n                            new_score += abs(s - mean);\n                        }\n                        \n                        if (new_score < best_score - 0.1) {\n                            best_score = new_score;\n                            best_g = new_g;\n                        }\n                    }\n                }\n                \n                if (best_g != old_g) {\n                    assignment[i] = best_g;\n                    sums[old_g] -= w;\n                    sums[best_g] += w;\n                    improved = true;\n                }\n            }\n            \n            // Try swaps\n            if (!improved) {\n                for (int i = 0; i < N && !improved; i++) {\n                    for (int j = i + 1; j < N; j++) {\n                        if (assignment[i] != assignment[j]) {\n                            int g1 = assignment[i], g2 = assignment[j];\n                            double w1 = weight[i], w2 = weight[j];\n                            \n                            double curr_score = abs(sums[g1] - mean) + abs(sums[g2] - mean);\n                            double new_score = abs(sums[g1] - w1 + w2 - mean) + \n                                             abs(sums[g2] - w2 + w1 - mean);\n                            \n                            if (new_score < curr_score - 0.1) {\n                                assignment[i] = g2;\n                                assignment[j] = g1;\n                                sums[g1] = sums[g1] - w1 + w2;\n                                sums[g2] = sums[g2] - w2 + w1;\n                                improved = true;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    cin >> N >> D >> Q;\n    \n    weight.assign(N, 1000.0);\n    comparison_count.assign(N, 0);\n    \n    int queries_used = 0;\n    \n    // Phase 1: Strategic comparisons (40% of queries)\n    int phase1_limit = Q * 2 / 5;\n    \n    // Compare neighbors and strategic pairs\n    for (int stride = 1; stride <= 3 && queries_used < phase1_limit; stride++) {\n        for (int i = 0; i < N && queries_used < phase1_limit; i++) {\n            int j = (i + stride) % N;\n            if (i != j) {\n                char result = query({i}, {j});\n                queries_used++;\n                update_weights({i}, {j}, result);\n            }\n        }\n    }\n    \n    // Phase 2: Group comparisons (50% of queries)\n    while (queries_used < Q * 9 / 10) {\n        vector<pair<double, int>> sorted;\n        for (int i = 0; i < N; i++) {\n            sorted.push_back({weight[i], i});\n        }\n        sort(sorted.begin(), sorted.end());\n        \n        // Dynamic group size\n        int group_size = min(5, max(2, N / (10 + queries_used * 10 / Q)));\n        \n        // Compare different percentiles\n        vector<vector<int>> percentile_groups;\n        int num_groups = min(4, D * 2);\n        \n        for (int p = 0; p < num_groups; p++) {\n            vector<int> group;\n            int start = p * N / num_groups;\n            int end = min(N, (p + 1) * N / num_groups);\n            for (int i = start; i < min(start + group_size, end); i++) {\n                group.push_back(sorted[i].second);\n            }\n            if (!group.empty()) percentile_groups.push_back(group);\n        }\n        \n        // Compare non-adjacent groups\n        for (int i = 0; i < (int)percentile_groups.size() && queries_used < Q * 9 / 10; i++) {\n            for (int j = i + 2; j < (int)percentile_groups.size() && queries_used < Q * 9 / 10; j++) {\n                char result = query(percentile_groups[i], percentile_groups[j]);\n                queries_used++;\n                update_weights(percentile_groups[i], percentile_groups[j], result);\n            }\n        }\n        \n        // Compare adjacent items with similar weights\n        for (int i = 0; i < N - 1 && queries_used < Q * 9 / 10; i++) {\n            if (comparison_count[sorted[i].second] < 5 && \n                comparison_count[sorted[i+1].second] < 5 &&\n                abs(sorted[i].first - sorted[i+1].first) < 100) {\n                char result = query({sorted[i].second}, {sorted[i+1].second});\n                queries_used++;\n                update_weights({sorted[i].second}, {sorted[i+1].second}, result);\n            }\n        }\n    }\n    \n    // Build initial partition using Karmarkar-Karp style approach\n    vector<pair<double, int>> sorted;\n    for (int i = 0; i < N; i++) {\n        sorted.push_back({weight[i], i});\n    }\n    sort(sorted.begin(), sorted.end(), greater<>());\n    \n    vector<int> assignment(N);\n    vector<double> sums(D, 0);\n    \n    // Initialize each group with one item for balance\n    for (int i = 0; i < D && i < N; i++) {\n        assignment[sorted[i].second] = i;\n        sums[i] += sorted[i].first;\n    }\n    \n    // Assign remaining items to minimize variance at each step\n    for (int idx = D; idx < N; idx++) {\n        auto [w, item] = sorted[idx];\n        \n        int best_g = 0;\n        double best_var = 1e18;\n        \n        for (int g = 0; g < D; g++) {\n            sums[g] += w;\n            \n            double mean = accumulate(sums.begin(), sums.end(), 0.0) / D;\n            double var = 0;\n            for (double s : sums) var += (s - mean) * (s - mean);\n            \n            if (var < best_var) {\n                best_var = var;\n                best_g = g;\n            }\n            \n            sums[g] -= w;\n        }\n        \n        assignment[item] = best_g;\n        sums[best_g] += w;\n    }\n    \n    // Optimize\n    optimize_partition(assignment);\n    \n    // Phase 3: Use remaining queries for final refinement\n    while (queries_used < Q) {\n        // Quick check of current balance\n        sums.assign(D, 0);\n        for (int i = 0; i < N; i++) {\n            sums[assignment[i]] += weight[i];\n        }\n        \n        // Find most imbalanced groups\n        double mean = accumulate(sums.begin(), sums.end(), 0.0) / D;\n        vector<pair<double, int>> deviations;\n        for (int g = 0; g < D; g++) {\n            deviations.push_back({abs(sums[g] - mean), g});\n        }\n        sort(deviations.begin(), deviations.end(), greater<>());\n        \n        if (deviations.size() >= 2) {\n            int g1 = deviations[0].second;\n            int g2 = deviations[1].second;\n            \n            // Get samples from these groups\n            vector<int> items1, items2;\n            for (int i = 0; i < N; i++) {\n                if (assignment[i] == g1) items1.push_back(i);\n                if (assignment[i] == g2) items2.push_back(i);\n            }\n            \n            if (!items1.empty() && !items2.empty()) {\n                int sz = min(2, min((int)items1.size(), (int)items2.size()));\n                vector<int> sample1(items1.begin(), items1.begin() + sz);\n                vector<int> sample2(items2.begin(), items2.begin() + sz);\n                \n                char result = query(sample1, sample2);\n                queries_used++;\n                update_weights(sample1, sample2, result);\n                \n                // Quick re-optimization after new information\n                if (queries_used % 10 == 0) {\n                    optimize_partition(assignment);\n                }\n            } else {\n                queries_used++;\n                query({0}, {1}); // Dummy query\n            }\n        } else {\n            queries_used++;\n            query({0}, {1}); // Dummy query\n        }\n    }\n    \n    // Final optimization\n    optimize_partition(assignment);\n    \n    // Output\n    for (int i = 0; i < N; i++) {\n        cout << assignment[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << endl;\n    \n    return 0;\n}","ahc026":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int n, m;\n    cin >> n >> m;\n    \n    vector<vector<int>> stacks(m);\n    \n    for (int i = 0; i < m; i++) {\n        int stack_size = n / m;\n        for (int j = 0; j < stack_size; j++) {\n            int box;\n            cin >> box;\n            stacks[i].push_back(box);\n        }\n    }\n    \n    vector<pair<int, int>> operations;\n    \n    // Helper to calculate the minimum number in a stack\n    auto get_min_in_stack = [&](int stack_idx) -> int {\n        if (stacks[stack_idx].empty()) return INT_MAX;\n        return *min_element(stacks[stack_idx].begin(), stacks[stack_idx].end());\n    };\n    \n    // Helper to count boxes in a range that are buried (not on top)\n    auto count_buried_in_range = [&](int low, int high) -> int {\n        int count = 0;\n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size() - 1; j++) {\n                if (stacks[i][j] >= low && stacks[i][j] <= high) {\n                    count++;\n                }\n            }\n        }\n        return count;\n    };\n    \n    for (int target = 1; target <= n; target++) {\n        // Find current position of target box\n        int target_stack = -1;\n        int target_pos = -1;\n        \n        for (int i = 0; i < m; i++) {\n            for (int j = 0; j < (int)stacks[i].size(); j++) {\n                if (stacks[i][j] == target) {\n                    target_stack = i;\n                    target_pos = j;\n                    break;\n                }\n            }\n            if (target_stack != -1) break;\n        }\n        \n        // If target is not at the top, move boxes above it\n        if (target_pos < (int)stacks[target_stack].size() - 1) {\n            // Collect boxes to be moved\n            vector<int> boxes_to_move;\n            for (int j = target_pos + 1; j < (int)stacks[target_stack].size(); j++) {\n                boxes_to_move.push_back(stacks[target_stack][j]);\n            }\n            \n            int min_box = *min_element(boxes_to_move.begin(), boxes_to_move.end());\n            int max_box = *max_element(boxes_to_move.begin(), boxes_to_move.end());\n            int num_boxes = boxes_to_move.size();\n            \n            // Count various metrics\n            int empty_count = 0;\n            for (int i = 0; i < m; i++) {\n                if (i != target_stack && stacks[i].empty()) empty_count++;\n            }\n            \n            int buried_soon = count_buried_in_range(target + 1, target + 20);\n            \n            // Find best destination\n            int best_dest = -1;\n            double best_score = -1e9;\n            \n            for (int i = 0; i < m; i++) {\n                if (i == target_stack) continue;\n                \n                double score = 0;\n                \n                if (stacks[i].empty()) {\n                    // Empty stack scoring\n                    score = 200000;\n                    \n                    // Critical urgency bonus\n                    if (min_box <= target + 3) {\n                        score += 150000;\n                    } else if (min_box <= target + 10) {\n                        score += 80000;\n                    } else if (min_box <= target + 25) {\n                        score += 40000;\n                    }\n                    \n                    // Empty stack management\n                    if (empty_count >= 3) {\n                        // Many empties available\n                        if (min_box > target + 40) {\n                            score -= 50000; // Save for urgent needs\n                        }\n                    } else if (empty_count == 2) {\n                        // Limited empties\n                        if (min_box > target + 25 && buried_soon > 5) {\n                            score -= 30000; // Save for upcoming urgent needs\n                        }\n                    } else if (empty_count == 1) {\n                        // Last empty - use only for critical needs\n                        if (min_box > target + 15) {\n                            score -= 80000;\n                        }\n                    }\n                    \n                    // Prefer empty for large groups of urgent boxes\n                    if (num_boxes >= 4 && min_box <= target + 30) {\n                        score += 20000;\n                    }\n                } else {\n                    int stack_size = stacks[i].size();\n                    int top_box = stacks[i].back();\n                    int min_in_dest = get_min_in_stack(i);\n                    \n                    // Base penalty - exponential growth for tall stacks\n                    score = -stack_size * stack_size * 60;\n                    \n                    // Ordering score\n                    if (top_box > max_box) {\n                        // All boxes we're moving are smaller - excellent\n                        score += (top_box - max_box) * 200;\n                        if (top_box - max_box > 60) {\n                            score += 40000;\n                        } else if (top_box - max_box > 35) {\n                            score += 25000;\n                        }\n                    } else if (top_box > min_box) {\n                        // At least some proper ordering\n                        score += (top_box - min_box) * 100;\n                        if (top_box - min_box > 40) {\n                            score += 15000;\n                        }\n                    } else {\n                        // Bad ordering\n                        score -= (min_box - top_box) * 500;\n                    }\n                    \n                    // Lane assignment concept - stacks should handle similar ranges\n                    int dest_range = min_in_dest / 30;\n                    int move_range = min_box / 30;\n                    if (dest_range == move_range) {\n                        score += 10000; // Same lane bonus\n                    } else if (abs(dest_range - move_range) == 1) {\n                        score += 3000; // Adjacent lane\n                    } else if (abs(dest_range - move_range) >= 3) {\n                        score -= 5000; // Far lanes penalty\n                    }\n                    \n                    // Future conflict analysis - weighted by urgency\n                    for (int next = target + 1; next <= min(n, target + 35); next++) {\n                        for (int j = 0; j < stack_size; j++) {\n                            if (stacks[i][j] == next) {\n                                int depth = stack_size - j;\n                                int urgency = 36 - (next - target);\n                                score -= depth * urgency * urgency * 5;\n                                break;\n                            }\n                        }\n                    }\n                    \n                    // Check if we're creating a problematic pattern\n                    if (min_box <= target + 20 && stack_size >= 15) {\n                        // Putting urgent boxes on tall stack\n                        score -= 15000;\n                    }\n                    \n                    // Game phase adjustments\n                    double progress = (double)target / n;\n                    \n                    if (progress < 0.5) {\n                        // First half: maximize future accessibility\n                        if (min_box <= target + 50) {\n                            int future_conflicts = 0;\n                            for (int box : stacks[i]) {\n                                if (box > target && box <= target + 50) {\n                                    future_conflicts++;\n                                }\n                            }\n                            score -= future_conflicts * 2500;\n                        }\n                        \n                        // Prefer maintaining some empty stacks\n                        if (empty_count <= 1 && stack_size >= 20) {\n                            score -= 10000;\n                        }\n                    } else {\n                        // Second half: focus on efficiency\n                        if (stack_size <= 12) {\n                            score += 8000;\n                        }\n                        \n                        // Less penalty for tall stacks in late game\n                        if (progress > 0.75 && stack_size < 30) {\n                            score += 3000;\n                        }\n                    }\n                    \n                    // Stack balance scoring\n                    if (stack_size >= 32) {\n                        score -= (stack_size - 32) * 8000;\n                    } else if (stack_size >= 25) {\n                        score -= (stack_size - 25) * 3000;\n                    }\n                    \n                    // Bonus for consolidating very similar boxes\n                    int very_similar = 0;\n                    for (int box : stacks[i]) {\n                        if (abs(box - min_box) <= 15) {\n                            very_similar++;\n                        }\n                    }\n                    score += very_similar * 1800;\n                }\n                \n                if (score > best_score) {\n                    best_score = score;\n                    best_dest = i;\n                }\n            }\n            \n            // Execute the move\n            operations.push_back({boxes_to_move[0], best_dest + 1});\n            \n            // Update stacks\n            stacks[target_stack].resize(target_pos + 1);\n            for (int box : boxes_to_move) {\n                stacks[best_dest].push_back(box);\n            }\n        }\n        \n        // Carry out the target\n        operations.push_back({target, 0});\n        stacks[target_stack].pop_back();\n    }\n    \n    // Output operations\n    for (auto [v, i] : operations) {\n        cout << v << \" \" << i << \"\\n\";\n    }\n    \n    return 0;\n}","ahc027":"#include <bits/stdc++.h>\nusing namespace std;\n\nint N;\nvector<string> h, v;\nvector<vector<int>> d;\nconst int MAX_LENGTH = 100000;\nconst int DIJ[4][2] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};\nconst char DIR[4] = {'R', 'D', 'L', 'U'};\n\nbool canMove(int i, int j, int dir) {\n    int di = DIJ[dir][0], dj = DIJ[dir][1];\n    int i2 = i + di, j2 = j + dj;\n    \n    if (i2 < 0 || i2 >= N || j2 < 0 || j2 >= N) return false;\n    \n    if (di == 0) {\n        return v[i][min(j, j2)] == '0';\n    } else {\n        return h[min(i, i2)][j] == '0';\n    }\n}\n\n// BFS for shortest path\nvector<int> findPath(int si, int sj, int ei, int ej) {\n    if (si == ei && sj == ej) return {};\n    \n    queue<pair<int, int>> q;\n    map<pair<int, int>, pair<int, int>> parent;\n    map<pair<int, int>, int> dirUsed;\n    \n    q.push({si, sj});\n    parent[{si, sj}] = {-1, -1};\n    \n    while (!q.empty()) {\n        auto [ci, cj] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            \n            if (parent.count({ni, nj})) continue;\n            \n            parent[{ni, nj}] = {ci, cj};\n            dirUsed[{ni, nj}] = dir;\n            \n            if (ni == ei && nj == ej) {\n                vector<int> path;\n                int i = ei, j = ej;\n                while (parent[{i, j}].first != -1) {\n                    path.push_back(dirUsed[{i, j}]);\n                    tie(i, j) = parent[{i, j}];\n                }\n                reverse(path.begin(), path.end());\n                return path;\n            }\n            \n            q.push({ni, nj});\n        }\n    }\n    return {};\n}\n\nint main() {\n    cin >> N;\n    h.resize(N - 1);\n    v.resize(N);\n    d.resize(N, vector<int>(N));\n    \n    for (int i = 0; i < N - 1; i++) {\n        cin >> h[i];\n    }\n    for (int i = 0; i < N; i++) {\n        cin >> v[i];\n    }\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    // Pre-compute distances from origin to all squares\n    vector<vector<int>> distFromOrigin(N, vector<int>(N, INT_MAX));\n    queue<pair<int, int>> q;\n    q.push({0, 0});\n    distFromOrigin[0][0] = 0;\n    \n    while (!q.empty()) {\n        auto [ci, cj] = q.front();\n        q.pop();\n        \n        for (int dir = 0; dir < 4; dir++) {\n            if (!canMove(ci, cj, dir)) continue;\n            int ni = ci + DIJ[dir][0];\n            int nj = cj + DIJ[dir][1];\n            \n            if (distFromOrigin[ni][nj] == INT_MAX) {\n                distFromOrigin[ni][nj] = distFromOrigin[ci][cj] + 1;\n                q.push({ni, nj});\n            }\n        }\n    }\n    \n    vector<int> route;\n    vector<vector<long long>> currentDirt(N, vector<long long>(N, 0));\n    vector<vector<bool>> visited(N, vector<bool>(N, false));\n    vector<vector<int>> visitCount(N, vector<int>(N, 0));\n    \n    int curI = 0, curJ = 0;\n    visited[0][0] = true;\n    visitCount[0][0] = 1;\n    \n    // Manhattan distance helper\n    auto manhattan = [](int i1, int j1, int i2, int j2) {\n        return abs(i1 - i2) + abs(j1 - j2);\n    };\n    \n    // Main loop\n    int iterations = 0;\n    const int MAX_ITERATIONS = 10000;\n    \n    while (route.size() < MAX_LENGTH - 20 && iterations < MAX_ITERATIONS) {\n        iterations++;\n        \n        // Check if we have enough moves to return\n        int returnDist = distFromOrigin[curI][curJ];\n        if (route.size() + returnDist >= MAX_LENGTH - 5) {\n            break;\n        }\n        \n        // Update dirt accumulation\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i != curI || j != curJ) {\n                    currentDirt[i][j] += d[i][j];\n                }\n            }\n        }\n        currentDirt[curI][curJ] = 0;\n        \n        // Find best target\n        double bestScore = -1;\n        int targetI = -1, targetJ = -1;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (i == curI && j == curJ) continue;\n                \n                double score;\n                if (!visited[i][j]) {\n                    // Unvisited squares get huge priority\n                    score = 1e10 + currentDirt[i][j] * 100;\n                } else {\n                    // Use Manhattan as quick distance estimate\n                    int approxDist = manhattan(curI, curJ, i, j);\n                    if (approxDist == 0) approxDist = 1;\n                    \n                    // Score considers:\n                    // - Current accumulated dirt (heavily weighted)\n                    // - Dirt generation rate\n                    // - Distance cost\n                    // - Visit frequency penalty\n                    \n                    double accumulatedWeight = currentDirt[i][j];\n                    double rateWeight = d[i][j] * sqrt((double)approxDist);\n                    double visitPenalty = visitCount[i][j] > 0 ? (1.0 + visitCount[i][j] * 0.1) : 1.0;\n                    \n                    score = (accumulatedWeight * 2.0 + rateWeight) / (approxDist * visitPenalty);\n                    \n                    // Bonus for squares that haven't been visited in a while\n                    if (currentDirt[i][j] > d[i][j] * N * 2) {\n                        score *= 2.0;\n                    }\n                }\n                \n                if (score > bestScore) {\n                    bestScore = score;\n                    targetI = i;\n                    targetJ = j;\n                }\n            }\n        }\n        \n        if (targetI == -1) break;\n        \n        // Early termination check\n        if (curI == 0 && curJ == 0 && visited[targetI][targetJ]) {\n            // At origin, check if it's worth continuing\n            if (route.size() > N * N * 3 && currentDirt[targetI][targetJ] < d[targetI][targetJ] * 10) {\n                break;\n            }\n        }\n        \n        // Find path to target\n        auto path = findPath(curI, curJ, targetI, targetJ);\n        if (path.empty()) continue;\n        \n        // Check if we can afford this path\n        int newReturnDist = distFromOrigin[targetI][targetJ];\n        if (route.size() + path.size() + newReturnDist >= MAX_LENGTH - 5) {\n            // Can't afford this move, try to find closer target\n            continue;\n        }\n        \n        // Execute path\n        for (int dir : path) {\n            route.push_back(dir);\n            curI += DIJ[dir][0];\n            curJ += DIJ[dir][1];\n            \n            // Update state during movement\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (i != curI || j != curJ) {\n                        currentDirt[i][j] += d[i][j];\n                    }\n                }\n            }\n            currentDirt[curI][curJ] = 0;\n            visited[curI][curJ] = true;\n            visitCount[curI][curJ]++;\n        }\n    }\n    \n    // Return to origin\n    if (curI != 0 || curJ != 0) {\n        auto pathHome = findPath(curI, curJ, 0, 0);\n        for (int dir : pathHome) {\n            if (route.size() >= MAX_LENGTH) break;\n            route.push_back(dir);\n        }\n    }\n    \n    // Convert to string\n    string result;\n    for (int dir : route) {\n        result += DIR[dir];\n    }\n    \n    cout << result << endl;\n    \n    return 0;\n}","ahc028":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Position {\n    int i, j;\n};\n\nint manhattan(Position a, Position b) {\n    return abs(a.i - b.i) + abs(a.j - b.j) + 1;\n}\n\nclass AdvancedSuperstring {\nprivate:\n    vector<string> words;\n    vector<vector<int>> overlap;\n    int n;\n    \n    int computeOverlap(const string& a, const string& b) {\n        int maxLen = min(a.length(), b.length());\n        for (int len = maxLen; len >= 1; len--) {\n            if (memcmp(a.c_str() + a.length() - len, b.c_str(), len) == 0) {\n                return len;\n            }\n        }\n        return 0;\n    }\n    \n    string buildFromOrder(const vector<int>& order) {\n        if (order.empty()) return \"\";\n        string result = words[order[0]];\n        for (int i = 1; i < order.size(); i++) {\n            result += words[order[i]].substr(overlap[order[i-1]][order[i]]);\n        }\n        return result;\n    }\n    \n    int calculateLength(const vector<int>& order) {\n        if (order.empty()) return 0;\n        int len = words[order[0]].length();\n        for (int i = 1; i < order.size(); i++) {\n            len += words[order[i]].length() - overlap[order[i-1]][order[i]];\n        }\n        return len;\n    }\n    \n    // Advanced local search with multiple neighborhoods\n    void advancedLocalSearch(vector<int>& order) {\n        int n = order.size();\n        if (n <= 2) return;\n        \n        int currentLen = calculateLength(order);\n        bool globalImproved = true;\n        \n        for (int round = 0; round < 3 && globalImproved; round++) {\n            globalImproved = false;\n            \n            // 2-opt\n            for (int i = 0; i < n - 2; i++) {\n                for (int j = i + 2; j < min(n, i + 20); j++) {\n                    reverse(order.begin() + i + 1, order.begin() + j + 1);\n                    int newLen = calculateLength(order);\n                    if (newLen < currentLen) {\n                        currentLen = newLen;\n                        globalImproved = true;\n                    } else {\n                        reverse(order.begin() + i + 1, order.begin() + j + 1);\n                    }\n                }\n            }\n            \n            // Insertion: move element to different position\n            for (int i = 0; i < n && !globalImproved; i++) {\n                int elem = order[i];\n                order.erase(order.begin() + i);\n                \n                int bestPos = i;\n                int bestLen = currentLen;\n                \n                for (int j = 0; j <= n - 1; j++) {\n                    order.insert(order.begin() + j, elem);\n                    int newLen = calculateLength(order);\n                    if (newLen < bestLen) {\n                        bestLen = newLen;\n                        bestPos = j;\n                    }\n                    order.erase(order.begin() + j);\n                }\n                \n                order.insert(order.begin() + bestPos, elem);\n                if (bestLen < currentLen) {\n                    currentLen = bestLen;\n                    globalImproved = true;\n                }\n            }\n        }\n    }\n    \n    // TSP-based construction using nearest neighbor\n    vector<int> tspConstruction(const vector<int>& indices) {\n        int m = indices.size();\n        if (m <= 1) return indices;\n        \n        // Find best starting point\n        int bestStart = -1;\n        int bestTotalLen = INT_MAX;\n        \n        for (int start = 0; start < min(m, 10); start++) {\n            vector<bool> used(m, false);\n            vector<int> tour;\n            \n            tour.push_back(indices[start]);\n            used[start] = true;\n            int totalLen = words[indices[start]].length();\n            \n            // Nearest neighbor\n            while (tour.size() < m) {\n                int last = tour.back();\n                int bestNext = -1;\n                int minCost = INT_MAX;\n                \n                for (int i = 0; i < m; i++) {\n                    if (!used[i]) {\n                        int cost = words[indices[i]].length() - overlap[last][indices[i]];\n                        if (cost < minCost) {\n                            minCost = cost;\n                            bestNext = i;\n                        }\n                    }\n                }\n                \n                tour.push_back(indices[bestNext]);\n                used[bestNext] = true;\n                totalLen += minCost;\n            }\n            \n            if (totalLen < bestTotalLen) {\n                bestTotalLen = totalLen;\n                bestStart = start;\n            }\n        }\n        \n        // Build best tour\n        vector<bool> used(m, false);\n        vector<int> result;\n        \n        result.push_back(indices[bestStart]);\n        used[bestStart] = true;\n        \n        while (result.size() < m) {\n            int last = result.back();\n            int bestNext = -1;\n            int minCost = INT_MAX;\n            \n            for (int i = 0; i < m; i++) {\n                if (!used[i]) {\n                    int cost = words[indices[i]].length() - overlap[last][indices[i]];\n                    if (cost < minCost) {\n                        minCost = cost;\n                        bestNext = i;\n                    }\n                }\n            }\n            \n            result.push_back(indices[bestNext]);\n            used[bestNext] = true;\n        }\n        \n        return result;\n    }\n    \n    // Dynamic programming for small subsets\n    vector<int> dpSolve(const vector<int>& indices) {\n        int m = indices.size();\n        if (m > 10) return {};  // Too large for DP\n        \n        int fullMask = (1 << m) - 1;\n        vector<vector<int>> dp(1 << m, vector<int>(m, INT_MAX));\n        vector<vector<int>> parent(1 << m, vector<int>(m, -1));\n        \n        // Initialize\n        for (int i = 0; i < m; i++) {\n            dp[1 << i][i] = words[indices[i]].length();\n        }\n        \n        // Fill DP\n        for (int mask = 1; mask <= fullMask; mask++) {\n            for (int last = 0; last < m; last++) {\n                if (!(mask & (1 << last)) || dp[mask][last] == INT_MAX) continue;\n                \n                for (int next = 0; next < m; next++) {\n                    if (mask & (1 << next)) continue;\n                    \n                    int newMask = mask | (1 << next);\n                    int newLen = dp[mask][last] + words[indices[next]].length() - overlap[indices[last]][indices[next]];\n                    \n                    if (newLen < dp[newMask][next]) {\n                        dp[newMask][next] = newLen;\n                        parent[newMask][next] = last;\n                    }\n                }\n            }\n        }\n        \n        // Find best ending\n        int bestEnd = 0;\n        for (int i = 1; i < m; i++) {\n            if (dp[fullMask][i] < dp[fullMask][bestEnd]) {\n                bestEnd = i;\n            }\n        }\n        \n        // Reconstruct path\n        vector<int> result;\n        int mask = fullMask;\n        int curr = bestEnd;\n        \n        while (curr != -1) {\n            result.push_back(indices[curr]);\n            int prevMask = mask ^ (1 << curr);\n            curr = parent[mask][curr];\n            mask = prevMask;\n        }\n        \n        reverse(result.begin(), result.end());\n        return result;\n    }\n    \npublic:\n    AdvancedSuperstring(const vector<string>& w) : words(w), n(w.size()) {\n        overlap.resize(n, vector<int>(n, 0));\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < n; j++) {\n                if (i != j) {\n                    overlap[i][j] = computeOverlap(words[i], words[j]);\n                }\n            }\n        }\n    }\n    \n    string build() {\n        // Remove substrings\n        vector<int> essential;\n        for (int i = 0; i < n; i++) {\n            bool isSub = false;\n            for (int j = 0; j < n; j++) {\n                if (i != j && words[j].find(words[i]) != string::npos) {\n                    isSub = true;\n                    break;\n                }\n            }\n            if (!isSub) essential.push_back(i);\n        }\n        \n        int m = essential.size();\n        if (m == 0) return \"\";\n        \n        string bestResult;\n        int bestLen = INT_MAX;\n        \n        // Use DP for small instances\n        if (m <= 10) {\n            vector<int> order = dpSolve(essential);\n            if (!order.empty()) {\n                bestResult = buildFromOrder(order);\n                bestLen = bestResult.length();\n            }\n        }\n        \n        // TSP construction\n        vector<int> tspOrder = tspConstruction(essential);\n        advancedLocalSearch(tspOrder);\n        string tspResult = buildFromOrder(tspOrder);\n        if (tspResult.length() < bestLen) {\n            bestResult = tspResult;\n            bestLen = tspResult.length();\n        }\n        \n        // Multiple greedy attempts with different strategies\n        for (int trial = 0; trial < min(m, 15); trial++) {\n            vector<int> order;\n            vector<bool> used(m, false);\n            \n            // Choose starting word\n            int start;\n            if (trial == 0) {\n                // Maximum total overlap\n                start = 0;\n                int maxTotal = 0;\n                for (int i = 0; i < min(m, 10); i++) {\n                    int total = 0;\n                    for (int j = 0; j < m; j++) {\n                        if (i != j) {\n                            total += overlap[essential[i]][essential[j]];\n                        }\n                    }\n                    if (total > maxTotal) {\n                        maxTotal = total;\n                        start = i;\n                    }\n                }\n            } else {\n                start = trial % m;\n            }\n            \n            order.push_back(essential[start]);\n            used[start] = true;\n            \n            // Build chain\n            while (order.size() < m) {\n                int last = order.back();\n                int bestNext = -1;\n                double bestScore = -1e9;\n                \n                for (int i = 0; i < m; i++) {\n                    if (!used[i]) {\n                        int ov = overlap[last][essential[i]];\n                        int len = words[essential[i]].length();\n                        \n                        // Score combining overlap and length efficiency\n                        double score = (double)ov - (double)(len - ov) * 0.5;\n                        \n                        // Future potential\n                        if (order.size() < m - 1) {\n                            int maxFuture = 0;\n                            for (int j = 0; j < m; j++) {\n                                if (!used[j] && j != i) {\n                                    maxFuture = max(maxFuture, overlap[essential[i]][essential[j]]);\n                                }\n                            }\n                            score += maxFuture * 0.2;\n                        }\n                        \n                        if (score > bestScore) {\n                            bestScore = score;\n                            bestNext = i;\n                        }\n                    }\n                }\n                \n                if (bestNext == -1) {\n                    for (int i = 0; i < m; i++) {\n                        if (!used[i]) {\n                            bestNext = i;\n                            break;\n                        }\n                    }\n                }\n                \n                order.push_back(essential[bestNext]);\n                used[bestNext] = true;\n            }\n            \n            // Local search\n            advancedLocalSearch(order);\n            \n            string result = buildFromOrder(order);\n            if (result.length() < bestLen) {\n                bestLen = result.length();\n                bestResult = result;\n            }\n        }\n        \n        // Add missing words\n        for (const string& w : words) {\n            if (bestResult.find(w) == string::npos) {\n                int ov = computeOverlap(bestResult, w);\n                bestResult += w.substr(ov);\n            }\n        }\n        \n        return bestResult;\n    }\n};\n\n// Path finding remains the same\nvector<pair<int, int>> findPath(const string& s, Position start,\n                                const vector<vector<Position>>& charPos) {\n    int n = s.length();\n    vector<pair<int, int>> result;\n    if (n == 0) return result;\n    \n    const int CHUNK = 1000;\n    \n    if (n <= CHUNK) {\n        vector<vector<int>> dp(n);\n        vector<vector<int>> parent(n);\n        \n        for (int i = 0; i < n; i++) {\n            int ch = s[i] - 'A';\n            dp[i].assign(charPos[ch].size(), INT_MAX);\n            parent[i].assign(charPos[ch].size(), -1);\n        }\n        \n        int ch0 = s[0] - 'A';\n        for (int j = 0; j < charPos[ch0].size(); j++) {\n            dp[0][j] = manhattan(start, charPos[ch0][j]);\n        }\n        \n        for (int i = 1; i < n; i++) {\n            int ch = s[i] - 'A';\n            int pch = s[i-1] - 'A';\n            \n            for (int j = 0; j < charPos[ch].size(); j++) {\n                for (int k = 0; k < charPos[pch].size(); k++) {\n                    int cost = dp[i-1][k] + manhattan(charPos[pch][k], charPos[ch][j]);\n                    if (cost < dp[i][j]) {\n                        dp[i][j] = cost;\n                        parent[i][j] = k;\n                    }\n                }\n            }\n        }\n        \n        int best = 0;\n        for (int j = 1; j < dp[n-1].size(); j++) {\n            if (dp[n-1][j] < dp[n-1][best]) {\n                best = j;\n            }\n        }\n        \n        vector<int> choices(n);\n        choices[n-1] = best;\n        for (int i = n-1; i > 0; i--) {\n            choices[i-1] = parent[i][choices[i]];\n        }\n        \n        for (int i = 0; i < n; i++) {\n            Position p = charPos[s[i] - 'A'][choices[i]];\n            result.push_back({p.i, p.j});\n        }\n    } else {\n        Position curr = start;\n        for (int i = 0; i < n; i++) {\n            int ch = s[i] - 'A';\n            Position bestPos = charPos[ch][0];\n            int bestCost = manhattan(curr, bestPos);\n            \n            for (const Position& pos : charPos[ch]) {\n                int cost = manhattan(curr, pos);\n                if (cost < bestCost) {\n                    bestCost = cost;\n                    bestPos = pos;\n                }\n            }\n            \n            result.push_back({bestPos.i, bestPos.j});\n            curr = bestPos;\n        }\n    }\n    \n    return result;\n}\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M;\n    cin >> N >> M;\n    \n    int si, sj;\n    cin >> si >> sj;\n    \n    vector<string> grid(N);\n    vector<vector<Position>> charPositions(26);\n    \n    for (int i = 0; i < N; i++) {\n        cin >> grid[i];\n        for (int j = 0; j < N; j++) {\n            charPositions[grid[i][j] - 'A'].push_back({i, j});\n        }\n    }\n    \n    vector<string> words(M);\n    for (int i = 0; i < M; i++) {\n        cin >> words[i];\n    }\n    \n    AdvancedSuperstring builder(words);\n    string superstring = builder.build();\n    \n    if (superstring.length() > 4990) {\n        superstring = \"\";\n        for (const string& w : words) {\n            superstring += w;\n        }\n    }\n    \n    auto moves = findPath(superstring, {si, sj}, charPositions);\n    \n    for (const auto& m : moves) {\n        cout << m.first << \" \" << m.second << \"\\n\";\n    }\n    \n    return 0;\n}","ahc030":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N, M;\n    double eps;\n    cin >> N >> M >> eps;\n    \n    // Read oil shapes\n    for (int m = 0; m < M; m++) {\n        int d;\n        cin >> d;\n        for (int k = 0; k < d; k++) {\n            int i, j;\n            cin >> i >> j;\n        }\n    }\n    \n    vector<vector<int>> drilled(N, vector<int>(N, -1));\n    vector<pair<int,int>> confirmedOil;\n    vector<vector<int>> hits(N, vector<int>(N, 0));\n    \n    // Phase 1: Large area divination to get overview\n    vector<pair<int,int>> allSquares;\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            allSquares.push_back({i, j});\n        }\n    }\n    \n    // Divine full board\n    cout << \"q \" << allSquares.size();\n    for (auto& p : allSquares) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl << flush;\n    \n    int totalOil;\n    cin >> totalOil;\n    \n    // Phase 2: Divide into regions and divine\n    int blockSize = 4;\n    for (int bi = 0; bi < N; bi += blockSize) {\n        for (int bj = 0; bj < N; bj += blockSize) {\n            vector<pair<int,int>> block;\n            for (int i = bi; i < min(N, bi + blockSize); i++) {\n                for (int j = bj; j < min(N, bj + blockSize); j++) {\n                    block.push_back({i, j});\n                }\n            }\n            \n            if (block.size() >= 2) {\n                cout << \"q \" << block.size();\n                for (auto& p : block) {\n                    cout << \" \" << p.first << \" \" << p.second;\n                }\n                cout << endl << flush;\n                \n                int result;\n                cin >> result;\n                \n                if (result > 0) {\n                    // Mark these squares as potentially having oil\n                    for (auto& p : block) {\n                        hits[p.first][p.second]++;\n                    }\n                    \n                    // If small block with strong signal, drill it\n                    if (block.size() <= 4 && result >= 1) {\n                        for (auto& p : block) {\n                            if (drilled[p.first][p.second] == -1) {\n                                cout << \"q 1 \" << p.first << \" \" << p.second << endl << flush;\n                                int v;\n                                cin >> v;\n                                drilled[p.first][p.second] = v;\n                                if (v > 0) {\n                                    confirmedOil.push_back(p);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 3: Overlapping regions for better coverage\n    blockSize = 5;\n    for (int offset = 0; offset < 2; offset++) {\n        for (int bi = offset * 2; bi + blockSize <= N; bi += blockSize - 1) {\n            for (int bj = offset * 2; bj + blockSize <= N; bj += blockSize - 1) {\n                vector<pair<int,int>> block;\n                for (int i = bi; i < bi + blockSize; i++) {\n                    for (int j = bj; j < bj + blockSize; j++) {\n                        if (drilled[i][j] == -1) {\n                            block.push_back({i, j});\n                        }\n                    }\n                }\n                \n                if (block.size() >= 3) {\n                    cout << \"q \" << block.size();\n                    for (auto& p : block) {\n                        cout << \" \" << p.first << \" \" << p.second;\n                    }\n                    cout << endl << flush;\n                    \n                    int result;\n                    cin >> result;\n                    \n                    if (result > 0) {\n                        for (auto& p : block) {\n                            hits[p.first][p.second]++;\n                        }\n                    }\n                }\n            }\n        }\n    }\n    \n    // Phase 4: Drill squares with multiple hits\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            if (drilled[i][j] == -1 && hits[i][j] >= 2) {\n                cout << \"q 1 \" << i << \" \" << j << endl << flush;\n                int v;\n                cin >> v;\n                drilled[i][j] = v;\n                if (v > 0) {\n                    confirmedOil.push_back({i, j});\n                }\n            }\n        }\n    }\n    \n    // Phase 5: Check neighbors of confirmed oil\n    for (auto& oil : confirmedOil) {\n        int oi = oil.first;\n        int oj = oil.second;\n        \n        // Check 4-connected neighbors\n        vector<pair<int,int>> neighbors = {\n            {oi-1, oj}, {oi+1, oj}, {oi, oj-1}, {oi, oj+1}\n        };\n        \n        for (auto& n : neighbors) {\n            if (n.first >= 0 && n.first < N && n.second >= 0 && n.second < N) {\n                if (drilled[n.first][n.second] == -1) {\n                    cout << \"q 1 \" << n.first << \" \" << n.second << endl << flush;\n                    int v;\n                    cin >> v;\n                    drilled[n.first][n.second] = v;\n                    if (v > 0) {\n                        confirmedOil.push_back(n);\n                    }\n                }\n            }\n        }\n    }\n    \n    // Submit answer\n    cout << \"a \" << confirmedOil.size();\n    for (auto& p : confirmedOil) {\n        cout << \" \" << p.first << \" \" << p.second;\n    }\n    cout << endl << flush;\n    \n    int result;\n    cin >> result;\n    \n    if (result == 0) {\n        // Wrong answer - drill remaining high-hit squares\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (drilled[i][j] == -1 && hits[i][j] > 0) {\n                    cout << \"q 1 \" << i << \" \" << j << endl << flush;\n                    int v;\n                    cin >> v;\n                    drilled[i][j] = v;\n                    if (v > 0) {\n                        confirmedOil.push_back({i, j});\n                    }\n                }\n            }\n        }\n        \n        // Resubmit\n        cout << \"a \" << confirmedOil.size();\n        for (auto& p : confirmedOil) {\n            cout << \" \" << p.first << \" \" << p.second;\n        }\n        cout << endl << flush;\n        \n        cin >> result;\n    }\n    \n    return 0;\n}","ahc031":"#include <iostream>\n#include <vector>\n#include <algorithm>\n#include <cmath>\nusing namespace std;\n\nint main() {\n    int W, D, N;\n    cin >> W >> D >> N;\n    \n    vector<vector<int>> a(D, vector<int>(N));\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cin >> a[d][k];\n        }\n    }\n    \n    // Analyze input characteristics\n    bool has_extreme_variance = false;\n    for (int k = 0; k < N; k++) {\n        int min_val = a[0][k], max_val = a[0][k];\n        for (int d = 1; d < D; d++) {\n            min_val = min(min_val, a[d][k]);\n            max_val = max(max_val, a[d][k]);\n        }\n        if (max_val > min_val * 3) {\n            has_extreme_variance = true;\n            break;\n        }\n    }\n    \n    // Calculate percentile areas\n    vector<int> p75_areas(N);\n    vector<int> p85_areas(N);  // Use p85 for extreme cases\n    vector<int> p90_areas(N);\n    \n    for (int k = 0; k < N; k++) {\n        vector<int> areas_k;\n        for (int d = 0; d < D; d++) {\n            areas_k.push_back(a[d][k]);\n        }\n        sort(areas_k.begin(), areas_k.end());\n        \n        int idx75 = min((3 * D) / 4, D - 1);\n        int idx85 = min((17 * D) / 20, D - 1);\n        int idx90 = min((9 * D) / 10, D - 1);\n        p75_areas[k] = areas_k[idx75];\n        p85_areas[k] = areas_k[idx85];\n        p90_areas[k] = areas_k[idx90];\n    }\n    \n    // Height allocation - use p85 for extreme variance cases\n    vector<int> heights(N);\n    vector<int> y_start(N);\n    \n    double total_target = 0;\n    for (int k = 0; k < N; k++) {\n        int target = has_extreme_variance ? p85_areas[k] : p90_areas[k];\n        total_target += sqrt((double)target);\n    }\n    \n    int used_height = 0;\n    for (int k = 0; k < N; k++) {\n        if (k == N - 1) {\n            heights[k] = W - used_height;\n        } else {\n            int target = has_extreme_variance ? p85_areas[k] : p90_areas[k];\n            double proportion = sqrt((double)target) / total_target;\n            int h = max(1, (int)(W * proportion + 0.5));\n            \n            // Ensure minimum viable height\n            int min_h = (p90_areas[k] + W - 1) / W;\n            h = max(h, min_h);\n            \n            // Leave space for remaining strips\n            h = min(h, W - used_height - (N - k - 1));\n            heights[k] = h;\n        }\n        \n        y_start[k] = used_height;\n        used_height += heights[k];\n    }\n    \n    // Base widths - use p75 normally, p85 for extreme cases\n    vector<int> stable_widths(N);\n    for (int k = 0; k < N; k++) {\n        int base_area = has_extreme_variance ? p85_areas[k] : p75_areas[k];\n        stable_widths[k] = (base_area + heights[k] - 1) / heights[k];\n        stable_widths[k] = min(stable_widths[k], W);\n    }\n    \n    // Initialize widths\n    vector<vector<int>> widths(D, vector<int>(N));\n    \n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            widths[d][k] = stable_widths[k];\n            \n            int min_width = (a[d][k] + heights[k] - 1) / heights[k];\n            widths[d][k] = max(widths[d][k], min_width);\n            widths[d][k] = min(widths[d][k], W);\n        }\n    }\n    \n    // Smoothing optimization\n    for (int k = 0; k < N; k++) {\n        // Pass 1: Group identical areas\n        for (int d = 0; d < D - 1; d++) {\n            if (a[d][k] == a[d+1][k]) {\n                int common_w = max(widths[d][k], widths[d+1][k]);\n                widths[d][k] = widths[d+1][k] = common_w;\n            }\n        }\n        \n        // Pass 2: Find dominant width\n        vector<pair<int, int>> width_counts;\n        for (int d = 0; d < D; d++) {\n            bool found = false;\n            for (auto& p : width_counts) {\n                if (p.first == widths[d][k]) {\n                    p.second++;\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                width_counts.push_back({widths[d][k], 1});\n            }\n        }\n        \n        // Find most common width\n        int dominant_width = stable_widths[k];\n        int max_count = 0;\n        for (auto& p : width_counts) {\n            if (p.second > max_count) {\n                max_count = p.second;\n                dominant_width = p.first;\n            }\n        }\n        \n        // Try to use dominant width where possible\n        if (max_count >= D / 3) {\n            for (int d = 0; d < D; d++) {\n                if (heights[k] * dominant_width >= a[d][k]) {\n                    widths[d][k] = dominant_width;\n                }\n            }\n        }\n        \n        // Pass 3: Smooth transitions\n        for (int pass = 0; pass < 2; pass++) {\n            for (int d = 1; d < D - 1; d++) {\n                int prev_w = widths[d-1][k];\n                int curr_w = widths[d][k];\n                int next_w = widths[d+1][k];\n                \n                if (prev_w == next_w && curr_w != prev_w) {\n                    if (heights[k] * prev_w >= a[d][k]) {\n                        widths[d][k] = prev_w;\n                    }\n                } else if (abs(prev_w - next_w) <= 2 && \n                          abs(curr_w - prev_w) <= 5 && \n                          abs(curr_w - next_w) <= 5) {\n                    int median_w = max(min(prev_w, next_w), min(max(prev_w, next_w), curr_w));\n                    if (heights[k] * median_w >= a[d][k]) {\n                        widths[d][k] = median_w;\n                    }\n                }\n            }\n        }\n        \n        // Pass 4: Merge adjacent similar widths\n        for (int d = 0; d < D - 1; d++) {\n            if (abs(widths[d][k] - widths[d+1][k]) <= 2) {\n                int merged_w = max(widths[d][k], widths[d+1][k]);\n                if (heights[k] * merged_w >= a[d][k] && \n                    heights[k] * merged_w >= a[d+1][k]) {\n                    widths[d][k] = widths[d+1][k] = merged_w;\n                }\n            }\n        }\n    }\n    \n    // Output rectangles\n    for (int d = 0; d < D; d++) {\n        for (int k = 0; k < N; k++) {\n            cout << y_start[k] << \" \" << 0 << \" \" \n                 << (y_start[k] + heights[k]) << \" \" << widths[d][k] << \"\\n\";\n        }\n    }\n    \n    return 0;\n}","ahc032":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst long long MOD = 998244353;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, K;\n    cin >> N >> M >> K;\n    \n    vector<vector<long long>> initial_board(N, vector<long long>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> initial_board[i][j];\n        }\n    }\n    \n    vector<vector<vector<long long>>> stamps(M, vector<vector<long long>>(3, vector<long long>(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    // Try multiple strategies and pick the best\n    vector<tuple<int, int, int>> best_operations;\n    long long best_total_score = 0;\n    \n    // Comprehensive strategy pool with extreme variants\n    vector<tuple<double, double, double, double, double, double>> strategies = {\n        // Core successful strategies\n        {2.5, 0.7, 0.5, 35000, 1.0, 1.0},\n        {3.0, 0.6, 0.4, 40000, 1.0, 1.0},\n        {2.0, 0.8, 0.6, 30000, 1.0, 1.0},\n        {2.8, 0.65, 0.45, 38000, 1.0, 1.0},\n        {3.5, 0.5, 0.3, 45000, 1.2, 0.8},\n        {2.2, 0.85, 0.55, 32000, 0.8, 1.2},\n        {2.7, 0.75, 0.4, 42000, 1.1, 0.9},\n        {2.3, 0.7, 0.5, 35000, 1.3, 1.1},\n        {3.2, 0.55, 0.35, 43000, 1.15, 0.85},\n        {2.6, 0.72, 0.48, 37000, 1.05, 0.95},\n        \n        // Extreme variants\n        {4.0, 0.3, 0.2, 50000, 1.5, 0.5},\n        {1.5, 0.9, 0.7, 25000, 0.7, 1.5},\n        {3.8, 0.4, 0.25, 48000, 1.4, 0.6},\n        {1.8, 0.88, 0.65, 28000, 0.75, 1.4},\n        {2.9, 0.68, 0.43, 39000, 1.12, 0.88},\n        {3.3, 0.58, 0.38, 44000, 1.25, 0.75},\n        \n        // Ultra-fine-tuned variants for edge cases\n        {2.45, 0.73, 0.52, 34000, 0.98, 1.02},\n        {2.55, 0.68, 0.47, 36000, 1.02, 0.98},\n        {3.1, 0.62, 0.42, 41000, 1.08, 0.92},\n        {2.75, 0.7, 0.45, 38500, 1.06, 0.94},\n    };\n    \n    for (auto [no_wrap_mult, wrap_mult, progress_thresh, eff_bonus, high_bonus_mult, wrap_penalty_mult] : strategies) {\n        vector<vector<long long>> board = initial_board;\n        vector<tuple<int, int, int>> operations;\n        \n        for (int op = 0; op < K; op++) {\n            int best_m = -1, best_p = -1, best_q = -1;\n            double best_score = -1e18;\n            \n            double progress = (double)op / K;\n            \n            // Dynamic adjustment\n            double dynamic_mult = 1.0;\n            if (progress > 0.85) {\n                dynamic_mult = 1.3;\n            } else if (progress > 0.7) {\n                dynamic_mult = 1.15;\n            } else if (progress > 0.5) {\n                dynamic_mult = 1.05;\n            }\n            \n            // Calculate board statistics for adaptive behavior\n            int cells_above_95 = 0;\n            int cells_above_90 = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    long long val = board[i][j] % MOD;\n                    if (val > 0.95 * MOD) cells_above_95++;\n                    if (val > 0.90 * MOD) cells_above_90++;\n                }\n            }\n            \n            // Adaptive strategy modification\n            double adaptive_bonus = 1.0;\n            if (cells_above_95 > 50) {\n                adaptive_bonus = 1.5; // Strong focus on precision when many cells are near optimal\n            } else if (cells_above_90 > 60) {\n                adaptive_bonus = 1.2;\n            }\n            \n            // Try all stamps and positions\n            for (int m = 0; m < M; m++) {\n                for (int p = 0; p <= N - 3; p++) {\n                    for (int q = 0; q <= N - 3; q++) {\n                        double score = 0;\n                        int cells_near_perfect = 0;\n                        double total_efficiency = 0;\n                        \n                        // Evaluate stamp placement\n                        for (int i = 0; i < 3; i++) {\n                            for (int j = 0; j < 3; j++) {\n                                long long old_val = board[p + i][q + j];\n                                long long stamp_val = stamps[m][i][j];\n                                long long new_val = old_val + stamp_val;\n                                \n                                long long old_mod = old_val % MOD;\n                                long long new_mod = new_val % MOD;\n                                \n                                // Base score\n                                long long delta = new_mod - old_mod;\n                                score += delta;\n                                \n                                long long room = MOD - 1 - old_mod;\n                                \n                                if (stamp_val <= room) {\n                                    // No wraparound\n                                    score += stamp_val * no_wrap_mult;\n                                    \n                                    // Progressive bonuses with adaptive adjustment\n                                    if (new_mod >= 0.995 * MOD) {\n                                        score += 180000 * high_bonus_mult * dynamic_mult * adaptive_bonus;\n                                        cells_near_perfect++;\n                                    } else if (new_mod >= 0.99 * MOD) {\n                                        score += 160000 * high_bonus_mult * dynamic_mult * adaptive_bonus;\n                                        cells_near_perfect++;\n                                    } else if (new_mod >= 0.985 * MOD) {\n                                        score += 140000 * high_bonus_mult * dynamic_mult;\n                                    } else if (new_mod >= 0.97 * MOD) {\n                                        score += 90000 * high_bonus_mult * dynamic_mult;\n                                    } else if (new_mod >= 0.95 * MOD) {\n                                        score += 60000 * high_bonus_mult;\n                                    } else if (new_mod >= 0.92 * MOD) {\n                                        score += 35000 * high_bonus_mult;\n                                    } else if (new_mod >= 0.88 * MOD) {\n                                        score += 20000 * high_bonus_mult;\n                                    } else if (new_mod >= 0.85 * MOD) {\n                                        score += 12000 * high_bonus_mult;\n                                    } else if (new_mod >= 0.80 * MOD) {\n                                        score += 6000 * high_bonus_mult;\n                                    }\n                                    \n                                    // Enhanced efficiency bonus\n                                    if (room > 0 && stamp_val > 0) {\n                                        double efficiency = (double)stamp_val / room;\n                                        total_efficiency += efficiency;\n                                        \n                                        if (progress > progress_thresh) {\n                                            if (efficiency >= 0.99) {\n                                                score += 100000 * dynamic_mult * adaptive_bonus;\n                                            } else if (efficiency >= 0.95) {\n                                                score += 80000 * dynamic_mult;\n                                            } else if (efficiency > 0.9) {\n                                                score += 60000 * dynamic_mult;\n                                            } else if (efficiency > 0.75) {\n                                                score += efficiency * eff_bonus;\n                                            } else if (efficiency > 0.5) {\n                                                score += efficiency * eff_bonus * 0.4;\n                                            }\n                                        }\n                                    }\n                                    \n                                    // Special handling for tiny gaps in ultra-late game\n                                    if (progress > 0.9 && room > 0 && room < 0.02 * MOD) {\n                                        if (stamp_val >= room * 0.95) {\n                                            score += 70000;\n                                        }\n                                    }\n                                } else {\n                                    // Wraparound\n                                    if (delta > 0) {\n                                        score += delta * wrap_mult;\n                                    }\n                                    \n                                    // Adaptive penalties\n                                    double penalty_mult = wrap_penalty_mult;\n                                    if (cells_above_95 > 50) {\n                                        penalty_mult *= 1.2; // Harsher penalty when many cells are near optimal\n                                    }\n                                    \n                                    if (old_mod >= 0.98 * MOD) {\n                                        score -= old_mod * 0.9 * penalty_mult;\n                                    } else if (old_mod >= 0.96 * MOD) {\n                                        score -= old_mod * 0.7 * penalty_mult;\n                                    } else if (old_mod >= 0.93 * MOD) {\n                                        score -= old_mod * 0.5 * penalty_mult;\n                                    } else if (old_mod >= 0.90 * MOD) {\n                                        score -= old_mod * 0.35 * penalty_mult;\n                                    } else if (old_mod >= 0.86 * MOD) {\n                                        score -= old_mod * 0.2 * penalty_mult;\n                                    } else if (old_mod >= 0.82 * MOD) {\n                                        score -= old_mod * 0.1 * penalty_mult;\n                                    } else if (old_mod >= 0.77 * MOD) {\n                                        score -= old_mod * 0.05 * penalty_mult;\n                                    }\n                                }\n                            }\n                        }\n                        \n                        // Enhanced synergy bonuses\n                        if (cells_near_perfect >= 6) {\n                            score += 120000;\n                        } else if (cells_near_perfect >= 4) {\n                            score += 70000;\n                        } else if (cells_near_perfect >= 2) {\n                            score += 30000;\n                        }\n                        \n                        // Average efficiency bonus\n                        if (total_efficiency > 0) {\n                            double avg_eff = total_efficiency / 9;\n                            if (avg_eff > 0.8) {\n                                score += 50000 * adaptive_bonus;\n                            } else if (avg_eff > 0.6) {\n                                score += 25000 * adaptive_bonus;\n                            }\n                        }\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_m = m;\n                            best_p = p;\n                            best_q = q;\n                        }\n                    }\n                }\n            }\n            \n            // Apply the best operation\n            if (best_m != -1) {\n                operations.push_back({best_m, best_p, best_q});\n                for (int i = 0; i < 3; i++) {\n                    for (int j = 0; j < 3; j++) {\n                        board[best_p + i][best_q + j] += stamps[best_m][i][j];\n                    }\n                }\n            }\n        }\n        \n        // Calculate final score\n        long long total_score = 0;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                total_score += board[i][j] % MOD;\n            }\n        }\n        \n        if (total_score > best_total_score) {\n            best_total_score = total_score;\n            best_operations = operations;\n        }\n    }\n    \n    // Output the best solution\n    cout << best_operations.size() << \"\\n\";\n    for (auto [m, p, q] : best_operations) {\n        cout << m << \" \" << p << \" \" << q << \"\\n\";\n    }\n    \n    return 0;\n}","ahc033":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 5;\nconst int MAX_TURNS = 10000;\n\nstruct Position {\n    int r, c;\n    bool operator==(const Position& other) const {\n        return r == other.r && c == other.c;\n    }\n    bool operator<(const Position& other) const {\n        return r < other.r || (r == other.r && c < other.c);\n    }\n};\n\nstruct State {\n    vector<vector<int>> grid;\n    vector<Position> crane_pos;\n    vector<int> crane_holding;\n    vector<queue<int>> receiving_queues;\n    vector<int> dispatch_count;\n    \n    State(const vector<vector<int>>& A) : \n        grid(N, vector<int>(N, -1)),\n        crane_pos(N),\n        crane_holding(N, -1),\n        receiving_queues(N),\n        dispatch_count(N, 0) {\n        \n        for (int i = 0; i < N; i++) {\n            crane_pos[i] = {i, 0};\n            for (int j = 0; j < N; j++) {\n                receiving_queues[i].push(A[i][j]);\n            }\n        }\n    }\n    \n    int getNextNeeded(int gate) const {\n        return gate * N + dispatch_count[gate];\n    }\n    \n    Position findContainer(int container) const {\n        for (int r = 0; r < N; r++) {\n            for (int c = 0; c < N; c++) {\n                if (grid[r][c] == container) return {r, c};\n            }\n        }\n        return {-1, -1};\n    }\n};\n\nPosition applyMove(Position pos, char move) {\n    if (move == 'U' && pos.r > 0) return {pos.r - 1, pos.c};\n    if (move == 'D' && pos.r < N-1) return {pos.r + 1, pos.c};\n    if (move == 'L' && pos.c > 0) return {pos.r, pos.c - 1};\n    if (move == 'R' && pos.c < N-1) return {pos.r, pos.c + 1};\n    return pos;\n}\n\nchar getDirectMove(Position from, Position to, const State& state, int crane) {\n    if (from == to) return '.';\n    \n    bool isLarge = (crane == 0);\n    \n    // Prioritize moves that reduce distance\n    vector<pair<char, int>> moves;\n    \n    if (to.c > from.c) moves.push_back({'R', abs(to.r - from.r)});\n    if (to.c < from.c) moves.push_back({'L', abs(to.r - from.r)});\n    if (to.r > from.r) moves.push_back({'D', abs(to.c - from.c)});\n    if (to.r < from.r) moves.push_back({'U', abs(to.c - from.c)});\n    \n    sort(moves.begin(), moves.end(), [](auto& a, auto& b) { return a.second < b.second; });\n    \n    for (auto [move, dist] : moves) {\n        Position next = applyMove(from, move);\n        if (next == from) continue;\n        \n        // Check crane collision\n        bool blocked = false;\n        for (int i = 0; i < N; i++) {\n            if (i != crane && state.crane_pos[i] == next) {\n                blocked = true;\n                break;\n            }\n        }\n        if (blocked) continue;\n        \n        // Check container collision for small crane\n        if (!isLarge && state.crane_holding[crane] != -1 && state.grid[next.r][next.c] != -1) {\n            continue;\n        }\n        \n        return move;\n    }\n    \n    // If direct path blocked, try any valid move\n    const char all_moves[] = {'R', 'D', 'U', 'L'};\n    for (char move : all_moves) {\n        Position next = applyMove(from, move);\n        if (next == from) continue;\n        \n        bool blocked = false;\n        for (int i = 0; i < N; i++) {\n            if (i != crane && state.crane_pos[i] == next) {\n                blocked = true;\n                break;\n            }\n        }\n        \n        if (!blocked && (isLarge || state.crane_holding[crane] == -1 || state.grid[next.r][next.c] == -1)) {\n            return move;\n        }\n    }\n    \n    return '.';\n}\n\nbool validateMoves(const State& state, const vector<char>& actions, vector<Position>& result) {\n    result = state.crane_pos;\n    \n    for (int i = 0; i < N; i++) {\n        if (actions[i] == 'U' || actions[i] == 'D' || \n            actions[i] == 'L' || actions[i] == 'R') {\n            Position next = applyMove(state.crane_pos[i], actions[i]);\n            if (next == state.crane_pos[i]) return false;\n            result[i] = next;\n        }\n    }\n    \n    for (int i = 0; i < N; i++) {\n        for (int j = i+1; j < N; j++) {\n            if (result[i] == result[j]) return false;\n            if (state.crane_pos[i] == result[j] && state.crane_pos[j] == result[i]) {\n                return false;\n            }\n        }\n    }\n    \n    return true;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    vector<vector<int>> A(N, vector<int>(N));\n    for (int i = 0; i < N; i++) {\n        for (int j = 0; j < N; j++) {\n            cin >> A[i][j];\n        }\n    }\n    \n    State state(A);\n    vector<string> commands(N);\n    \n    for (int turn = 0; turn < MAX_TURNS; turn++) {\n        // Receive containers\n        for (int i = 0; i < N; i++) {\n            if (!state.receiving_queues[i].empty() && state.grid[i][0] == -1) {\n                bool blocked = false;\n                for (int j = 0; j < N; j++) {\n                    if (state.crane_pos[j].r == i && state.crane_pos[j].c == 0 && \n                        state.crane_holding[j] != -1) {\n                        blocked = true;\n                        break;\n                    }\n                }\n                if (!blocked) {\n                    state.grid[i][0] = state.receiving_queues[i].front();\n                    state.receiving_queues[i].pop();\n                }\n            }\n        }\n        \n        vector<char> actions(N, '.');\n        \n        // Process each crane\n        for (int crane = 0; crane < N; crane++) {\n            Position pos = state.crane_pos[crane];\n            bool isLarge = (crane == 0);\n            \n            if (state.crane_holding[crane] != -1) {\n                // Holding container - deliver it\n                int container = state.crane_holding[crane];\n                int target_row = container / N;\n                Position dispatch = {target_row, N-1};\n                \n                if (pos == dispatch && state.grid[pos.r][pos.c] == -1) {\n                    actions[crane] = 'Q';\n                } else {\n                    // Move towards dispatch\n                    actions[crane] = getDirectMove(pos, dispatch, state, crane);\n                    \n                    // If stuck, try temporary storage in middle columns\n                    if (actions[crane] == '.') {\n                        for (int c = 3; c >= 1; c--) {\n                            for (int r = 0; r < N; r++) {\n                                if (state.grid[r][c] == -1) {\n                                    Position temp = {r, c};\n                                    char move = getDirectMove(pos, temp, state, crane);\n                                    if (move != '.') {\n                                        actions[crane] = move;\n                                        break;\n                                    }\n                                }\n                            }\n                            if (actions[crane] != '.') break;\n                        }\n                    }\n                }\n            } else {\n                // Not holding\n                if (state.grid[pos.r][pos.c] != -1) {\n                    int container = state.grid[pos.r][pos.c];\n                    int target_gate = container / N;\n                    int needed = state.getNextNeeded(target_gate);\n                    \n                    // Pick up if:\n                    // 1. It's the exact needed container\n                    // 2. At receiving gate (to clear space)\n                    // 3. Large crane and it's somewhat needed\n                    bool should_pick = (container == needed) || \n                                     (pos.c == 0) ||\n                                     (isLarge && container >= needed && container < needed + 5);\n                    \n                    if (should_pick) {\n                        actions[crane] = 'P';\n                    } else {\n                        // Move away to make space\n                        Position away;\n                        if (pos.c < N-1) {\n                            away = {pos.r, pos.c + 1};\n                        } else {\n                            away = {(pos.r + 1) % N, pos.c};\n                        }\n                        actions[crane] = getDirectMove(pos, away, state, crane);\n                    }\n                } else {\n                    // Find container to pick up\n                    Position best_target = {-1, -1};\n                    int best_score = -1000000;\n                    \n                    // Priority 1: Next needed containers\n                    for (int gate = 0; gate < N; gate++) {\n                        int needed = state.getNextNeeded(gate);\n                        if (needed >= N * N) continue;\n                        \n                        Position cont_pos = state.findContainer(needed);\n                        if (cont_pos.r == -1) continue;\n                        \n                        // Check if accessible (for small cranes)\n                        if (!isLarge) {\n                            bool blocked = false;\n                            for (int c = 0; c < cont_pos.c; c++) {\n                                if (state.grid[cont_pos.r][c] != -1) {\n                                    blocked = true;\n                                    break;\n                                }\n                            }\n                            if (blocked) continue;\n                        }\n                        \n                        int dist = abs(pos.r - cont_pos.r) + abs(pos.c - cont_pos.c);\n                        int score = 10000 - dist;\n                        \n                        if (isLarge) score += 500;\n                        \n                        if (score > best_score) {\n                            best_score = score;\n                            best_target = cont_pos;\n                        }\n                    }\n                    \n                    // Priority 2: Clear receiving gates\n                    if (best_target.r == -1) {\n                        for (int r = 0; r < N; r++) {\n                            if (state.grid[r][0] != -1) {\n                                int dist = abs(pos.r - r) + pos.c;\n                                int score = 5000 - dist;\n                                if (score > best_score) {\n                                    best_score = score;\n                                    best_target = {r, 0};\n                                }\n                            }\n                        }\n                    }\n                    \n                    if (best_target.r != -1) {\n                        actions[crane] = getDirectMove(pos, best_target, state, crane);\n                    } else if (pos.c > 0) {\n                        // Default: move left\n                        actions[crane] = 'L';\n                    }\n                }\n            }\n        }\n        \n        // Validate and resolve conflicts\n        vector<Position> new_positions;\n        if (!validateMoves(state, actions, new_positions)) {\n            // Stop lower priority cranes\n            for (int i = N-1; i >= 1; i--) {\n                if (actions[i] != 'P' && actions[i] != 'Q') {\n                    actions[i] = '.';\n                    if (validateMoves(state, actions, new_positions)) break;\n                }\n            }\n            \n            if (!validateMoves(state, actions, new_positions)) {\n                for (int i = 0; i < N; i++) {\n                    if (actions[i] != 'P' && actions[i] != 'Q') {\n                        actions[i] = '.';\n                    }\n                }\n                new_positions = state.crane_pos;\n            }\n        }\n        \n        // Execute actions\n        for (int crane = 0; crane < N; crane++) {\n            char action = actions[crane];\n            \n            if (action == 'P') {\n                if (state.grid[state.crane_pos[crane].r][state.crane_pos[crane].c] != -1 && \n                    state.crane_holding[crane] == -1) {\n                    state.crane_holding[crane] = state.grid[state.crane_pos[crane].r][state.crane_pos[crane].c];\n                    state.grid[state.crane_pos[crane].r][state.crane_pos[crane].c] = -1;\n                }\n            } else if (action == 'Q') {\n                if (state.crane_holding[crane] != -1 && \n                    state.grid[state.crane_pos[crane].r][state.crane_pos[crane].c] == -1) {\n                    state.grid[state.crane_pos[crane].r][state.crane_pos[crane].c] = state.crane_holding[crane];\n                    state.crane_holding[crane] = -1;\n                }\n            }\n            \n            commands[crane] += action;\n        }\n        \n        state.crane_pos = new_positions;\n        \n        // Dispatch containers\n        for (int i = 0; i < N; i++) {\n            if (state.grid[i][N-1] != -1) {\n                int container = state.grid[i][N-1];\n                state.grid[i][N-1] = -1;\n                \n                if (container == state.getNextNeeded(i)) {\n                    state.dispatch_count[i]++;\n                }\n            }\n        }\n        \n        // Check if done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            if (state.dispatch_count[i] < N) {\n                done = false;\n                break;\n            }\n        }\n        if (done) break;\n    }\n    \n    for (int i = 0; i < N; i++) {\n        cout << commands[i] << endl;\n    }\n    \n    return 0;\n}","ahc034":"#include <iostream>\n#include <vector>\n#include <queue>\n#include <algorithm>\n#include <cmath>\n#include <string>\n#include <set>\n\nusing namespace std;\n\nconst int N = 20;\nconst int MAX_OPS = 100000;\nconst int INF = 1e9;\n\nvector<string> operations;\nint grid[N][N];\nint cur_r = 0, cur_c = 0;\nint loaded = 0;\n\n// Direction vectors\nconst int dr[] = {-1, 1, 0, 0};\nconst int dc[] = {0, 0, -1, 1};\nconst char dir_char[] = {'U', 'D', 'L', 'R'};\n\nstruct Task {\n    int sr, sc, dr, dc, amount;\n    double efficiency;\n    bool operator<(const Task& other) const {\n        return efficiency > other.efficiency; // Higher efficiency first\n    }\n};\n\n// BFS to find shortest path\nvector<int> find_path(int sr, int sc, int tr, int tc) {\n    if (sr == tr && sc == tc) return {};\n    \n    vector<vector<int>> dist(N, vector<int>(N, INF));\n    vector<vector<int>> parent(N, vector<int>(N, -1));\n    queue<pair<int,int>> q;\n    \n    dist[sr][sc] = 0;\n    q.push({sr, sc});\n    \n    while (!q.empty()) {\n        auto [r, c] = q.front();\n        q.pop();\n        \n        if (r == tr && c == tc) break;\n        \n        for (int d = 0; d < 4; d++) {\n            int nr = r + dr[d];\n            int nc = c + dc[d];\n            if (nr >= 0 && nr < N && nc >= 0 && nc < N && dist[nr][nc] == INF) {\n                dist[nr][nc] = dist[r][c] + 1;\n                parent[nr][nc] = d;\n                q.push({nr, nc});\n            }\n        }\n    }\n    \n    // Reconstruct path\n    vector<int> path;\n    int r = tr, c = tc;\n    while (r != sr || c != sc) {\n        int d = parent[r][c];\n        path.push_back(d);\n        r -= dr[d];\n        c -= dc[d];\n    }\n    reverse(path.begin(), path.end());\n    return path;\n}\n\n// Move to target location\nvoid move_to(int tr, int tc) {\n    if (cur_r == tr && cur_c == tc) return;\n    \n    vector<int> path = find_path(cur_r, cur_c, tr, tc);\n    for (int d : path) {\n        operations.push_back(string(1, dir_char[d]));\n        cur_r += dr[d];\n        cur_c += dc[d];\n    }\n}\n\n// Load soil from current position\nvoid load_soil(int amount) {\n    if (amount <= 0 || grid[cur_r][cur_c] <= 0) return;\n    amount = min(amount, grid[cur_r][cur_c]);\n    operations.push_back(\"+\" + to_string(amount));\n    grid[cur_r][cur_c] -= amount;\n    loaded += amount;\n}\n\n// Unload soil to current position  \nvoid unload_soil(int amount) {\n    if (amount <= 0 || loaded <= 0 || grid[cur_r][cur_c] >= 0) return;\n    amount = min(amount, min(loaded, -grid[cur_r][cur_c]));\n    operations.push_back(\"-\" + to_string(amount));\n    grid[cur_r][cur_c] += amount;\n    loaded -= amount;\n}\n\n// Unload all to current position (handles both positive and negative targets)\nvoid unload_all() {\n    if (loaded <= 0) return;\n    int amount = min(loaded, -grid[cur_r][cur_c]);\n    if (amount > 0) {\n        operations.push_back(\"-\" + to_string(amount));\n        grid[cur_r][cur_c] += amount;\n        loaded -= amount;\n    }\n}\n\nint manhattan_dist(int r1, int c1, int r2, int c2) {\n    return abs(r1 - r2) + abs(c1 - c2);\n}\n\n// Calculate efficiency score for a transport task\ndouble calc_efficiency(int sr, int sc, int dr, int dc, int amount, int curr_r, int curr_c) {\n    int dist_to_src = manhattan_dist(curr_r, curr_c, sr, sc);\n    int transport_dist = manhattan_dist(sr, sc, dr, dc);\n    int total_dist = dist_to_src + transport_dist;\n    \n    // Cost = load + unload + movement\n    int cost = 2 * amount + dist_to_src * 100 + transport_dist * (100 + amount);\n    \n    // Efficiency = amount transported / estimated cost\n    // Higher is better\n    return (double)amount / (double)cost;\n}\n\nint main() {\n    int n;\n    cin >> n;\n    \n    // Read grid\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    // Main processing loop\n    while (operations.size() < MAX_OPS - 1000) {\n        // Find all tasks\n        vector<Task> tasks;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (grid[i][j] > 0) {\n                    // Find all possible destinations for this source\n                    for (int di = 0; di < N; di++) {\n                        for (int dj = 0; dj < N; dj++) {\n                            if (grid[di][dj] < 0) {\n                                int amount = min(grid[i][j], -grid[di][dj]);\n                                double eff = calc_efficiency(i, j, di, dj, amount, cur_r, cur_c);\n                                tasks.push_back({i, j, di, dj, amount, eff});\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (tasks.empty()) break;\n        \n        // Sort by efficiency\n        sort(tasks.begin(), tasks.end());\n        \n        // Execute the best task\n        Task best = tasks[0];\n        \n        // Move to source\n        move_to(best.sr, best.sc);\n        \n        // Load what we can\n        int to_load = min(grid[best.sr][best.sc], best.amount);\n        if (to_load > 0) {\n            load_soil(to_load);\n            \n            // Move to destination\n            move_to(best.dr, best.dc);\n            \n            // Unload\n            unload_all();\n        }\n        \n        // Check if done\n        bool all_zero = true;\n        for (int i = 0; i < N && all_zero; i++) {\n            for (int j = 0; j < N && all_zero; j++) {\n                if (grid[i][j] != 0) all_zero = false;\n            }\n        }\n        if (all_zero) break;\n    }\n    \n    // If there's still loaded soil at the end, try to unload it\n    if (loaded > 0) {\n        for (int i = 0; i < N && loaded > 0; i++) {\n            for (int j = 0; j < N && loaded > 0; j++) {\n                if (grid[i][j] < 0) {\n                    move_to(i, j);\n                    unload_all();\n                }\n            }\n        }\n    }\n    \n    // Output operations\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 <random>\n#include <numeric>\n#include <set>\n#include <cmath>\n#include <map>\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));\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    random_device rd;\n    mt19937 gen(rd());\n    \n    // Progress tracking\n    vector<double> generation_best(T+1, 0);\n    vector<int> global_best_traits(M, 0);\n    double prev_best = 0;\n    double prev_avg = 0;\n    int stagnation_count = 0;\n    \n    for (int t = 0; t < T; t++) {\n        // Update global best traits\n        for (int i = 0; i < seed_count; i++) {\n            for (int j = 0; j < M; j++) {\n                global_best_traits[j] = max(global_best_traits[j], X[i][j]);\n            }\n        }\n        \n        // Calculate metrics\n        vector<int> seed_values(seed_count);\n        vector<vector<int>> trait_values(M);\n        double current_best = 0;\n        double current_avg = 0;\n        \n        for (int i = 0; i < seed_count; i++) {\n            seed_values[i] = 0;\n            for (int j = 0; j < M; j++) {\n                seed_values[i] += X[i][j];\n                trait_values[j].push_back(X[i][j]);\n            }\n            current_best = max(current_best, (double)seed_values[i]);\n            current_avg += seed_values[i];\n        }\n        current_avg /= seed_count;\n        \n        // Calculate percentiles\n        vector<int> p25(M), p50(M), p75(M), p90(M), p95(M);\n        vector<double> trait_means(M, 0);\n        \n        for (int j = 0; j < M; j++) {\n            sort(trait_values[j].begin(), trait_values[j].end());\n            p25[j] = trait_values[j][seed_count/4];\n            p50[j] = trait_values[j][seed_count/2];\n            p75[j] = trait_values[j][3*seed_count/4];\n            p90[j] = trait_values[j][9*seed_count/10];\n            p95[j] = trait_values[j][19*seed_count/20];\n            \n            for (int val : trait_values[j]) {\n                trait_means[j] += val;\n            }\n            trait_means[j] /= seed_count;\n        }\n        \n        // Stagnation detection\n        generation_best[t] = current_best;\n        if (current_best <= prev_best * 1.005 && current_avg <= prev_avg * 1.01) {\n            stagnation_count++;\n        } else {\n            stagnation_count = 0;\n        }\n        prev_best = current_best;\n        prev_avg = current_avg;\n        \n        // Scoring\n        vector<double> seed_scores(seed_count);\n        \n        for (int i = 0; i < seed_count; i++) {\n            double score = seed_values[i];\n            \n            double min_trait = 1000.0;\n            double harmonic_mean = 0;\n            int elite_count = 0;\n            int good_count = 0;\n            int weak_count = 0;\n            double percentile_sum = 0;\n            \n            for (int j = 0; j < M; j++) {\n                min_trait = min(min_trait, (double)X[i][j]);\n                if (X[i][j] > 0) harmonic_mean += 1.0 / X[i][j];\n                \n                if (X[i][j] >= p90[j]) elite_count++;\n                if (X[i][j] >= p75[j]) good_count++;\n                if (X[i][j] < p25[j]) weak_count++;\n                \n                int better_count = 0;\n                for (int k = 0; k < seed_count; k++) {\n                    if (trait_values[j][k] < X[i][j]) better_count++;\n                }\n                percentile_sum += (double)better_count / seed_count;\n            }\n            \n            harmonic_mean = M / harmonic_mean;\n            \n            // Proven scoring formula\n            score = seed_values[i];\n            score += min_trait * 3.0;\n            score += harmonic_mean * 1.5;\n            score += elite_count * 30.0;\n            score += good_count * 10.0;\n            score -= weak_count * 15.0;\n            score += percentile_sum * 20.0;\n            \n            if (min_trait >= p75[0]) {\n                score *= 1.2;\n            }\n            \n            seed_scores[i] = score;\n        }\n        \n        // Sort seeds\n        vector<pair<double, int>> scored_seeds;\n        for (int i = 0; i < seed_count; i++) {\n            scored_seeds.push_back({seed_scores[i], i});\n        }\n        sort(scored_seeds.begin(), scored_seeds.end(), greater<pair<double,int>>());\n        \n        // Strategy selection\n        enum Strategy { EXPLORE, EXPLOIT, CONVERGE };\n        Strategy strategy;\n        \n        if (t < 2) {\n            strategy = EXPLORE;\n        } else if (t >= T - 2 || (t >= T - 3 && stagnation_count >= 2)) {\n            strategy = CONVERGE;\n        } else if (stagnation_count >= 3) {\n            strategy = EXPLORE;\n            stagnation_count = 0;\n        } else {\n            strategy = EXPLOIT;\n        }\n        \n        // Seed selection\n        vector<int> selected_seeds;\n        set<int> used;\n        \n        if (strategy == EXPLORE) {\n            // Diversity selection\n            int elite_size = N * N / 3;\n            for (int i = 0; i < elite_size; i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n                used.insert(scored_seeds[i].second);\n            }\n            \n            // Add trait specialists\n            for (int j = 0; j < M && (int)selected_seeds.size() < N*N; j++) {\n                int best_idx = -1;\n                int best_val = -1;\n                for (int i = 0; i < seed_count; i++) {\n                    if (used.find(i) == used.end() && X[i][j] > best_val) {\n                        best_val = X[i][j];\n                        best_idx = i;\n                    }\n                }\n                if (best_idx != -1 && best_val >= p75[j]) {\n                    selected_seeds.push_back(best_idx);\n                    used.insert(best_idx);\n                }\n            }\n            \n            // Fill remaining\n            for (auto& p : scored_seeds) {\n                if ((int)selected_seeds.size() >= N*N) break;\n                if (used.find(p.second) == used.end()) {\n                    selected_seeds.push_back(p.second);\n                    used.insert(p.second);\n                }\n            }\n            \n            // Full shuffle for diversity\n            shuffle(selected_seeds.begin(), selected_seeds.end(), gen);\n            \n        } else if (strategy == EXPLOIT) {\n            // Breeding pairs selection\n            map<pair<int,int>, double> breeding_potential;\n            \n            vector<int> candidates;\n            int candidate_count = min(N*N*2, seed_count);\n            for (int i = 0; i < candidate_count; i++) {\n                candidates.push_back(scored_seeds[i].second);\n            }\n            \n            // Calculate breeding potential with limited pairs\n            for (size_t i = 0; i < candidates.size(); i++) {\n                size_t max_j = min(candidates.size(), i + 50);  // Check up to 50 partners\n                for (size_t j = i+1; j < max_j; j++) {\n                    int s1 = candidates[i];\n                    int s2 = candidates[j];\n                    \n                    double potential = 0;\n                    double complement_bonus = 0;\n                    \n                    for (int k = 0; k < M; k++) {\n                        double max_val = max(X[s1][k], X[s2][k]);\n                        double min_val = min(X[s1][k], X[s2][k]);\n                        double expected;\n                        \n                        double diff = max_val - min_val;\n                        if (diff > 30) {\n                            expected = max_val * 0.7 + min_val * 0.3;\n                        } else if (diff > 15) {\n                            expected = max_val * 0.6 + min_val * 0.4;\n                        } else {\n                            expected = (max_val + min_val) / 2.0;\n                        }\n                        \n                        potential += expected;\n                        \n                        if ((X[s1][k] >= p90[k]) != (X[s2][k] >= p90[k])) {\n                            complement_bonus += 10;\n                        }\n                        if (X[s1][k] >= p75[k] && X[s2][k] >= p75[k]) {\n                            potential += 5;\n                        }\n                    }\n                    \n                    breeding_potential[{min(i,j), max(i,j)}] = potential + complement_bonus;\n                }\n            }\n            \n            // Select best pairs\n            vector<pair<double, pair<size_t,size_t>>> sorted_pairs;\n            for (auto& bp : breeding_potential) {\n                sorted_pairs.push_back({bp.second, bp.first});\n            }\n            sort(sorted_pairs.begin(), sorted_pairs.end(), greater<pair<double,pair<size_t,size_t>>>());\n            \n            set<size_t> selected_indices;\n            for (auto& sp : sorted_pairs) {\n                if ((int)selected_seeds.size() >= N*N) break;\n                \n                size_t idx1 = sp.second.first;\n                size_t idx2 = sp.second.second;\n                \n                if (selected_indices.find(idx1) == selected_indices.end()) {\n                    selected_seeds.push_back(candidates[idx1]);\n                    selected_indices.insert(idx1);\n                }\n                \n                if ((int)selected_seeds.size() < N*N && selected_indices.find(idx2) == selected_indices.end()) {\n                    selected_seeds.push_back(candidates[idx2]);\n                    selected_indices.insert(idx2);\n                }\n            }\n            \n            // Fill remaining\n            for (size_t i = 0; i < candidates.size() && (int)selected_seeds.size() < N*N; i++) {\n                if (selected_indices.find(i) == selected_indices.end()) {\n                    selected_seeds.push_back(candidates[i]);\n                }\n            }\n            \n        } else {  // CONVERGE\n            // Select best seeds\n            for (int i = 0; i < N*N; i++) {\n                selected_seeds.push_back(scored_seeds[i].second);\n            }\n        }\n        \n        // Placement\n        vector<vector<int>> A(N, vector<int>(N, -1));\n        \n        if (strategy == CONVERGE) {\n            // Concentric placement\n            vector<pair<double, pair<int,int>>> positions;\n            \n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    double center_i = (N - 1) / 2.0;\n                    double center_j = (N - 1) / 2.0;\n                    double dist = sqrt(pow(i - center_i, 2) + pow(j - center_j, 2));\n                    positions.push_back({dist, {i, j}});\n                }\n            }\n            \n            sort(positions.begin(), positions.end());\n            \n            for (int k = 0; k < N*N; k++) {\n                A[positions[k].second.first][positions[k].second.second] = selected_seeds[k];\n            }\n            \n        } else if (strategy == EXPLOIT) {\n            // Optimized breeding placement\n            vector<bool> placed(selected_seeds.size(), false);\n            \n            // Place best seed in center\n            A[N/2][N/2] = selected_seeds[0];\n            placed[0] = true;\n            \n            // Iteratively place remaining seeds\n            for (int count = 1; count < N*N; count++) {\n                double best_placement_score = -1;\n                int best_seed_idx = -1;\n                int best_i = -1, best_j = -1;\n                \n                // Limit search to next few unplaced seeds for efficiency\n                int search_limit = min((int)selected_seeds.size(), count + 15);\n                for (int idx = 0; idx < search_limit; idx++) {\n                    if (placed[idx]) continue;\n                    \n                    for (int i = 0; i < N; i++) {\n                        for (int j = 0; j < N; j++) {\n                            if (A[i][j] != -1) continue;\n                            \n                            double score = 0;\n                            int neighbor_count = 0;\n                            \n                            // Check neighbors\n                            int di[] = {-1, 1, 0, 0};\n                            int dj[] = {0, 0, -1, 1};\n                            \n                            for (int d = 0; d < 4; d++) {\n                                int ni = i + di[d];\n                                int nj = j + dj[d];\n                                \n                                if (ni >= 0 && ni < N && nj >= 0 && nj < N && A[ni][nj] != -1) {\n                                    neighbor_count++;\n                                    // Breeding potential\n                                    for (int k = 0; k < M; k++) {\n                                        score += max(X[selected_seeds[idx]][k], X[A[ni][nj]][k]);\n                                    }\n                                }\n                            }\n                            \n                            score += neighbor_count * 100;\n                            \n                            if (score > best_placement_score) {\n                                best_placement_score = score;\n                                best_seed_idx = idx;\n                                best_i = i;\n                                best_j = j;\n                            }\n                        }\n                    }\n                }\n                \n                if (best_seed_idx != -1) {\n                    A[best_i][best_j] = selected_seeds[best_seed_idx];\n                    placed[best_seed_idx] = true;\n                } else {\n                    // Fallback: place next unplaced seed in first empty spot\n                    for (size_t idx = 0; idx < selected_seeds.size(); idx++) {\n                        if (!placed[idx]) {\n                            bool found = false;\n                            for (int i = 0; i < N && !found; i++) {\n                                for (int j = 0; j < N && !found; j++) {\n                                    if (A[i][j] == -1) {\n                                        A[i][j] = selected_seeds[idx];\n                                        placed[idx] = true;\n                                        found = true;\n                                    }\n                                }\n                            }\n                            break;\n                        }\n                    }\n                }\n            }\n            \n        } else {  // EXPLORE\n            // Simple placement after shuffle\n            int idx = 0;\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    A[i][j] = selected_seeds[idx++];\n                }\n            }\n        }\n        \n        // Output\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) cout << \" \";\n                else cout << endl;\n            }\n        }\n        cout.flush();\n        \n        // Read new generation\n        X.clear();\n        X.resize(seed_count, vector<int>(M));\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 <bits/stdc++.h>\nusing namespace std;\n\nconst int dx[4] = {0, 1, 0, -1};  // R, D, L, U\nconst int dy[4] = {1, 0, -1, 0};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, V;\n    cin >> N >> M >> V;\n    \n    vector<string> grid(N), target(N);\n    for (int i = 0; i < N; i++) cin >> grid[i];\n    for (int i = 0; i < N; i++) cin >> target[i];\n    \n    // Use simple 2-vertex arm (root + 1 fingertip)\n    cout << \"2\\n\";\n    cout << \"0 1\\n\";  // vertex 1 has parent 0, length 1\n    cout << N/2 << \" \" << N/2 << \"\\n\";  // Start at center\n    \n    // Track state\n    int rootX = N/2, rootY = N/2;\n    int dir = 0;  // direction of arm (0=R, 1=D, 2=L, 3=U)\n    bool holding = false;\n    \n    vector<string> operations;\n    int maxTurns = 90000;\n    \n    for (int turn = 0; turn < maxTurns; turn++) {\n        // Check if we're done\n        bool done = true;\n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (target[i][j] == '1' && grid[i][j] != '1') {\n                    done = false;\n                    break;\n                }\n            }\n            if (!done) break;\n        }\n        if (done) break;\n        \n        // Current fingertip position (before any operations this turn)\n        int tipX = rootX + dx[dir];\n        int tipY = rootY + dy[dir];\n        \n        // Plan this turn's operations\n        string op = \"....\";  // 2*V = 4 characters\n        \n        // Find nearest goal\n        int goalX = -1, goalY = -1;\n        int minDist = INT_MAX;\n        \n        if (holding) {\n            // Find nearest empty target position\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (target[i][j] == '1' && grid[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goalX = i;\n                            goalY = j;\n                        }\n                    }\n                }\n            }\n        } else {\n            // Find nearest takoyaki that needs to be moved\n            for (int i = 0; i < N; i++) {\n                for (int j = 0; j < N; j++) {\n                    if (grid[i][j] == '1' && target[i][j] == '0') {\n                        int dist = abs(rootX - i) + abs(rootY - j);\n                        if (dist < minDist) {\n                            minDist = dist;\n                            goalX = i;\n                            goalY = j;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (goalX == -1) {\n            operations.push_back(op);\n            continue;\n        }\n        \n        // First, try to rotate to face the goal\n        int bestDir = dir;\n        int bestDist = abs(tipX - goalX) + abs(tipY - goalY);\n        \n        for (int d = 0; d < 4; d++) {\n            int newTipX = rootX + dx[d];\n            int newTipY = rootY + dy[d];\n            int dist = abs(newTipX - goalX) + abs(newTipY - goalY);\n            if (dist < bestDist) {\n                bestDist = dist;\n                bestDir = d;\n            }\n        }\n        \n        if (bestDir != dir) {\n            int diff = (bestDir - dir + 4) % 4;\n            if (diff == 1) {\n                op[1] = 'R';\n                dir = bestDir;\n            } else if (diff == 3) {\n                op[1] = 'L';\n                dir = bestDir;\n            } else if (diff == 2) {\n                // Need 2 rotations, do one now\n                op[1] = 'R';\n                dir = (dir + 1) % 4;\n            }\n        }\n        \n        // Recalculate tip position after rotation\n        tipX = rootX + dx[dir];\n        tipY = rootY + dy[dir];\n        \n        // Then, move towards goal if needed\n        if (abs(tipX - goalX) + abs(tipY - goalY) > 0) {\n            int newRootX = rootX, newRootY = rootY;\n            \n            if (goalX < tipX && rootX > 0) {\n                newRootX--;\n                op[0] = 'U';\n            } else if (goalX > tipX && rootX < N-1) {\n                newRootX++;\n                op[0] = 'D';\n            } else if (goalY < tipY && rootY > 0) {\n                newRootY--;\n                op[0] = 'L';\n            } else if (goalY > tipY && rootY < N-1) {\n                newRootY++;\n                op[0] = 'R';\n            }\n            \n            rootX = newRootX;\n            rootY = newRootY;\n        }\n        \n        // Recalculate final tip position\n        tipX = rootX + dx[dir];\n        tipY = rootY + dy[dir];\n        \n        // Try to pick or place\n        if (tipX >= 0 && tipX < N && tipY >= 0 && tipY < N) {\n            if (!holding && grid[tipX][tipY] == '1' && target[tipX][tipY] == '0') {\n                // Pick up\n                op[3] = 'P';  // op[V + 1] where V=2\n                grid[tipX][tipY] = '0';\n                holding = true;\n            } else if (holding && grid[tipX][tipY] == '0' && target[tipX][tipY] == '1') {\n                // Place\n                op[3] = 'P';\n                grid[tipX][tipY] = '1';\n                holding = false;\n            }\n        }\n        \n        operations.push_back(op);\n    }\n    \n    // Output all operations\n    for (const string& op : operations) {\n        cout << op << \"\\n\";\n    }\n    \n    return 0;\n}","ahc039":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int MAX_COORD = 100000;\n\nstruct Point {\n    int x, y;\n    Point(int x = 0, int y = 0) : x(x), y(y) {}\n};\n\nstruct Rectangle {\n    int x1, y1, x2, y2;\n    int score;\n    Rectangle(int x1 = 0, int y1 = 0, int x2 = 1000, int y2 = 1000) \n        : x1(x1), y1(y1), x2(x2), y2(y2), score(0) {}\n};\n\nclass Solution {\nprivate:\n    int N;\n    vector<Point> mackerels;\n    vector<Point> sardines;\n    \npublic:\n    void solve() {\n        cin >> N;\n        mackerels.resize(N);\n        sardines.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> mackerels[i].x >> mackerels[i].y;\n        }\n        for (int i = 0; i < N; i++) {\n            cin >> sardines[i].x >> sardines[i].y;\n        }\n        \n        // Find optimal rectangle\n        Rectangle best = findBestStrategy();\n        \n        // Output rectangle\n        cout << \"4\\n\";\n        cout << best.x1 << \" \" << best.y1 << \"\\n\";\n        cout << best.x2 << \" \" << best.y1 << \"\\n\";\n        cout << best.x2 << \" \" << best.y2 << \"\\n\";\n        cout << best.x1 << \" \" << best.y2 << \"\\n\";\n    }\n    \nprivate:\n    Rectangle findBestStrategy() {\n        // Analyze distribution characteristics\n        auto clusters = findClusters();\n        \n        Rectangle best;\n        best.score = 0;\n        \n        // Strategy 1: Global optimization (current approach)\n        Rectangle global_rect = findGlobalRectangle();\n        if (global_rect.score > best.score) {\n            best = global_rect;\n        }\n        \n        // Strategy 2: Cluster-focused (for multi-cluster distributions)\n        if (clusters.size() > 1) {\n            for (const auto& cluster : clusters) {\n                Rectangle cluster_rect = optimizeForCluster(cluster);\n                if (cluster_rect.score > best.score) {\n                    best = cluster_rect;\n                }\n            }\n        }\n        \n        // Strategy 3: Dense region search\n        Rectangle dense_rect = findDenseRegion();\n        if (dense_rect.score > best.score) {\n            best = dense_rect;\n        }\n        \n        return best;\n    }\n    \n    vector<vector<int>> findClusters() {\n        // Simple clustering based on distance\n        const int CLUSTER_DIST = 20000;\n        vector<vector<int>> clusters;\n        vector<bool> assigned(N, false);\n        \n        for (int i = 0; i < N; i++) {\n            if (!assigned[i]) {\n                vector<int> cluster;\n                queue<int> q;\n                q.push(i);\n                assigned[i] = true;\n                \n                while (!q.empty()) {\n                    int idx = q.front();\n                    q.pop();\n                    cluster.push_back(idx);\n                    \n                    for (int j = 0; j < N; j++) {\n                        if (!assigned[j]) {\n                            int dx = abs(mackerels[idx].x - mackerels[j].x);\n                            int dy = abs(mackerels[idx].y - mackerels[j].y);\n                            if (dx < CLUSTER_DIST && dy < CLUSTER_DIST) {\n                                assigned[j] = true;\n                                q.push(j);\n                            }\n                        }\n                    }\n                }\n                \n                if (cluster.size() >= 100) {  // Only consider significant clusters\n                    clusters.push_back(cluster);\n                }\n            }\n        }\n        \n        return clusters;\n    }\n    \n    Rectangle optimizeForCluster(const vector<int>& cluster) {\n        // Find bounding box of cluster\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        \n        for (int idx : cluster) {\n            min_x = min(min_x, mackerels[idx].x);\n            max_x = max(max_x, mackerels[idx].x);\n            min_y = min(min_y, mackerels[idx].y);\n            max_y = max(max_y, mackerels[idx].y);\n        }\n        \n        // Start with cluster bounding box\n        Rectangle rect(max(0, min_x - 2000), max(0, min_y - 2000),\n                      min(MAX_COORD, max_x + 2000), min(MAX_COORD, max_y + 2000));\n        \n        // Optimize\n        rect = optimizeRectangle(rect);\n        \n        return rect;\n    }\n    \n    Rectangle findDenseRegion() {\n        // Create density map\n        const int DENSITY_GRID = 100;\n        int cell_size = (MAX_COORD + DENSITY_GRID - 1) / DENSITY_GRID;\n        \n        vector<vector<int>> density(DENSITY_GRID, vector<int>(DENSITY_GRID, 0));\n        \n        for (const auto& p : mackerels) {\n            density[min(p.x / cell_size, DENSITY_GRID - 1)]\n                   [min(p.y / cell_size, DENSITY_GRID - 1)]++;\n        }\n        for (const auto& p : sardines) {\n            density[min(p.x / cell_size, DENSITY_GRID - 1)]\n                   [min(p.y / cell_size, DENSITY_GRID - 1)]--;\n        }\n        \n        // Find densest region\n        int best_density = 0;\n        int best_x = 0, best_y = 0;\n        \n        for (int x = 0; x < DENSITY_GRID; x++) {\n            for (int y = 0; y < DENSITY_GRID; y++) {\n                int sum = 0;\n                for (int dx = 0; dx < 10 && x + dx < DENSITY_GRID; dx++) {\n                    for (int dy = 0; dy < 10 && y + dy < DENSITY_GRID; dy++) {\n                        sum += density[x + dx][y + dy];\n                    }\n                }\n                if (sum > best_density) {\n                    best_density = sum;\n                    best_x = x;\n                    best_y = y;\n                }\n            }\n        }\n        \n        // Create rectangle around dense region\n        Rectangle rect(best_x * cell_size, best_y * cell_size,\n                      min((best_x + 10) * cell_size, MAX_COORD),\n                      min((best_y + 10) * cell_size, MAX_COORD));\n        \n        rect = optimizeRectangle(rect);\n        \n        return rect;\n    }\n    \n    Rectangle findGlobalRectangle() {\n        // Analyze spread\n        int min_x = MAX_COORD, max_x = 0, min_y = MAX_COORD, max_y = 0;\n        for (const auto& p : mackerels) {\n            min_x = min(min_x, p.x);\n            max_x = max(max_x, p.x);\n            min_y = min(min_y, p.y);\n            max_y = max(max_y, p.y);\n        }\n        \n        int spread = max(max_x - min_x, max_y - min_y);\n        \n        // Choose grid sizes\n        vector<int> grid_sizes;\n        if (spread < 25000) {\n            grid_sizes = {120, 160, 200, 240, 280};\n        } else if (spread < 40000) {\n            grid_sizes = {70, 90, 110, 130, 150};\n        } else if (spread < 60000) {\n            grid_sizes = {50, 70, 90, 110};\n        } else {\n            grid_sizes = {35, 50, 65, 80};\n        }\n        \n        Rectangle best;\n        best.score = 0;\n        \n        for (int grid_size : grid_sizes) {\n            Rectangle rect = findRectangleWithGrid(grid_size);\n            rect = optimizeRectangle(rect);\n            if (rect.score > best.score) {\n                best = rect;\n            }\n        }\n        \n        return best;\n    }\n    \n    Rectangle findRectangleWithGrid(int grid_size) {\n        int cell_size = (MAX_COORD + grid_size - 1) / grid_size;\n        \n        vector<vector<int>> grid(grid_size, vector<int>(grid_size, 0));\n        \n        for (const auto& p : mackerels) {\n            grid[min(p.x / cell_size, grid_size - 1)]\n                [min(p.y / cell_size, grid_size - 1)]++;\n        }\n        for (const auto& p : sardines) {\n            grid[min(p.x / cell_size, grid_size - 1)]\n                [min(p.y / cell_size, grid_size - 1)]--;\n        }\n        \n        Rectangle best;\n        best.score = 0;\n        \n        int max_width = min(grid_size, 200000 / cell_size + 1);\n        int max_height = min(grid_size, 200000 / cell_size + 1);\n        \n        // 2D Kadane\n        for (int left = 0; left < grid_size; left++) {\n            vector<int> temp(grid_size, 0);\n            \n            for (int right = left; right < min(left + max_width, grid_size); right++) {\n                for (int i = 0; i < grid_size; i++) {\n                    temp[i] += grid[right][i];\n                }\n                \n                // 1D Kadane\n                int current = 0, max_sum = 0;\n                int start = 0, end = -1, temp_start = 0;\n                \n                for (int i = 0; i < grid_size; i++) {\n                    current += temp[i];\n                    \n                    while (temp_start < i && i - temp_start + 1 > max_height) {\n                        current -= temp[temp_start];\n                        temp_start++;\n                    }\n                    \n                    if (current > max_sum) {\n                        max_sum = current;\n                        start = temp_start;\n                        end = i;\n                    }\n                    \n                    if (current < 0) {\n                        current = 0;\n                        temp_start = i + 1;\n                    }\n                }\n                \n                if (max_sum > best.score) {\n                    best.score = max_sum;\n                    best.x1 = left * cell_size;\n                    best.y1 = start * cell_size;\n                    best.x2 = min((right + 1) * cell_size, MAX_COORD);\n                    best.y2 = min((end + 1) * cell_size, MAX_COORD);\n                }\n            }\n        }\n        \n        return best;\n    }\n    \n    Rectangle optimizeRectangle(Rectangle rect) {\n        rect.score = calculateScore(rect);\n        \n        // Multi-scale optimization\n        for (int scale : {5000, 2000, 1000, 500, 200, 100, 50, 20, 10, 5, 2, 1}) {\n            bool improved = true;\n            int iterations = 0;\n            \n            while (improved && iterations < 10) {\n                improved = false;\n                iterations++;\n                \n                for (int delta : {-scale, scale}) {\n                    Rectangle candidates[4] = {\n                        Rectangle(rect.x1 + delta, rect.y1, rect.x2, rect.y2),\n                        Rectangle(rect.x1, rect.y1 + delta, rect.x2, rect.y2),\n                        Rectangle(rect.x1, rect.y1, rect.x2 + delta, rect.y2),\n                        Rectangle(rect.x1, rect.y1, rect.x2, rect.y2 + delta)\n                    };\n                    \n                    for (auto& r : candidates) {\n                        if (r.x1 >= 0 && r.x1 < r.x2 && r.x2 <= MAX_COORD &&\n                            r.y1 >= 0 && r.y1 < r.y2 && r.y2 <= MAX_COORD &&\n                            2 * ((r.x2 - r.x1) + (r.y2 - r.y1)) <= 400000) {\n                            r.score = calculateScore(r);\n                            if (r.score > rect.score) {\n                                rect = r;\n                                improved = true;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        \n        // Fish coordinate optimization\n        rect = optimizeWithFishCoordinates(rect);\n        \n        return rect;\n    }\n    \n    Rectangle optimizeWithFishCoordinates(Rectangle rect) {\n        set<int> x_coords, y_coords;\n        \n        // Collect coordinates near boundaries\n        for (const auto& p : mackerels) {\n            if (abs(p.x - rect.x1) <= 30 || abs(p.x - rect.x2) <= 30) {\n                x_coords.insert(p.x);\n                if (p.x > 0) x_coords.insert(p.x - 1);\n                if (p.x < MAX_COORD) x_coords.insert(p.x + 1);\n            }\n            if (abs(p.y - rect.y1) <= 30 || abs(p.y - rect.y2) <= 30) {\n                y_coords.insert(p.y);\n                if (p.y > 0) y_coords.insert(p.y - 1);\n                if (p.y < MAX_COORD) y_coords.insert(p.y + 1);\n            }\n        }\n        \n        for (const auto& p : sardines) {\n            if (abs(p.x - rect.x1) <= 30 || abs(p.x - rect.x2) <= 30) {\n                x_coords.insert(p.x);\n                if (p.x > 0) x_coords.insert(p.x - 1);\n                if (p.x < MAX_COORD) x_coords.insert(p.x + 1);\n            }\n            if (abs(p.y - rect.y1) <= 30 || abs(p.y - rect.y2) <= 30) {\n                y_coords.insert(p.y);\n                if (p.y > 0) y_coords.insert(p.y - 1);\n                if (p.y < MAX_COORD) y_coords.insert(p.y + 1);\n            }\n        }\n        \n        rect.score = calculateScore(rect);\n        \n        // Try fish coordinates\n        for (int x : x_coords) {\n            if (x >= max(0, rect.x1 - 30) && x < rect.x2) {\n                Rectangle r(x, rect.y1, rect.x2, rect.y2);\n                r.score = calculateScore(r);\n                if (r.score > rect.score) rect = r;\n            }\n            \n            if (x > rect.x1 && x <= min(MAX_COORD, rect.x2 + 30) &&\n                2 * ((x - rect.x1) + (rect.y2 - rect.y1)) <= 400000) {\n                Rectangle r(rect.x1, rect.y1, x, rect.y2);\n                r.score = calculateScore(r);\n                if (r.score > rect.score) rect = r;\n            }\n        }\n        \n        for (int y : y_coords) {\n            if (y >= max(0, rect.y1 - 30) && y < rect.y2) {\n                Rectangle r(rect.x1, y, rect.x2, rect.y2);\n                r.score = calculateScore(r);\n                if (r.score > rect.score) rect = r;\n            }\n            \n            if (y > rect.y1 && y <= min(MAX_COORD, rect.y2 + 30) &&\n                2 * ((rect.x2 - rect.x1) + (y - rect.y1)) <= 400000) {\n                Rectangle r(rect.x1, rect.y1, rect.x2, y);\n                r.score = calculateScore(r);\n                if (r.score > rect.score) rect = r;\n            }\n        }\n        \n        return rect;\n    }\n    \n    int calculateScore(const Rectangle& rect) {\n        int score = 0;\n        for (const auto& p : mackerels) {\n            if (p.x >= rect.x1 && p.x <= rect.x2 && \n                p.y >= rect.y1 && p.y <= rect.y2) {\n                score++;\n            }\n        }\n        for (const auto& p : sardines) {\n            if (p.x >= rect.x1 && p.x <= rect.x2 && \n                p.y >= rect.y1 && p.y <= rect.y2) {\n                score--;\n            }\n        }\n        return score;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Solution sol;\n    sol.solve();\n    \n    return 0;\n}","ahc040":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct Rectangle {\n    double obs_w, obs_h;\n    double est_w, est_h;\n    double sum_ratio;\n    int count;\n};\n\nstruct Placement {\n    int p, r, b;\n    char d;\n};\n\nstruct PlacedRect {\n    int x, y, w, h;\n};\n\nclass Packer {\nprivate:\n    int N, T;\n    double sigma;\n    vector<Rectangle> rects;\n    double best_score = 1e18;\n    vector<Placement> best_placement;\n    \n    pair<vector<PlacedRect>, pair<int,int>> simulatePlacement(const vector<Placement>& placements) {\n        vector<PlacedRect> placed;\n        \n        for (const auto& p : placements) {\n            int w = p.r ? (int)round(rects[p.p].est_h) : (int)round(rects[p.p].est_w);\n            int h = p.r ? (int)round(rects[p.p].est_w) : (int)round(rects[p.p].est_h);\n            \n            int x = 0, y = 0;\n            \n            if (p.d == 'U') {\n                if (p.b >= 0) {\n                    x = placed[p.b].x + placed[p.b].w;\n                }\n                for (const auto& rect : placed) {\n                    if (x < rect.x + rect.w && x + w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n            } else {\n                if (p.b >= 0) {\n                    y = placed[p.b].y + placed[p.b].h;\n                }\n                for (const auto& rect : placed) {\n                    if (y < rect.y + rect.h && y + h > rect.y) {\n                        x = max(x, rect.x + rect.w);\n                    }\n                }\n            }\n            \n            placed.push_back({x, y, w, h});\n        }\n        \n        int maxX = 0, maxY = 0;\n        for (const auto& rect : placed) {\n            maxX = max(maxX, rect.x + rect.w);\n            maxY = max(maxY, rect.y + rect.h);\n        }\n        \n        return {placed, {maxX, maxY}};\n    }\n    \n    // Clean bottom-left packing\n    vector<Placement> createBottomLeft(const vector<bool>& rotations, bool allow_above = true) {\n        vector<Placement> result;\n        vector<PlacedRect> placed;\n        \n        for (int i = 0; i < N; i++) {\n            int w = rotations[i] ? (int)round(rects[i].est_h) : (int)round(rects[i].est_w);\n            int h = rotations[i] ? (int)round(rects[i].est_w) : (int)round(rects[i].est_h);\n            \n            if (i == 0) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, 'U'});\n                placed.push_back({0, 0, w, h});\n                continue;\n            }\n            \n            int bestX = INT_MAX, bestY = INT_MAX;\n            int bestRef = -1;\n            char bestDir = 'U';\n            \n            // Try x=0\n            int y = 0;\n            for (const auto& rect : placed) {\n                if (w > rect.x) {\n                    y = max(y, rect.y + rect.h);\n                }\n            }\n            if (y < bestY || (y == bestY && 0 < bestX)) {\n                bestY = y; bestX = 0; bestRef = -1; bestDir = 'U';\n            }\n            \n            // Try right of each rectangle\n            for (int j = 0; j < (int)placed.size(); j++) {\n                int x = placed[j].x + placed[j].w;\n                y = 0;\n                for (const auto& rect : placed) {\n                    if (x < rect.x + rect.w && x + w > rect.x) {\n                        y = max(y, rect.y + rect.h);\n                    }\n                }\n                if (y < bestY || (y == bestY && x < bestX)) {\n                    bestY = y; bestX = x; bestRef = j; bestDir = 'U';\n                }\n            }\n            \n            // Try above recent rectangles\n            if (allow_above) {\n                int check_limit = min(4, (int)placed.size());\n                for (int j = placed.size() - check_limit; j < (int)placed.size(); j++) {\n                    if (j < 0) continue;\n                    \n                    int x = 0;\n                    y = placed[j].y + placed[j].h;\n                    for (const auto& rect : placed) {\n                        if (y < rect.y + rect.h && y + h > rect.y) {\n                            x = max(x, rect.x + rect.w);\n                        }\n                    }\n                    if (y < bestY || (y == bestY && x < bestX)) {\n                        bestY = y; bestX = x; bestRef = j; bestDir = 'L';\n                    }\n                }\n            }\n            \n            result.push_back({i, rotations[i] ? 1 : 0, bestRef, bestDir});\n            placed.push_back({bestX, bestY, w, h});\n        }\n        \n        return result;\n    }\n    \n    // Simple shelf packing\n    vector<Placement> createShelfPacking(const vector<bool>& rotations, int items_per_shelf) {\n        vector<Placement> result;\n        int shelf_start = -1;\n        int count = 0;\n        \n        for (int i = 0; i < N; i++) {\n            if (count == 0) {\n                if (i == 0) {\n                    result.push_back({i, rotations[i] ? 1 : 0, -1, 'L'});\n                } else {\n                    result.push_back({i, rotations[i] ? 1 : 0, shelf_start, 'L'});\n                }\n                shelf_start = i;\n                count = 1;\n            } else if (count < items_per_shelf) {\n                result.push_back({i, rotations[i] ? 1 : 0, i-1, 'U'});\n                count++;\n            } else {\n                result.push_back({i, rotations[i] ? 1 : 0, shelf_start, 'L'});\n                shelf_start = i;\n                count = 1;\n            }\n        }\n        \n        return result;\n    }\n    \n    // Strip packing\n    vector<Placement> createStripPacking(const vector<bool>& rotations, bool horizontal) {\n        vector<Placement> result;\n        for (int i = 0; i < N; i++) {\n            if (i == 0) {\n                result.push_back({i, rotations[i] ? 1 : 0, -1, horizontal ? 'U' : 'L'});\n            } else {\n                result.push_back({i, rotations[i] ? 1 : 0, i-1, horizontal ? 'U' : 'L'});\n            }\n        }\n        return result;\n    }\n    \n    pair<int, int> query(const vector<Placement>& placements) {\n        cout << placements.size() << endl;\n        for (const auto& p : placements) {\n            cout << p.p << \" \" << p.r << \" \" << p.d << \" \" << p.b << endl;\n        }\n        cout.flush();\n        \n        int W, H;\n        cin >> W >> H;\n        return {W, H};\n    }\n    \n    void updateEstimates(int W_measured, int H_measured, const vector<Placement>& placements) {\n        auto [placed, expected] = simulatePlacement(placements);\n        \n        // Calculate error ratio\n        double ratio = sqrt((double)(W_measured * H_measured) / (expected.first * expected.second));\n        \n        // Update rectangles\n        for (int i = 0; i < N; i++) {\n            rects[i].count++;\n            \n            if (ratio > 0.8 && ratio < 1.25) {\n                rects[i].sum_ratio += ratio;\n                double avg_ratio = rects[i].sum_ratio / rects[i].count;\n                \n                // Simple adaptive learning rate\n                double lr = 0.2 / sqrt(rects[i].count);\n                \n                double target_w = rects[i].obs_w * avg_ratio;\n                double target_h = rects[i].obs_h * avg_ratio;\n                \n                rects[i].est_w = rects[i].est_w * (1 - lr) + target_w * lr;\n                rects[i].est_h = rects[i].est_h * (1 - lr) + target_h * lr;\n            }\n            \n            // Keep bounds reasonable\n            rects[i].est_w = max(rects[i].obs_w * 0.75, min(rects[i].est_w, rects[i].obs_w * 1.25));\n            rects[i].est_h = max(rects[i].obs_h * 0.75, min(rects[i].est_h, rects[i].obs_h * 1.25));\n        }\n    }\n    \n    vector<bool> chooseRotations(int strategy) {\n        vector<bool> rotations(N);\n        \n        for (int i = 0; i < N; i++) {\n            switch(strategy) {\n                case 0: // Minimize height\n                    rotations[i] = (rects[i].est_w > rects[i].est_h);\n                    break;\n                case 1: // Minimize width\n                    rotations[i] = (rects[i].est_h > rects[i].est_w);\n                    break;\n                case 2: // Balance\n                    {\n                        double ratio = rects[i].est_w / rects[i].est_h;\n                        rotations[i] = (ratio > 1.5 || ratio < 0.67);\n                    }\n                    break;\n                default: // Mixed\n                    rotations[i] = ((i % 2) == 0) ? (rects[i].est_w > rects[i].est_h) : false;\n            }\n        }\n        \n        return rotations;\n    }\n    \npublic:\n    void solve() {\n        cin >> N >> T >> sigma;\n        rects.resize(N);\n        \n        for (int i = 0; i < N; i++) {\n            cin >> rects[i].obs_w >> rects[i].obs_h;\n            rects[i].est_w = rects[i].obs_w;\n            rects[i].est_h = rects[i].obs_h;\n            rects[i].sum_ratio = 1.0;\n            rects[i].count = 0;\n        }\n        \n        // Initial conservative adjustment\n        double init_factor = max(0.85, 1.0 - sigma / 30000.0);\n        for (int i = 0; i < N; i++) {\n            rects[i].est_w *= init_factor;\n            rects[i].est_h *= init_factor;\n        }\n        \n        for (int turn = 0; turn < T; turn++) {\n            vector<Placement> placements;\n            \n            if (turn < T / 3) {\n                // Exploration phase\n                int pack_method = turn % 4;\n                int rot_method = turn % 3;\n                auto rotations = chooseRotations(rot_method);\n                \n                switch(pack_method) {\n                    case 0:\n                    case 1:\n                        placements = createBottomLeft(rotations, pack_method == 0);\n                        break;\n                    case 2:\n                        placements = createShelfPacking(rotations, max(3, (int)sqrt(N)));\n                        break;\n                    case 3:\n                        placements = createStripPacking(rotations, turn % 2 == 0);\n                        break;\n                }\n            } else if (turn < 2 * T / 3) {\n                // Refinement phase\n                auto rotations = chooseRotations(0); // Minimize height\n                \n                if (turn % 2 == 0) {\n                    placements = createBottomLeft(rotations, true);\n                } else {\n                    placements = createShelfPacking(rotations, max(3, N/4));\n                }\n            } else {\n                // Exploitation phase\n                if (best_placement.size() > 0 && turn % 3 == 0) {\n                    placements = best_placement;\n                } else {\n                    auto rotations = chooseRotations(0);\n                    placements = createBottomLeft(rotations, true);\n                }\n            }\n            \n            auto [W, H] = query(placements);\n            \n            double score = W + H;\n            if (score < best_score) {\n                best_score = score;\n                best_placement = placements;\n            }\n            \n            updateEstimates(W, H, placements);\n        }\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    Packer packer;\n    packer.solve();\n    \n    return 0;\n}","ahc041":"#include <bits/stdc++.h>\nusing namespace std;\n\nclass ForestOptimizer {\n    int N, M, H;\n    vector<int> beauty;\n    vector<vector<int>> adj;\n    \n    long long calculateScore(const vector<int>& parent) {\n        long long score = 1;\n        for (int i = 0; i < N; i++) {\n            int depth = 0;\n            int curr = i;\n            while (parent[curr] != -1) {\n                depth++;\n                curr = parent[curr];\n                if (depth > H) return -1; // Invalid configuration\n            }\n            score += (long long)(depth + 1) * beauty[i];\n        }\n        return score;\n    }\n    \n    int getDepth(int v, const vector<int>& parent) {\n        int depth = 0;\n        int curr = v;\n        while (parent[curr] != -1) {\n            depth++;\n            curr = parent[curr];\n        }\n        return depth;\n    }\n    \n    int getSubtreeHeight(int v, const vector<int>& parent) {\n        int maxHeight = 0;\n        for (int u = 0; u < N; u++) {\n            if (parent[u] == v) {\n                maxHeight = max(maxHeight, 1 + getSubtreeHeight(u, parent));\n            }\n        }\n        return maxHeight;\n    }\n    \n    long long evaluateSubtree(int root, const vector<bool>& used, int maxDepth) {\n        if (used[root]) return 0;\n        \n        long long score = beauty[root];\n        queue<pair<int, int>> q;\n        q.push({root, 0});\n        vector<bool> visited = used;\n        visited[root] = true;\n        \n        while (!q.empty()) {\n            auto [u, depth] = q.front();\n            q.pop();\n            \n            if (depth >= maxDepth) continue;\n            \n            vector<pair<int, int>> neighbors;\n            for (int v : adj[u]) {\n                if (!visited[v]) {\n                    neighbors.push_back({beauty[v], v});\n                }\n            }\n            sort(neighbors.rbegin(), neighbors.rend());\n            \n            for (auto [b, v] : neighbors) {\n                visited[v] = true;\n                score += (long long)(depth + 2) * b;\n                q.push({v, depth + 1});\n            }\n        }\n        \n        return score;\n    }\n    \n    vector<int> buildOptimalForest() {\n        vector<int> parent(N, -1);\n        vector<bool> used(N, false);\n        \n        while (true) {\n            int bestRoot = -1;\n            long long bestScore = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (!used[i]) {\n                    long long score = evaluateSubtree(i, used, H);\n                    if (score > bestScore) {\n                        bestScore = score;\n                        bestRoot = i;\n                    }\n                }\n            }\n            \n            if (bestRoot == -1) break;\n            \n            used[bestRoot] = true;\n            queue<pair<int, int>> q;\n            q.push({bestRoot, 0});\n            \n            while (!q.empty()) {\n                auto [u, depth] = q.front();\n                q.pop();\n                \n                if (depth >= H) continue;\n                \n                vector<pair<int, int>> neighbors;\n                for (int v : adj[u]) {\n                    if (!used[v]) {\n                        neighbors.push_back({beauty[v], v});\n                    }\n                }\n                sort(neighbors.rbegin(), neighbors.rend());\n                \n                for (auto [_, v] : neighbors) {\n                    parent[v] = u;\n                    used[v] = true;\n                    q.push({v, depth + 1});\n                }\n            }\n        }\n        \n        return parent;\n    }\n    \n    vector<int> buildGreedyForest() {\n        vector<int> parent(N, -1);\n        vector<bool> visited(N, false);\n        \n        vector<pair<int, int>> nodes;\n        for (int i = 0; i < N; i++) {\n            nodes.push_back({beauty[i], i});\n        }\n        sort(nodes.rbegin(), nodes.rend());\n        \n        for (auto [_, root] : nodes) {\n            if (visited[root]) continue;\n            \n            visited[root] = true;\n            queue<pair<int, int>> q;\n            q.push({root, 0});\n            \n            while (!q.empty()) {\n                auto [u, depth] = q.front();\n                q.pop();\n                \n                if (depth >= H) continue;\n                \n                vector<pair<int, int>> neighbors;\n                for (int v : adj[u]) {\n                    if (!visited[v]) {\n                        neighbors.push_back({beauty[v], v});\n                    }\n                }\n                sort(neighbors.rbegin(), neighbors.rend());\n                \n                for (auto [_, v] : neighbors) {\n                    parent[v] = u;\n                    visited[v] = true;\n                    q.push({v, depth + 1});\n                }\n            }\n        }\n        \n        return parent;\n    }\n    \n    vector<int> improveWithLocalSearch(vector<int> parent, int iterations = 200) {\n        long long currentScore = calculateScore(parent);\n        \n        for (int iter = 0; iter < iterations; iter++) {\n            bool improved = false;\n            \n            // Only move leaf nodes to avoid depth constraint violations\n            for (int v = 0; v < N; v++) {\n                if (parent[v] == -1) continue;\n                \n                // Check if v is a leaf\n                bool isLeaf = true;\n                for (int u = 0; u < N; u++) {\n                    if (parent[u] == v) {\n                        isLeaf = false;\n                        break;\n                    }\n                }\n                \n                if (!isLeaf) continue; // Only move leaves\n                \n                int oldParent = parent[v];\n                int oldDepth = getDepth(v, parent);\n                long long oldContrib = (long long)(oldDepth + 1) * beauty[v];\n                \n                int bestParent = oldParent;\n                long long bestImprovement = 0;\n                \n                // Try each neighbor as new parent\n                for (int newParent : adj[v]) {\n                    if (newParent == oldParent) continue;\n                    \n                    // Check for cycle\n                    bool hasCycle = false;\n                    int curr = newParent;\n                    int steps = 0;\n                    while (parent[curr] != -1 && steps <= H + 1) {\n                        if (curr == v) {\n                            hasCycle = true;\n                            break;\n                        }\n                        curr = parent[curr];\n                        steps++;\n                    }\n                    if (hasCycle) continue;\n                    \n                    // Check depth constraint\n                    int newDepth = getDepth(newParent, parent) + 1;\n                    if (newDepth > H) continue;\n                    \n                    long long newContrib = (long long)(newDepth + 1) * beauty[v];\n                    long long improvement = newContrib - oldContrib;\n                    \n                    if (improvement > bestImprovement) {\n                        bestImprovement = improvement;\n                        bestParent = newParent;\n                    }\n                }\n                \n                // Try making v a root if it has high beauty\n                if (beauty[v] > 80) {\n                    long long newContrib = beauty[v];\n                    long long improvement = newContrib - oldContrib;\n                    if (improvement > bestImprovement) {\n                        bestImprovement = improvement;\n                        bestParent = -1;\n                    }\n                }\n                \n                if (bestParent != oldParent) {\n                    parent[v] = bestParent;\n                    currentScore += bestImprovement;\n                    improved = true;\n                }\n            }\n            \n            if (!improved && iter > 50) break;\n        }\n        \n        return parent;\n    }\n    \npublic:\n    ForestOptimizer(int n, int m, int h) : N(n), M(m), H(h) {\n        beauty.resize(N);\n        adj.resize(N);\n    }\n    \n    void input() {\n        for (int i = 0; i < N; i++) {\n            cin >> beauty[i];\n        }\n        \n        for (int i = 0; i < M; i++) {\n            int u, v;\n            cin >> u >> v;\n            adj[u].push_back(v);\n            adj[v].push_back(u);\n        }\n        \n        // Skip coordinates\n        for (int i = 0; i < N; i++) {\n            int x, y;\n            cin >> x >> y;\n        }\n    }\n    \n    vector<int> solve() {\n        vector<int> bestParent;\n        long long bestScore = 0;\n        \n        // Strategy 1: Optimal with subtree evaluation\n        vector<int> parent1 = buildOptimalForest();\n        parent1 = improveWithLocalSearch(parent1);\n        long long score1 = calculateScore(parent1);\n        if (score1 > 0 && score1 > bestScore) {\n            bestScore = score1;\n            bestParent = parent1;\n        }\n        \n        // Strategy 2: Pure greedy\n        vector<int> parent2 = buildGreedyForest();\n        parent2 = improveWithLocalSearch(parent2);\n        long long score2 = calculateScore(parent2);\n        if (score2 > 0 && score2 > bestScore) {\n            bestScore = score2;\n            bestParent = parent2;\n        }\n        \n        // Verify the solution\n        for (int i = 0; i < N; i++) {\n            int depth = getDepth(i, bestParent);\n            if (depth > H) {\n                // Fallback to simple greedy if something went wrong\n                return buildGreedyForest();\n            }\n        }\n        \n        return bestParent;\n    }\n};\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, M, H;\n    cin >> N >> M >> H;\n    \n    ForestOptimizer optimizer(N, M, H);\n    optimizer.input();\n    \n    vector<int> result = optimizer.solve();\n    \n    for (int i = 0; i < N; i++) {\n        cout << result[i];\n        if (i < N - 1) cout << \" \";\n    }\n    cout << \"\\n\";\n    \n    return 0;\n}","ahc042":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    int N;\n    cin >> N;\n    \n    vector<string> board(N);\n    for (int i = 0; i < N; i++) {\n        cin >> board[i];\n    }\n    \n    vector<pair<char, int>> operations;\n    \n    while (true) {\n        // First, analyze all Oni and their removal options\n        map<pair<int,int>, vector<pair<char,int>>> oni_options;\n        \n        for (int i = 0; i < N; i++) {\n            for (int j = 0; j < N; j++) {\n                if (board[i][j] != 'x') continue;\n                \n                // Check UP\n                bool up_ok = true;\n                for (int k = 0; k < i; k++) {\n                    if (board[k][j] == 'o') {\n                        up_ok = false;\n                        break;\n                    }\n                }\n                if (up_ok) {\n                    oni_options[{i,j}].push_back({'U', i+1});\n                }\n                \n                // Check DOWN\n                bool down_ok = true;\n                for (int k = i+1; k < N; k++) {\n                    if (board[k][j] == 'o') {\n                        down_ok = false;\n                        break;\n                    }\n                }\n                if (down_ok) {\n                    oni_options[{i,j}].push_back({'D', N-i});\n                }\n                \n                // Check LEFT\n                bool left_ok = true;\n                for (int k = 0; k < j; k++) {\n                    if (board[i][k] == 'o') {\n                        left_ok = false;\n                        break;\n                    }\n                }\n                if (left_ok) {\n                    oni_options[{i,j}].push_back({'L', j+1});\n                }\n                \n                // Check RIGHT\n                bool right_ok = true;\n                for (int k = j+1; k < N; k++) {\n                    if (board[i][k] == 'o') {\n                        right_ok = false;\n                        break;\n                    }\n                }\n                if (right_ok) {\n                    oni_options[{i,j}].push_back({'R', N-j});\n                }\n            }\n        }\n        \n        if (oni_options.empty()) break;\n        \n        // Create batch options\n        struct BatchOpt {\n            char dir;\n            int line;\n            vector<pair<int,int>> targets;\n            int cost;\n            double score;\n            int min_flexibility;  // Minimum number of options among targets\n        };\n        \n        vector<BatchOpt> batches;\n        \n        // Generate all possible batches\n        for (int j = 0; j < N; j++) {\n            // UP\n            BatchOpt up;\n            up.dir = 'U';\n            up.line = j;\n            up.min_flexibility = INT_MAX;\n            int max_pos = -1;\n            \n            for (int i = 0; i < N; i++) {\n                if (board[i][j] == 'o') break;\n                if (board[i][j] == 'x') {\n                    up.targets.push_back({i, j});\n                    max_pos = i;\n                    if (oni_options.count({i,j})) {\n                        up.min_flexibility = min(up.min_flexibility, (int)oni_options[{i,j}].size());\n                    }\n                }\n            }\n            \n            if (!up.targets.empty()) {\n                up.cost = 2 * (max_pos + 1);\n                batches.push_back(up);\n            }\n            \n            // DOWN\n            BatchOpt down;\n            down.dir = 'D';\n            down.line = j;\n            down.min_flexibility = INT_MAX;\n            int min_pos = N;\n            \n            for (int i = N-1; i >= 0; i--) {\n                if (board[i][j] == 'o') break;\n                if (board[i][j] == 'x') {\n                    down.targets.push_back({i, j});\n                    min_pos = i;\n                    if (oni_options.count({i,j})) {\n                        down.min_flexibility = min(down.min_flexibility, (int)oni_options[{i,j}].size());\n                    }\n                }\n            }\n            \n            if (!down.targets.empty()) {\n                down.cost = 2 * (N - min_pos);\n                batches.push_back(down);\n            }\n        }\n        \n        for (int i = 0; i < N; i++) {\n            // LEFT\n            BatchOpt left;\n            left.dir = 'L';\n            left.line = i;\n            left.min_flexibility = INT_MAX;\n            int max_pos = -1;\n            \n            for (int j = 0; j < N; j++) {\n                if (board[i][j] == 'o') break;\n                if (board[i][j] == 'x') {\n                    left.targets.push_back({i, j});\n                    max_pos = j;\n                    if (oni_options.count({i,j})) {\n                        left.min_flexibility = min(left.min_flexibility, (int)oni_options[{i,j}].size());\n                    }\n                }\n            }\n            \n            if (!left.targets.empty()) {\n                left.cost = 2 * (max_pos + 1);\n                batches.push_back(left);\n            }\n            \n            // RIGHT\n            BatchOpt right;\n            right.dir = 'R';\n            right.line = i;\n            right.min_flexibility = INT_MAX;\n            int min_pos = N;\n            \n            for (int j = N-1; j >= 0; j--) {\n                if (board[i][j] == 'o') break;\n                if (board[i][j] == 'x') {\n                    right.targets.push_back({i, j});\n                    min_pos = j;\n                    if (oni_options.count({i,j})) {\n                        right.min_flexibility = min(right.min_flexibility, (int)oni_options[{i,j}].size());\n                    }\n                }\n            }\n            \n            if (!right.targets.empty()) {\n                right.cost = 2 * (N - min_pos);\n                batches.push_back(right);\n            }\n        }\n        \n        // Score batches\n        for (auto& b : batches) {\n            // Base efficiency\n            double eff = (double)b.cost / b.targets.size();\n            \n            // Batch size bonus\n            if (b.targets.size() >= 4) {\n                eff *= 0.65;\n            } else if (b.targets.size() == 3) {\n                eff *= 0.75;\n            } else if (b.targets.size() == 2) {\n                eff *= 0.88;\n            }\n            \n            // Priority for batches containing forced Oni\n            if (b.min_flexibility == 1) {\n                eff *= 0.85;  // 15% bonus for batches with forced Oni\n            } else if (b.min_flexibility == 2) {\n                eff *= 0.93;  // 7% bonus for batches with limited-option Oni\n            }\n            \n            // Compactness bonus\n            if (b.targets.size() > 1) {\n                int span = 0;\n                if (b.dir == 'U' || b.dir == 'D') {\n                    int min_pos = N, max_pos = -1;\n                    for (auto [r, c] : b.targets) {\n                        min_pos = min(min_pos, r);\n                        max_pos = max(max_pos, r);\n                    }\n                    span = max_pos - min_pos + 1;\n                } else {\n                    int min_pos = N, max_pos = -1;\n                    for (auto [r, c] : b.targets) {\n                        min_pos = min(min_pos, c);\n                        max_pos = max(max_pos, c);\n                    }\n                    span = max_pos - min_pos + 1;\n                }\n                \n                if (span == b.targets.size()) {  // Perfectly consecutive\n                    eff *= 0.85;\n                } else if ((double)b.targets.size() / span >= 0.7) {  // Dense\n                    eff *= 0.92;\n                }\n            }\n            \n            b.score = eff;\n        }\n        \n        // Select best batch\n        auto best = min_element(batches.begin(), batches.end(),\n                                [](const BatchOpt& a, const BatchOpt& b) {\n                                    return a.score < b.score;\n                                });\n        \n        // Execute\n        int shifts = best->cost / 2;\n        for (int t = 0; t < shifts; t++) {\n            operations.push_back({best->dir, best->line});\n        }\n        \n        char rev = best->dir;\n        if (rev == 'U') rev = 'D';\n        else if (rev == 'D') rev = 'U';\n        else if (rev == 'L') rev = 'R';\n        else if (rev == 'R') rev = 'L';\n        \n        for (int t = 0; t < shifts; t++) {\n            operations.push_back({rev, best->line});\n        }\n        \n        // Update board\n        for (auto [i, j] : best->targets) {\n            board[i][j] = '.';\n        }\n    }\n    \n    // Output\n    for (auto [dir, pos] : operations) {\n        cout << dir << \" \" << pos << \"\\n\";\n    }\n    \n    return 0;\n}","ahc044":"#include <bits/stdc++.h>\nusing namespace std;\n\nint main() {\n    ios_base::sync_with_stdio(false);\n    cin.tie(nullptr);\n    \n    int N, L;\n    cin >> N >> L;\n    \n    vector<int> T(N);\n    for (int i = 0; i < N; i++) {\n        cin >> T[i];\n    }\n    \n    vector<int> a(N), b(N);\n    mt19937 rng(42);\n    \n    // Initialize based on target distribution\n    vector<double> prob(N);\n    for (int i = 0; i < N; i++) {\n        prob[i] = max(1, T[i]);\n    }\n    \n    discrete_distribution<int> dist(prob.begin(), prob.end());\n    for (int i = 0; i < N; i++) {\n        a[i] = dist(rng);\n        b[i] = dist(rng);\n    }\n    \n    // Fast simulation\n    auto simulate = [&](int maxSteps) -> vector<int> {\n        vector<int> count(N, 0);\n        int curr = 0;\n        count[0]++;\n        \n        for (int step = 2; step <= maxSteps; step++) {\n            if (count[curr] % 2 == 1) {\n                curr = a[curr];\n            } else {\n                curr = b[curr];\n            }\n            count[curr]++;\n        }\n        \n        return count;\n    };\n    \n    // Calculate error\n    auto calcError = [&](const vector<int>& counts, int simLen) -> int {\n        double scale = (double)L / simLen;\n        int error = 0;\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            error += abs(projected - T[i]);\n        }\n        return error;\n    };\n    \n    // Get individual errors\n    auto getErrors = [&](const vector<int>& counts, int simLen) -> vector<int> {\n        double scale = (double)L / simLen;\n        vector<int> errors(N);\n        for (int i = 0; i < N; i++) {\n            int projected = (int)(counts[i] * scale + 0.5);\n            errors[i] = projected - T[i];\n        }\n        return errors;\n    };\n    \n    // Store best solution\n    vector<int> bestA = a, bestB = b;\n    int bestError = INT_MAX;\n    \n    // Multi-stage optimization with increasing accuracy\n    vector<int> stages = {20000, 40000, 60000, 80000, 100000};\n    \n    for (int stage = 0; stage < (int)stages.size(); stage++) {\n        int simLen = min(stages[stage], L);\n        \n        // Initial evaluation\n        auto counts = simulate(simLen);\n        int currentError = calcError(counts, simLen);\n        \n        if (currentError < bestError) {\n            bestError = currentError;\n            bestA = a;\n            bestB = b;\n        }\n        \n        // Optimization iterations\n        int numIters = 400 - stage * 60; // Fewer iterations for longer simulations\n        \n        for (int iter = 0; iter < numIters; iter++) {\n            // Get current errors\n            counts = simulate(simLen);\n            auto errors = getErrors(counts, simLen);\n            currentError = calcError(counts, simLen);\n            \n            // Find nodes with largest absolute errors\n            vector<pair<int, int>> absErrors;\n            for (int i = 0; i < N; i++) {\n                absErrors.push_back({abs(errors[i]), i});\n            }\n            sort(absErrors.rbegin(), absErrors.rend());\n            \n            // Pick one of the top error nodes\n            int pickIdx = min(iter % 10, (int)absErrors.size() - 1);\n            int targetNode = absErrors[pickIdx].second;\n            \n            // Save current state\n            int oldA = a[targetNode];\n            int oldB = b[targetNode];\n            \n            // Modification strategy\n            if (errors[targetNode] > 0) {\n                // This node gets too many visits\n                // Find nodes that need more visits\n                int bestTarget = -1;\n                int maxDeficit = 0;\n                for (int i = 0; i < N; i++) {\n                    if (-errors[i] > maxDeficit) {\n                        maxDeficit = -errors[i];\n                        bestTarget = i;\n                    }\n                }\n                \n                if (bestTarget != -1) {\n                    // Redirect to deficit node\n                    if (iter % 2 == 0) {\n                        a[targetNode] = bestTarget;\n                    } else {\n                        b[targetNode] = bestTarget;\n                    }\n                    \n                    // Also make a surplus node point to deficit\n                    for (int i = 0; i < N; i++) {\n                        if (i != targetNode && errors[i] > 10) {\n                            if (rng() % 3 == 0) {\n                                if (rng() % 2 == 0) a[i] = bestTarget;\n                                else b[i] = bestTarget;\n                                break;\n                            }\n                        }\n                    }\n                }\n            } else if (errors[targetNode] < 0) {\n                // This node needs more visits\n                // Find nodes with excess visits\n                int bestSource = -1;\n                int maxSurplus = 0;\n                for (int i = 0; i < N; i++) {\n                    if (errors[i] > maxSurplus) {\n                        maxSurplus = errors[i];\n                        bestSource = i;\n                    }\n                }\n                \n                if (bestSource != -1) {\n                    // Make surplus node point here\n                    if (iter % 2 == 0) {\n                        a[bestSource] = targetNode;\n                    } else {\n                        b[bestSource] = targetNode;\n                    }\n                    \n                    // Also redirect targetNode to other deficit nodes\n                    for (int i = 0; i < N; i++) {\n                        if (i != targetNode && errors[i] < -10) {\n                            if (rng() % 3 == 0) {\n                                if (rng() % 2 == 0) a[targetNode] = i;\n                                else b[targetNode] = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n            \n            // Evaluate change\n            auto newCounts = simulate(simLen);\n            int newError = calcError(newCounts, simLen);\n            \n            if (newError < bestError) {\n                bestError = newError;\n                bestA = a;\n                bestB = b;\n            } else if (newError > currentError) {\n                // Simulated annealing\n                double temp = 200.0 * exp(-4.0 * iter / numIters);\n                double prob = exp(-(newError - currentError) / temp);\n                \n                if (uniform_real_distribution<>(0, 1)(rng) > prob) {\n                    // Revert\n                    a[targetNode] = oldA;\n                    b[targetNode] = oldB;\n                }\n            }\n            \n            // Early exit if very good\n            if (bestError < L * 0.001) break;\n        }\n        \n        // Use best solution for next stage\n        a = bestA;\n        b = bestB;\n    }\n    \n    // Final fine-tuning with longer simulation\n    int finalSimLen = min(150000, L);\n    \n    for (int finalIter = 0; finalIter < 100; finalIter++) {\n        auto counts = simulate(finalSimLen);\n        auto errors = getErrors(counts, finalSimLen);\n        int currentError = calcError(counts, finalSimLen);\n        \n        if (currentError < bestError) {\n            bestError = currentError;\n            bestA = a;\n            bestB = b;\n        }\n        \n        // Find worst error\n        int worstIdx = 0;\n        int worstError = 0;\n        for (int i = 0; i < N; i++) {\n            if (abs(errors[i]) > worstError) {\n                worstError = abs(errors[i]);\n                worstIdx = i;\n            }\n        }\n        \n        if (worstError < 2) break;\n        \n        // Single targeted change\n        if (errors[worstIdx] > 0) {\n            // Find most deficit node\n            int target = 0;\n            for (int i = 1; i < N; i++) {\n                if (errors[i] < errors[target]) {\n                    target = i;\n                }\n            }\n            \n            if (finalIter % 2 == 0) a[worstIdx] = target;\n            else b[worstIdx] = target;\n        } else {\n            // Find most surplus node\n            int source = 0;\n            for (int i = 1; i < N; i++) {\n                if (errors[i] > errors[source]) {\n                    source = i;\n                }\n            }\n            \n            if (finalIter % 2 == 0) a[source] = worstIdx;\n            else b[source] = worstIdx;\n        }\n        \n        // Check improvement\n        auto newCounts = simulate(finalSimLen);\n        int newError = calcError(newCounts, finalSimLen);\n        \n        if (newError < bestError) {\n            bestError = newError;\n            bestA = a;\n            bestB = b;\n        } else if (newError > currentError * 1.05) {\n            // Revert if significantly worse\n            a = bestA;\n            b = bestB;\n        }\n    }\n    \n    // Output best solution\n    for (int i = 0; i < N; i++) {\n        cout << bestA[i] << \" \" << bestB[i] << \"\\n\";\n    }\n    \n    return 0;\n}","ahc045":"#include <bits/stdc++.h>\nusing namespace std;\n\nstruct City {\n    int id;\n    int lx, rx, ly, ry;\n    double cx, cy;\n    double uncertainty;\n};\n\nclass UnionFind {\npublic:\n    vector<int> parent, size;\n    \n    UnionFind(int n) : parent(n), size(n, 1) {\n        iota(parent.begin(), parent.end(), 0);\n    }\n    \n    int find(int x) {\n        if (parent[x] != x) parent[x] = find(parent[x]);\n        return parent[x];\n    }\n    \n    bool unite(int x, int y) {\n        int px = find(x), py = find(y);\n        if (px == py) return false;\n        if (size[px] < size[py]) swap(px, py);\n        parent[py] = px;\n        size[px] += size[py];\n        return true;\n    }\n    \n    bool connected(int x, int y) {\n        return find(x) == find(y);\n    }\n};\n\ndouble dist(const City& a, const City& b) {\n    double dx = a.cx - b.cx;\n    double dy = a.cy - b.cy;\n    return sqrt(dx * dx + dy * dy);\n}\n\ndouble maxPossibleDist(const City& a, const City& b) {\n    double dx = max(abs(a.rx - b.lx), abs(a.lx - b.rx));\n    double dy = max(abs(a.ry - b.ly), abs(a.ly - b.ry));\n    return sqrt(dx * dx + dy * dy);\n}\n\nvector<pair<int, int>> query(const vector<int>& cities) {\n    cout << \"? \" << cities.size();\n    for (int c : cities) cout << \" \" << c;\n    cout << endl;\n    cout.flush();\n    \n    vector<pair<int, int>> edges;\n    for (int i = 0; i < (int)cities.size() - 1; i++) {\n        int u, v;\n        cin >> u >> v;\n        edges.push_back({u, v});\n    }\n    return edges;\n}\n\n// K-means++ initialization for better initial centers\nvector<int> kMeansPlusPlus(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<int> centers;\n    vector<double> minDist(n, 1e9);\n    \n    // Choose first center randomly\n    centers.push_back(rand() % n);\n    \n    for (int i = 1; i < k; i++) {\n        // Update distances\n        for (int j = 0; j < n; j++) {\n            double d = dist(cities[j], cities[centers.back()]);\n            minDist[j] = min(minDist[j], d);\n        }\n        \n        // Choose next center with probability proportional to distance squared\n        double sum = 0;\n        for (int j = 0; j < n; j++) sum += minDist[j] * minDist[j];\n        \n        double r = (double)rand() / RAND_MAX * sum;\n        double cumSum = 0;\n        for (int j = 0; j < n; j++) {\n            cumSum += minDist[j] * minDist[j];\n            if (cumSum >= r) {\n                centers.push_back(j);\n                break;\n            }\n        }\n    }\n    \n    return centers;\n}\n\n// Balanced k-means clustering\nvector<vector<int>> balancedKMeans(const vector<City>& cities, int k, const vector<int>& targetSizes) {\n    int n = cities.size();\n    vector<vector<int>> clusters(k);\n    \n    // Initialize centers\n    vector<int> centerIds = kMeansPlusPlus(cities, k, targetSizes);\n    vector<pair<double, double>> centers(k);\n    for (int i = 0; i < k; i++) {\n        centers[i] = {cities[centerIds[i]].cx, cities[centerIds[i]].cy};\n    }\n    \n    // Assign cities to clusters with size constraints\n    for (int iter = 0; iter < 20; iter++) {\n        // Calculate distances to all centers\n        vector<vector<pair<double, int>>> distances(k);\n        for (int i = 0; i < n; i++) {\n            for (int j = 0; j < k; j++) {\n                double dx = cities[i].cx - centers[j].first;\n                double dy = cities[i].cy - centers[j].second;\n                double d = sqrt(dx * dx + dy * dy);\n                distances[j].push_back({d, i});\n            }\n        }\n        \n        // Sort by distance for each cluster\n        for (int i = 0; i < k; i++) {\n            sort(distances[i].begin(), distances[i].end());\n        }\n        \n        // Assign cities greedily with size constraints\n        clusters.assign(k, vector<int>());\n        vector<bool> assigned(n, false);\n        \n        for (int round = 0; round < n; round++) {\n            for (int c = 0; c < k; c++) {\n                if (clusters[c].size() >= targetSizes[c]) continue;\n                \n                for (auto [d, city] : distances[c]) {\n                    if (!assigned[city]) {\n                        clusters[c].push_back(city);\n                        assigned[city] = true;\n                        break;\n                    }\n                }\n                \n                if (clusters[c].size() >= targetSizes[c]) continue;\n            }\n        }\n        \n        // Update centers\n        for (int i = 0; i < k; i++) {\n            if (clusters[i].empty()) continue;\n            double cx = 0, cy = 0;\n            for (int city : clusters[i]) {\n                cx += cities[city].cx;\n                cy += cities[city].cy;\n            }\n            centers[i] = {cx / clusters[i].size(), cy / clusters[i].size()};\n        }\n    }\n    \n    return clusters;\n}\n\nint main() {\n    ios::sync_with_stdio(false);\n    cin.tie(nullptr);\n    srand(time(nullptr));\n    \n    int N, M, Q, L, W;\n    cin >> N >> M >> Q >> L >> W;\n    \n    vector<int> G(M);\n    for (int i = 0; i < M; i++) cin >> G[i];\n    \n    vector<City> cities(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        cities[i].uncertainty = sqrt((cities[i].rx - cities[i].lx) * (cities[i].rx - cities[i].lx) + \n                                    (cities[i].ry - cities[i].ly) * (cities[i].ry - cities[i].ly));\n    }\n    \n    // Use balanced k-means for initial grouping\n    vector<vector<int>> groups = balancedKMeans(cities, M, G);\n    \n    // Ensure exact group sizes\n    for (int i = 0; i < M; i++) {\n        while (groups[i].size() > G[i]) {\n            groups[(i + 1) % M].push_back(groups[i].back());\n            groups[i].pop_back();\n        }\n    }\n    \n    // Process each group to find MST\n    vector<vector<pair<int, int>>> groupEdges(M);\n    map<pair<int, int>, bool> knownEdges;  // Track which edges we know exactly\n    int queriesUsed = 0;\n    \n    for (int g = 0; g < M; g++) {\n        int sz = groups[g].size();\n        if (sz <= 1) continue;\n        \n        if (sz <= L && queriesUsed < Q) {\n            // Query entire small group\n            auto edges = query(groups[g]);\n            groupEdges[g] = edges;\n            for (auto& e : edges) {\n                knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n            }\n            queriesUsed++;\n        } else {\n            // Smart querying for large groups\n            UnionFind uf(N);\n            set<pair<int, int>> mstEdges;\n            \n            // Priority queue for potential edges (estimated distance, u, v)\n            priority_queue<tuple<double, int, int>, vector<tuple<double, int, int>>, greater<>> pq;\n            \n            // Add all potential edges\n            for (int i = 0; i < sz; i++) {\n                for (int j = i + 1; j < sz; j++) {\n                    double d = dist(cities[groups[g][i]], cities[groups[g][j]]);\n                    pq.push({d, groups[g][i], groups[g][j]});\n                }\n            }\n            \n            // Process edges and query when uncertain\n            while (!pq.empty() && mstEdges.size() < sz - 1) {\n                auto [d, u, v] = pq.top();\n                pq.pop();\n                \n                if (uf.connected(u, v)) continue;\n                \n                // Check if we know this edge\n                pair<int, int> edge = {min(u, v), max(u, v)};\n                \n                if (!knownEdges.count(edge) && queriesUsed < Q) {\n                    // Query a subset containing this edge and nearby cities\n                    vector<int> subset = {u, v};\n                    \n                    // Add nearby cities up to L\n                    vector<pair<double, int>> neighbors;\n                    for (int c : groups[g]) {\n                        if (c != u && c != v) {\n                            double d1 = dist(cities[u], cities[c]);\n                            double d2 = dist(cities[v], cities[c]);\n                            neighbors.push_back({min(d1, d2), c});\n                        }\n                    }\n                    sort(neighbors.begin(), neighbors.end());\n                    \n                    for (auto [d, c] : neighbors) {\n                        subset.push_back(c);\n                        if (subset.size() >= L) break;\n                    }\n                    \n                    if (subset.size() >= 2) {\n                        auto edges = query(subset);\n                        for (auto& e : edges) {\n                            knownEdges[{min(e.first, e.second), max(e.first, e.second)}] = true;\n                            \n                            // Add to MST if it connects our components\n                            if (!uf.connected(e.first, e.second)) {\n                                uf.unite(e.first, e.second);\n                                mstEdges.insert({e.first, e.second});\n                            }\n                        }\n                        queriesUsed++;\n                    }\n                } else {\n                    // Use this edge if no cycle\n                    if (!uf.connected(u, v)) {\n                        uf.unite(u, v);\n                        mstEdges.insert({u, v});\n                    }\n                }\n            }\n            \n            // Ensure connectivity (failsafe)\n            if (mstEdges.size() < sz - 1) {\n                for (int i = 0; i < sz; i++) {\n                    for (int j = i + 1; j < sz; j++) {\n                        if (!uf.connected(groups[g][i], groups[g][j])) {\n                            uf.unite(groups[g][i], groups[g][j]);\n                            mstEdges.insert({groups[g][i], groups[g][j]});\n                            if (mstEdges.size() >= sz - 1) break;\n                        }\n                    }\n                    if (mstEdges.size() >= sz - 1) break;\n                }\n            }\n            \n            groupEdges[g] = vector<pair<int, int>>(mstEdges.begin(), mstEdges.end());\n        }\n    }\n    \n    // Output answer\n    cout << \"!\" << endl;\n    for (int g = 0; g < M; g++) {\n        for (int c : groups[g]) cout << c << \" \";\n        cout << endl;\n        for (auto& e : groupEdges[g]) {\n            cout << e.first << \" \" << e.second << endl;\n        }\n    }\n    \n    return 0;\n}","ahc046":"#include <bits/stdc++.h>\nusing namespace std;\n\nconst int N = 20;\nconst int M = 40;\n\nstruct Point {\n    int i, 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 tie(i, j) < tie(other.i, other.j);\n    }\n};\n\nvector<string> actions;\nset<Point> blocks;\nmap<Point, int> blockUseCount; // Track how useful each block is\nPoint current;\nvector<Point> targets;\nint targetIdx = 0;\n\nconst int di[] = {-1, 1, 0, 0};\nconst int dj[] = {0, 0, -1, 1};\nconst char dirs[] = {'U', 'D', 'L', 'R'};\n\nbool inBounds(int i, int j) {\n    return i >= 0 && i < N && j >= 0 && j < N;\n}\n\nPoint getNext(Point p, int dir) {\n    return {p.i + di[dir], p.j + dj[dir]};\n}\n\nPoint slideFrom(Point p, int dir) {\n    while (true) {\n        Point next = getNext(p, dir);\n        if (!inBounds(next.i, next.j) || blocks.count(next)) break;\n        p = next;\n    }\n    return p;\n}\n\nvoid addAction(char type, int dir) {\n    if (type == 'A') {\n        Point next = getNext(current, dir);\n        if (!inBounds(next.i, next.j)) return;\n    }\n    \n    actions.push_back(string(1, type) + \" \" + dirs[dir]);\n    \n    if (type == 'M') {\n        current = getNext(current, dir);\n    } else if (type == 'S') {\n        current = slideFrom(current, dir);\n    } else if (type == 'A') {\n        Point next = getNext(current, dir);\n        if (blocks.count(next)) {\n            blocks.erase(next);\n            blockUseCount.erase(next);\n        } else {\n            blocks.insert(next);\n        }\n    }\n}\n\n// Calculate how many future targets a block helps\nint calculateBlockValue(Point block) {\n    int value = 0;\n    \n    // Check next several targets\n    for (int idx = targetIdx + 1; idx < min(targetIdx + 7, M); idx++) {\n        Point t = targets[idx];\n        \n        // Direct adjacency (useful as stopper)\n        if (abs(block.i - t.i) + abs(block.j - t.j) == 1) {\n            value += 3;\n        }\n        \n        // Creates corridor between current and future target\n        for (int idx2 = idx + 1; idx2 < min(idx + 3, M); idx2++) {\n            Point t2 = targets[idx2];\n            // Check if block helps create a sliding corridor\n            if ((t.i == t2.i && block.i == t.i) || (t.j == t2.j && block.j == t.j)) {\n                if (min(t.j, t2.j) <= block.j && block.j <= max(t.j, t2.j) ||\n                    min(t.i, t2.i) <= block.i && block.i <= max(t.i, t2.i)) {\n                    value += 2;\n                }\n            }\n        }\n    }\n    \n    return value;\n}\n\n// Enhanced pathfinding with strong sliding preference\nvector<pair<char, int>> findPath(Point start, Point goal, bool preferSlide = true) {\n    if (start == goal) return {};\n    \n    struct State {\n        Point pos;\n        int cost;\n        int heuristic;\n        vector<pair<char, int>> path;\n        \n        int f() const { return cost + heuristic; }\n        bool operator>(const State& other) const {\n            return f() > other.f();\n        }\n    };\n    \n    priority_queue<State, vector<State>, greater<State>> pq;\n    map<Point, int> bestCost;\n    \n    auto calcHeuristic = [&](Point p) {\n        int di = abs(p.i - goal.i);\n        int dj = abs(p.j - goal.j);\n        \n        // Strong preference for aligned positions\n        if (preferSlide) {\n            if (p.i == goal.i || p.j == goal.j) {\n                return min(di + dj, 1); // Aligned positions are very cheap\n            }\n            // Prefer positions that can align easily\n            return min(di, dj) + 1;\n        }\n        return di + dj;\n    };\n    \n    pq.push({start, 0, calcHeuristic(start), {}});\n    bestCost[start] = 0;\n    \n    int iterations = 0;\n    const int MAX_ITER = 3000;\n    \n    while (!pq.empty() && iterations++ < MAX_ITER) {\n        auto state = pq.top();\n        pq.pop();\n        \n        if (state.pos == goal) return state.path;\n        \n        if (bestCost.count(state.pos) && bestCost[state.pos] < state.cost) continue;\n        \n        // Always try slides first (even for short distances)\n        if (preferSlide) {\n            for (int d = 0; d < 4; d++) {\n                Point next = slideFrom(state.pos, d);\n                if (next == state.pos) continue;\n                \n                int slideDist = abs(next.i - state.pos.i) + abs(next.j - state.pos.j);\n                // Slide for any distance >= 2 when preferring slides\n                if (slideDist >= 2) {\n                    int newCost = state.cost + 1;\n                    if (!bestCost.count(next) || bestCost[next] > newCost) {\n                        bestCost[next] = newCost;\n                        auto newPath = state.path;\n                        newPath.push_back({'S', d});\n                        pq.push({next, newCost, calcHeuristic(next), newPath});\n                    }\n                }\n            }\n        }\n        \n        // Try moves\n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(state.pos, d);\n            if (!inBounds(next.i, next.j) || blocks.count(next)) continue;\n            \n            int newCost = state.cost + 1;\n            // Penalize moves when we prefer sliding\n            if (preferSlide && !(next.i == goal.i || next.j == goal.j)) {\n                newCost += 1; // Slight penalty for non-aligned moves\n            }\n            \n            if (!bestCost.count(next) || bestCost[next] > newCost) {\n                bestCost[next] = newCost;\n                auto newPath = state.path;\n                newPath.push_back({'M', d});\n                pq.push({next, newCost, calcHeuristic(next), newPath});\n            }\n        }\n    }\n    \n    // Simple BFS fallback\n    queue<pair<Point, vector<pair<char, int>>>> q;\n    set<Point> visited;\n    q.push({start, {}});\n    visited.insert(start);\n    \n    while (!q.empty()) {\n        auto [p, path] = q.front();\n        q.pop();\n        \n        for (int d = 0; d < 4; d++) {\n            Point next = getNext(p, d);\n            if (!inBounds(next.i, next.j) || blocks.count(next) || visited.count(next)) \n                continue;\n            \n            visited.insert(next);\n            auto newPath = path;\n            newPath.push_back({'M', d});\n            \n            if (next == goal) return newPath;\n            q.push({next, newPath});\n        }\n    }\n    \n    return {};\n}\n\nbool setupSlideToTarget(Point target) {\n    if (current.i != target.i && current.j != target.j) return false;\n    \n    // Check direct slide\n    for (int d = 0; d < 4; d++) {\n        if (slideFrom(current, d) == target) {\n            addAction('S', d);\n            return true;\n        }\n    }\n    \n    int dist = abs(current.i - target.i) + abs(current.j - target.j);\n    \n    // Be aggressive - try blocker for any distance >= 2\n    if (dist >= 2) {\n        int dir = -1;\n        Point blocker;\n        \n        if (current.i == target.i) {\n            dir = (current.j < target.j) ? 3 : 2;\n            blocker = getNext(target, dir);\n        } else {\n            dir = (current.i < target.i) ? 1 : 0;\n            blocker = getNext(target, dir);\n        }\n        \n        if (!inBounds(blocker.i, blocker.j) || blocks.count(blocker)) return false;\n        \n        // Verify blocker helps\n        blocks.insert(blocker);\n        bool works = (slideFrom(current, dir) == target);\n        blocks.erase(blocker);\n        \n        if (!works) return false;\n        \n        // Calculate block value\n        int blockValue = calculateBlockValue(blocker);\n        \n        // Try to place blocker\n        bool placed = false;\n        \n        // If adjacent, place immediately\n        for (int d = 0; d < 4; d++) {\n            if (getNext(current, d) == blocker) {\n                addAction('A', d);\n                if (blockValue > 0) blockUseCount[blocker] = blockValue;\n                placed = true;\n                break;\n            }\n        }\n        \n        // Move to place if worthwhile\n        if (!placed) {\n            int minDist = 100;\n            int bestDir = -1;\n            \n            for (int d = 0; d < 4; d++) {\n                Point adj = getNext(blocker, d);\n                if (adj == target || !inBounds(adj.i, adj.j) || blocks.count(adj)) continue;\n                \n                int moveDist = abs(current.i - adj.i) + abs(current.j - adj.j);\n                if (moveDist < minDist) {\n                    minDist = moveDist;\n                    bestDir = d ^ 1;\n                }\n            }\n            \n            // Be more aggressive - place if close\n            if (minDist <= 3 && dist >= 3) {\n                for (int d = 0; d < 4; d++) {\n                    Point adj = getNext(blocker, d);\n                    if (adj == target || !inBounds(adj.i, adj.j) || blocks.count(adj)) continue;\n                    \n                    if (abs(current.i - adj.i) + abs(current.j - adj.j) == minDist) {\n                        auto path = findPath(current, adj, false);\n                        if (!path.empty() && path.size() <= 3) {\n                            for (auto [type, dd] : path) {\n                                addAction(type, dd);\n                            }\n                            addAction('A', d ^ 1);\n                            if (blockValue > 0) blockUseCount[blocker] = blockValue;\n                            placed = true;\n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        \n        if (placed) {\n            addAction('S', dir);\n            \n            // Remove if not valuable\n            if (blockValue <= 2) {\n                for (int d = 0; d < 4; d++) {\n                    if (getNext(current, d) == blocker) {\n                        addAction('A', d);\n                        blockUseCount.erase(blocker);\n                        break;\n                    }\n                }\n            }\n            return true;\n        }\n    }\n    \n    return false;\n}\n\nvoid moveToTarget(Point target) {\n    if (current == target) return;\n    \n    // Clear target if blocked\n    if (blocks.count(target)) {\n        for (int d = 0; d < 4; d++) {\n            Point adj = getNext(target, d);\n            if (inBounds(adj.i, adj.j) && !blocks.count(adj)) {\n                auto path = findPath(current, adj, false);\n                if (!path.empty()) {\n                    for (auto [type, dir] : path) {\n                        addAction(type, dir);\n                        if (actions.size() >= 1590) return;\n                    }\n                    for (int dd = 0; dd < 4; dd++) {\n                        if (getNext(current, dd) == target) {\n                            addAction('A', dd);\n                            break;\n                        }\n                    }\n                    break;\n                }\n            }\n        }\n    }\n    \n    // Always try sliding first if aligned\n    if (setupSlideToTarget(target)) return;\n    \n    // Try to align for sliding\n    int dist = abs(current.i - target.i) + abs(current.j - target.j);\n    if (dist >= 4 && current.i != target.i && current.j != target.j) {\n        Point alignH = {current.i, target.j};\n        Point alignV = {target.i, current.j};\n        \n        vector<pair<Point, int>> alignOptions;\n        \n        if (inBounds(alignH.i, alignH.j) && !blocks.count(alignH)) {\n            int cost = abs(current.j - target.j);\n            int benefit = abs(current.i - target.i);\n            if (benefit >= cost) {\n                alignOptions.push_back({alignH, cost - benefit});\n            }\n        }\n        \n        if (inBounds(alignV.i, alignV.j) && !blocks.count(alignV)) {\n            int cost = abs(current.i - target.i);\n            int benefit = abs(current.j - target.j);\n            if (benefit >= cost) {\n                alignOptions.push_back({alignV, cost - benefit});\n            }\n        }\n        \n        if (!alignOptions.empty()) {\n            sort(alignOptions.begin(), alignOptions.end(),\n                 [](const auto& a, const auto& b) { return a.second < b.second; });\n            \n            auto path = findPath(current, alignOptions[0].first, true);\n            if (!path.empty()) {\n                for (auto [type, d] : path) {\n                    addAction(type, d);\n                    if (actions.size() >= 1590) return;\n                }\n                if (setupSlideToTarget(target)) return;\n            }\n        }\n    }\n    \n    // Use optimal path with sliding preference\n    auto path = findPath(current, target, true);\n    for (auto [type, dir] : path) {\n        addAction(type, dir);\n        if (actions.size() >= 1590) return;\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    targets.resize(m);\n    for (int i = 0; i < m; i++) {\n        cin >> targets[i].i >> targets[i].j;\n    }\n    \n    current = targets[0];\n    \n    for (int i = 1; i < m && actions.size() < 1590; i++) {\n        targetIdx = i;\n        moveToTarget(targets[i]);\n    }\n    \n    for (const string& action : actions) {\n        cout << action << \"\\n\";\n    }\n    \n    return 0;\n}"}}}